react-chess-puzzle-kit 1.0.5 → 1.0.7
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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -9,6 +9,8 @@ export declare abstract class Position implements Traversable {
|
|
|
9
9
|
protected i: number;
|
|
10
10
|
constructor();
|
|
11
11
|
getIndex(): number;
|
|
12
|
+
/** UCI of the move that produced the current position. */
|
|
13
|
+
getLastMoveUci(): string | null;
|
|
12
14
|
next(): boolean;
|
|
13
15
|
prev(): boolean;
|
|
14
16
|
isFinished(): boolean;
|
package/dist/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
-
import { useBoardRevision, useCorrectMoveFeedback, useIncorrectMoveFeedback, useMissBoard, HighlightChessboard, DEFAULT_ANSWER_ARROW_COLOR, uciFromDrop, fenAtPlyFromStart, useSolutionLineRecap, ThemeProvider, AnalysisErrorBoundary, AnalysisBoardCore, AnalysisBoardLayout, AnalysisBoard, BoardCompleteCheckOverlay, DEFAULT_ANALYSIS_LAYOUT, AUTO_ADVANCE_ON_COMPLETE_DELAY_MS,
|
|
3
|
+
import { useBoardRevision, useCorrectMoveFeedback, useIncorrectMoveFeedback, useMissBoard, HighlightChessboard, DEFAULT_ANSWER_ARROW_COLOR, uciFromDrop, fenAtPlyFromStart, useSolutionLineRecap, lastMoveUciAtPly, ThemeProvider, AnalysisErrorBoundary, AnalysisBoardCore, AnalysisBoardLayout, AnalysisBoard, BoardCompleteCheckOverlay, DEFAULT_ANALYSIS_LAYOUT, AUTO_ADVANCE_ON_COMPLETE_DELAY_MS, evaluateExpectedMoveDrop, fenAfterUci, boardSquareHighlightColors, analysisBoardHighlightColors } from 'react-chess-core';
|
|
4
4
|
export { DEFAULT_ANALYSIS_LAYOUT } from 'react-chess-core';
|
|
5
5
|
import { Chess } from 'chess.js';
|
|
6
6
|
|
|
@@ -61,7 +61,7 @@ const EMPTY_BOARD_FEN = '8/8/8/8/8/8/8/8 w - - 0 1';
|
|
|
61
61
|
* visible while the next position loads so layout and perspective do not flicker.
|
|
62
62
|
*/
|
|
63
63
|
const PuzzlePlaySurface = ({ position, onFeedback, incInteractionNum, boardWidth, onResumeCorrect, revealAnswerOnIncorrect = false, showAnswerArrowOnIncorrect = false, allowRetryOnIncorrect = true, showRefutationOnIncorrect = false, autoShowWrongMoves = true, refutationEngine, answerArrowColor = DEFAULT_ANSWER_ARROW_COLOR, positionLocked = false, onMissFeedbackChange, recapBoard = null, }) => {
|
|
64
|
-
var _a, _b, _c, _d, _e, _f;
|
|
64
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
65
65
|
const [showAnswerArrow, setShowAnswerArrow] = useState(false);
|
|
66
66
|
const [incorrectActive, setIncorrectActive] = useState(false);
|
|
67
67
|
const attemptMissedRef = useRef(false);
|
|
@@ -182,6 +182,11 @@ const PuzzlePlaySurface = ({ position, onFeedback, incInteractionNum, boardWidth
|
|
|
182
182
|
: useRefutation && incorrectActive
|
|
183
183
|
? missBoard.boardPosition
|
|
184
184
|
: boardFen;
|
|
185
|
+
const lastMoveUci = isRecapping
|
|
186
|
+
? recapBoard.lastMoveUci
|
|
187
|
+
: useRefutation && incorrectActive
|
|
188
|
+
? missBoard.lastMoveUci
|
|
189
|
+
: ((_e = position === null || position === void 0 ? void 0 : position.getLastMoveUci()) !== null && _e !== void 0 ? _e : null);
|
|
185
190
|
const missLocked = useRefutation &&
|
|
186
191
|
incorrectActive &&
|
|
187
192
|
(missBoard.boardAnimating ||
|
|
@@ -296,7 +301,7 @@ const PuzzlePlaySurface = ({ position, onFeedback, incInteractionNum, boardWidth
|
|
|
296
301
|
showCorrectMove(targetSquare, finishCorrectFeedback);
|
|
297
302
|
return true;
|
|
298
303
|
};
|
|
299
|
-
return hasBoard ? (jsx(HighlightChessboard, { boardWidth: boardWidth, checkSquare: isRecapping ? '' : ((
|
|
304
|
+
return hasBoard ? (jsx(HighlightChessboard, { boardWidth: boardWidth, checkSquare: isRecapping ? '' : ((_f = position === null || position === void 0 ? void 0 : position.getCheckSquare()) !== null && _f !== void 0 ? _f : ''), hintSquare: isRecapping ? null : ((_g = position === null || position === void 0 ? void 0 : position.getHintSquare()) !== null && _g !== void 0 ? _g : null), incorrectMoveSquare: isRecapping ? null : overlayIncorrectSquare, refutationMoveSquare: isRecapping ? null : refutationMoveSquare, correctMoveSquare: isRecapping ? null : correctMoveSquare, customArrows: customArrows, lastMoveUci: lastMoveUci, onPieceDrop: onPieceDrop, position: displayFen, boardOrientation: boardOrientation, arePiecesDraggable: arePiecesDraggable, areArrowsAllowed: false, promotionDialogVariant: "modal", animationDuration: isRecapping ? recapBoard.animationDuration : 0 }, revision)) : null;
|
|
300
305
|
};
|
|
301
306
|
|
|
302
307
|
const PuzzleBoard = ({ position, onFeedback, incInteractionNum, boardWidth, revealAnswerOnIncorrect = false, showAnswerArrowOnIncorrect = false, allowRetryOnIncorrect = true, answerArrowColor, }) => (jsx(PuzzlePlaySurface, { position: position, onFeedback: onFeedback, incInteractionNum: incInteractionNum, boardWidth: boardWidth, revealAnswerOnIncorrect: revealAnswerOnIncorrect, showAnswerArrowOnIncorrect: showAnswerArrowOnIncorrect, allowRetryOnIncorrect: allowRetryOnIncorrect, answerArrowColor: answerArrowColor }));
|
|
@@ -512,6 +517,10 @@ class Position {
|
|
|
512
517
|
getIndex() {
|
|
513
518
|
return this.i;
|
|
514
519
|
}
|
|
520
|
+
/** UCI of the move that produced the current position. */
|
|
521
|
+
getLastMoveUci() {
|
|
522
|
+
return lastMoveUciAtPly(this.moves, this.i);
|
|
523
|
+
}
|
|
515
524
|
// Common methods shared by all positions
|
|
516
525
|
next() {
|
|
517
526
|
if (this.i >= this.moves.length) {
|
|
@@ -1181,10 +1190,12 @@ const PuzzleBoardWithControls = ({ theme, boardTheme, apiProxy, renderControls =
|
|
|
1181
1190
|
window.clearTimeout(timer);
|
|
1182
1191
|
};
|
|
1183
1192
|
}, [completionCheckVisible]);
|
|
1193
|
+
const analysis = usePuzzleAnalysis(position, resultStatus, puzzleNum);
|
|
1184
1194
|
const shouldAutoAdvance = autoAdvanceOnComplete &&
|
|
1185
1195
|
resultStatus === 'complete' &&
|
|
1186
1196
|
!(hasIncorrectAttempt && !autoAdvanceOnCompleteAfterIncorrect) &&
|
|
1187
|
-
(!showCompletionRecap || completionRecapDone)
|
|
1197
|
+
(!showCompletionRecap || completionRecapDone) &&
|
|
1198
|
+
!analysis.isOpen;
|
|
1188
1199
|
const autoAdvance = usePuzzleAutoAdvanceCountdown(shouldAutoAdvance, autoAdvanceOnCompleteDelayMs, handleNextPuzzle);
|
|
1189
1200
|
const controlState = {
|
|
1190
1201
|
canShowHint: position !== null &&
|
|
@@ -1194,7 +1205,6 @@ const PuzzleBoardWithControls = ({ theme, boardTheme, apiProxy, renderControls =
|
|
|
1194
1205
|
canShowSolution: position !== null &&
|
|
1195
1206
|
(position.isSolutionRevealed() || !position.isFinished()),
|
|
1196
1207
|
};
|
|
1197
|
-
const analysis = usePuzzleAnalysis(position, resultStatus, puzzleNum);
|
|
1198
1208
|
const analysisSnapshot = analysis.isOpen && analysis.snapshot ? analysis.snapshot : null;
|
|
1199
1209
|
const resolvedAnalysisBoardWidth = analysisBoardWidth !== null && analysisBoardWidth !== void 0 ? analysisBoardWidth : analysisLayout.boardWidth;
|
|
1200
1210
|
const useHostAnalysisUi = Boolean(renderAnalysisSidebar &&
|
package/dist/index.js
CHANGED
|
@@ -62,7 +62,7 @@ const EMPTY_BOARD_FEN = '8/8/8/8/8/8/8/8 w - - 0 1';
|
|
|
62
62
|
* visible while the next position loads so layout and perspective do not flicker.
|
|
63
63
|
*/
|
|
64
64
|
const PuzzlePlaySurface = ({ position, onFeedback, incInteractionNum, boardWidth, onResumeCorrect, revealAnswerOnIncorrect = false, showAnswerArrowOnIncorrect = false, allowRetryOnIncorrect = true, showRefutationOnIncorrect = false, autoShowWrongMoves = true, refutationEngine, answerArrowColor = reactChessCore.DEFAULT_ANSWER_ARROW_COLOR, positionLocked = false, onMissFeedbackChange, recapBoard = null, }) => {
|
|
65
|
-
var _a, _b, _c, _d, _e, _f;
|
|
65
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
66
66
|
const [showAnswerArrow, setShowAnswerArrow] = react.useState(false);
|
|
67
67
|
const [incorrectActive, setIncorrectActive] = react.useState(false);
|
|
68
68
|
const attemptMissedRef = react.useRef(false);
|
|
@@ -183,6 +183,11 @@ const PuzzlePlaySurface = ({ position, onFeedback, incInteractionNum, boardWidth
|
|
|
183
183
|
: useRefutation && incorrectActive
|
|
184
184
|
? missBoard.boardPosition
|
|
185
185
|
: boardFen;
|
|
186
|
+
const lastMoveUci = isRecapping
|
|
187
|
+
? recapBoard.lastMoveUci
|
|
188
|
+
: useRefutation && incorrectActive
|
|
189
|
+
? missBoard.lastMoveUci
|
|
190
|
+
: ((_e = position === null || position === void 0 ? void 0 : position.getLastMoveUci()) !== null && _e !== void 0 ? _e : null);
|
|
186
191
|
const missLocked = useRefutation &&
|
|
187
192
|
incorrectActive &&
|
|
188
193
|
(missBoard.boardAnimating ||
|
|
@@ -297,7 +302,7 @@ const PuzzlePlaySurface = ({ position, onFeedback, incInteractionNum, boardWidth
|
|
|
297
302
|
showCorrectMove(targetSquare, finishCorrectFeedback);
|
|
298
303
|
return true;
|
|
299
304
|
};
|
|
300
|
-
return hasBoard ? (jsxRuntime.jsx(reactChessCore.HighlightChessboard, { boardWidth: boardWidth, checkSquare: isRecapping ? '' : ((
|
|
305
|
+
return hasBoard ? (jsxRuntime.jsx(reactChessCore.HighlightChessboard, { boardWidth: boardWidth, checkSquare: isRecapping ? '' : ((_f = position === null || position === void 0 ? void 0 : position.getCheckSquare()) !== null && _f !== void 0 ? _f : ''), hintSquare: isRecapping ? null : ((_g = position === null || position === void 0 ? void 0 : position.getHintSquare()) !== null && _g !== void 0 ? _g : null), incorrectMoveSquare: isRecapping ? null : overlayIncorrectSquare, refutationMoveSquare: isRecapping ? null : refutationMoveSquare, correctMoveSquare: isRecapping ? null : correctMoveSquare, customArrows: customArrows, lastMoveUci: lastMoveUci, onPieceDrop: onPieceDrop, position: displayFen, boardOrientation: boardOrientation, arePiecesDraggable: arePiecesDraggable, areArrowsAllowed: false, promotionDialogVariant: "modal", animationDuration: isRecapping ? recapBoard.animationDuration : 0 }, revision)) : null;
|
|
301
306
|
};
|
|
302
307
|
|
|
303
308
|
const PuzzleBoard = ({ position, onFeedback, incInteractionNum, boardWidth, revealAnswerOnIncorrect = false, showAnswerArrowOnIncorrect = false, allowRetryOnIncorrect = true, answerArrowColor, }) => (jsxRuntime.jsx(PuzzlePlaySurface, { position: position, onFeedback: onFeedback, incInteractionNum: incInteractionNum, boardWidth: boardWidth, revealAnswerOnIncorrect: revealAnswerOnIncorrect, showAnswerArrowOnIncorrect: showAnswerArrowOnIncorrect, allowRetryOnIncorrect: allowRetryOnIncorrect, answerArrowColor: answerArrowColor }));
|
|
@@ -513,6 +518,10 @@ class Position {
|
|
|
513
518
|
getIndex() {
|
|
514
519
|
return this.i;
|
|
515
520
|
}
|
|
521
|
+
/** UCI of the move that produced the current position. */
|
|
522
|
+
getLastMoveUci() {
|
|
523
|
+
return reactChessCore.lastMoveUciAtPly(this.moves, this.i);
|
|
524
|
+
}
|
|
516
525
|
// Common methods shared by all positions
|
|
517
526
|
next() {
|
|
518
527
|
if (this.i >= this.moves.length) {
|
|
@@ -1182,10 +1191,12 @@ const PuzzleBoardWithControls = ({ theme, boardTheme, apiProxy, renderControls =
|
|
|
1182
1191
|
window.clearTimeout(timer);
|
|
1183
1192
|
};
|
|
1184
1193
|
}, [completionCheckVisible]);
|
|
1194
|
+
const analysis = usePuzzleAnalysis(position, resultStatus, puzzleNum);
|
|
1185
1195
|
const shouldAutoAdvance = autoAdvanceOnComplete &&
|
|
1186
1196
|
resultStatus === 'complete' &&
|
|
1187
1197
|
!(hasIncorrectAttempt && !autoAdvanceOnCompleteAfterIncorrect) &&
|
|
1188
|
-
(!showCompletionRecap || completionRecapDone)
|
|
1198
|
+
(!showCompletionRecap || completionRecapDone) &&
|
|
1199
|
+
!analysis.isOpen;
|
|
1189
1200
|
const autoAdvance = usePuzzleAutoAdvanceCountdown(shouldAutoAdvance, autoAdvanceOnCompleteDelayMs, handleNextPuzzle);
|
|
1190
1201
|
const controlState = {
|
|
1191
1202
|
canShowHint: position !== null &&
|
|
@@ -1195,7 +1206,6 @@ const PuzzleBoardWithControls = ({ theme, boardTheme, apiProxy, renderControls =
|
|
|
1195
1206
|
canShowSolution: position !== null &&
|
|
1196
1207
|
(position.isSolutionRevealed() || !position.isFinished()),
|
|
1197
1208
|
};
|
|
1198
|
-
const analysis = usePuzzleAnalysis(position, resultStatus, puzzleNum);
|
|
1199
1209
|
const analysisSnapshot = analysis.isOpen && analysis.snapshot ? analysis.snapshot : null;
|
|
1200
1210
|
const resolvedAnalysisBoardWidth = analysisBoardWidth !== null && analysisBoardWidth !== void 0 ? analysisBoardWidth : analysisLayout.boardWidth;
|
|
1201
1211
|
const useHostAnalysisUi = Boolean(renderAnalysisSidebar &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-chess-puzzle-kit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "React chess puzzle kit: play, controls, analysis, and browser Stockfish for endchess.training and other apps",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Robert Blackwell",
|
|
@@ -68,11 +68,13 @@
|
|
|
68
68
|
"@storybook/react": "^8.2.9",
|
|
69
69
|
"@storybook/react-vite": "^8.2.9",
|
|
70
70
|
"@storybook/test": "^8.2.9",
|
|
71
|
+
"@testing-library/react": "^16.0.1",
|
|
71
72
|
"@types/jest": "^29.5.12",
|
|
72
73
|
"@types/react": "^18.3.12",
|
|
73
74
|
"@types/react-dom": "^18.3.1",
|
|
74
75
|
"chess.js": "^1.0.0-beta.8",
|
|
75
76
|
"jest": "^29.7.0",
|
|
77
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
76
78
|
"react": "^18.3.1",
|
|
77
79
|
"react-chess-core": "^0.1.8",
|
|
78
80
|
"react-chessboard": "^4.7.1",
|