react-chess-puzzle-kit 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/LICENSE +21 -0
- package/README.md +331 -0
- package/dist/features/analysis/AnalysisBoard.d.ts +18 -0
- package/dist/features/analysis/AnalysisBoardCore.d.ts +28 -0
- package/dist/features/analysis/AnalysisBoardLayout.d.ts +12 -0
- package/dist/features/analysis/AnalysisChessboardView.d.ts +5 -0
- package/dist/features/analysis/AnalysisPosition.d.ts +53 -0
- package/dist/features/analysis/AnalysisTrigger.d.ts +6 -0
- package/dist/features/analysis/DefaultAnalysisContainer.d.ts +3 -0
- package/dist/features/analysis/DefaultAnalysisSidebar.d.ts +2 -0
- package/dist/features/analysis/analysisBoardHighlightColors.d.ts +12 -0
- package/dist/features/analysis/analysisContext.d.ts +8 -0
- package/dist/features/analysis/analysisLayout.d.ts +5 -0
- package/dist/features/analysis/core/AnalysisBoardCore.d.ts +28 -0
- package/dist/features/analysis/core/AnalysisChessboardView.d.ts +5 -0
- package/dist/features/analysis/core/AnalysisErrorBoundary.d.ts +14 -0
- package/dist/features/analysis/core/AnalysisPosition.d.ts +54 -0
- package/dist/features/analysis/core/analysisContext.d.ts +13 -0
- package/dist/features/analysis/core/analysisLayout.d.ts +5 -0
- package/dist/features/analysis/core/analysisLayoutConfig.d.ts +6 -0
- package/dist/features/analysis/core/index.d.ts +9 -0
- package/dist/features/analysis/core/renderProps.d.ts +39 -0
- package/dist/features/analysis/core/useAnalysisBoardModel.d.ts +36 -0
- package/dist/features/analysis/core/usePuzzleAnalysis.d.ts +10 -0
- package/dist/features/analysis/defaults/AnalysisBoard.d.ts +16 -0
- package/dist/features/analysis/defaults/AnalysisBoardLayout.d.ts +14 -0
- package/dist/features/analysis/defaults/DefaultAnalysisContainer.d.ts +4 -0
- package/dist/features/analysis/defaults/DefaultAnalysisSidebar.d.ts +3 -0
- package/dist/features/analysis/defaults/analysisLayout.d.ts +3 -0
- package/dist/features/analysis/defaults/analysisModalStyles.d.ts +7 -0
- package/dist/features/analysis/defaults/analysisSidebarColors.d.ts +37 -0
- package/dist/features/analysis/defaults/analysisSidebarRowStyle.d.ts +8 -0
- package/dist/features/analysis/defaults/index.d.ts +8 -0
- package/dist/features/analysis/index.d.ts +3 -0
- package/dist/features/analysis/renderProps.d.ts +39 -0
- package/dist/features/analysis/useAnalysisBoardModel.d.ts +33 -0
- package/dist/features/analysis/usePuzzleAnalysis.d.ts +10 -0
- package/dist/features/board/BlankPuzzleBoard.d.ts +5 -0
- package/dist/features/board/HighlightChessboard.d.ts +2 -0
- package/dist/features/board/LineBoard.d.ts +15 -0
- package/dist/features/board/LineBoardWithControls.d.ts +50 -0
- package/dist/features/board/PuzzleBoard.d.ts +10 -0
- package/dist/features/board/PuzzleBoardWithControls.d.ts +51 -0
- package/dist/features/board/PuzzlePlaySurface.d.ts +25 -0
- package/dist/features/board/boardSquareHighlightColors.d.ts +1 -0
- package/dist/features/board/chessboardTheme.d.ts +2 -0
- package/dist/features/board/defaults/DefaultLineControls.d.ts +5 -0
- package/dist/features/board/defaults/DefaultPuzzleControls.d.ts +18 -0
- package/dist/features/board/defaults/index.d.ts +1 -0
- package/dist/features/board/puzzleBoardLayout.d.ts +8 -0
- package/dist/features/engine/EngineEvaluationPanel.d.ts +8 -0
- package/dist/features/engine/StockfishBrowserEngine.d.ts +1 -0
- package/dist/features/engine/formatEvaluation.d.ts +1 -0
- package/dist/features/engine/index.d.ts +1 -0
- package/dist/features/engine/isAnalyzableFen.d.ts +1 -0
- package/dist/features/engine/parseUciInfo.d.ts +1 -0
- package/dist/features/engine/stockfishUrls.d.ts +1 -0
- package/dist/features/engine/types.d.ts +1 -0
- package/dist/features/engine/useAnalysisEngine.d.ts +1 -0
- package/dist/features/position/Position.d.ts +67 -0
- package/dist/features/position/Position.test.d.ts +1 -0
- package/dist/features/position/Traversable.d.ts +4 -0
- package/dist/features/position/moveHistory.d.ts +7 -0
- package/dist/features/theme/ThemeContext.d.ts +26 -0
- package/dist/features/theme/ThemeProvider.d.ts +7 -0
- package/dist/features/theme/squareHighlightColors.d.ts +50 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.esm.js +861 -0
- package/dist/index.js +885 -0
- package/dist/stories/AnalysisBoard.stories.d.ts +9 -0
- package/dist/stories/HighlightChessboard.stories.d.ts +9 -0
- package/dist/stories/PuzzleBoard.stories.d.ts +6 -0
- package/dist/stories/PuzzleBoardWithControls.stories.d.ts +9 -0
- package/dist/stories/analysisFixtures.d.ts +4 -0
- package/dist/stories/regressions/PuzzleRegressions.stories.d.ts +7 -0
- package/dist/stories/regressions/StockfishAnalysisRegressions.stories.d.ts +7 -0
- package/dist/stories/regressions/fixtures.d.ts +18 -0
- package/dist/stories/regressions/regressionAnalysisContext.d.ts +5 -0
- package/dist/stories/storybookLayout.d.ts +4 -0
- package/dist/stories/withChessboardDnD.d.ts +4 -0
- package/dist/stories/withDefaultPuzzleControls.d.ts +7 -0
- package/dist/stories/withThemeProvider.d.ts +3 -0
- package/package.json +87 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { EngineEvaluation } from 'react-chess-core';
|
|
3
|
+
import { AnalysisHistoryRow, SolutionMoveDisplay } from './AnalysisPosition';
|
|
4
|
+
import { AnalysisBoardModel } from './useAnalysisBoardModel';
|
|
5
|
+
export type AnalysisControls = {
|
|
6
|
+
visible: boolean;
|
|
7
|
+
openAnalysis: () => void;
|
|
8
|
+
};
|
|
9
|
+
export type EngineEvaluationRenderProps = {
|
|
10
|
+
fen: string;
|
|
11
|
+
evaluation: EngineEvaluation;
|
|
12
|
+
theme: 'light' | 'dark';
|
|
13
|
+
};
|
|
14
|
+
export type AnalysisSidebarRenderProps = {
|
|
15
|
+
/** Main-line moves (legacy; prefer historyRows). */
|
|
16
|
+
moves: SolutionMoveDisplay[];
|
|
17
|
+
historyRows: AnalysisHistoryRow[];
|
|
18
|
+
isHistoryRowSelected: (row: AnalysisHistoryRow) => boolean;
|
|
19
|
+
onSelectHistoryRow: (row: AnalysisHistoryRow) => void;
|
|
20
|
+
ply: number;
|
|
21
|
+
maxPly: number;
|
|
22
|
+
onSelectPly: (ply: number) => void;
|
|
23
|
+
theme: 'light' | 'dark';
|
|
24
|
+
/** Host-rendered engine UI from `renderEngineEvaluation`. */
|
|
25
|
+
engineEvaluationPanel: ReactNode | null;
|
|
26
|
+
};
|
|
27
|
+
export type AnalysisContainerRenderProps = {
|
|
28
|
+
theme: 'light' | 'dark';
|
|
29
|
+
onClose: () => void;
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
/** Used by {@link DefaultAnalysisContainer} for overlay dismiss (ignored by most hosts). */
|
|
32
|
+
onBackdropMouseDown?: () => void;
|
|
33
|
+
};
|
|
34
|
+
/** Place board + sidebar inside the analysis shell (host or default grid). */
|
|
35
|
+
export type AnalysisMainRenderProps = {
|
|
36
|
+
model: AnalysisBoardModel;
|
|
37
|
+
board: ReactNode;
|
|
38
|
+
sidebar: ReactNode;
|
|
39
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AnalysisHistoryRow, SolutionMoveDisplay } from './AnalysisPosition';
|
|
2
|
+
import { PuzzleAnalysisContext } from './analysisContext';
|
|
3
|
+
import { AnalysisEngineOptions, EngineEvaluation } from 'react-chess-core';
|
|
4
|
+
export type UseAnalysisBoardModelArgs = {
|
|
5
|
+
analysisContext: PuzzleAnalysisContext;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
theme: 'light' | 'dark';
|
|
8
|
+
/** Chessboard pixel width (host-controlled). */
|
|
9
|
+
boardWidth: number;
|
|
10
|
+
engine?: AnalysisEngineOptions;
|
|
11
|
+
};
|
|
12
|
+
export type AnalysisBoardModel = {
|
|
13
|
+
theme: 'light' | 'dark';
|
|
14
|
+
boardWidth: number;
|
|
15
|
+
analysisContext: PuzzleAnalysisContext;
|
|
16
|
+
fen: string;
|
|
17
|
+
ply: number;
|
|
18
|
+
maxPly: number;
|
|
19
|
+
historyRows: AnalysisHistoryRow[];
|
|
20
|
+
solutionSans: SolutionMoveDisplay[];
|
|
21
|
+
boardOrientation: 'white' | 'black';
|
|
22
|
+
engineEvaluation: EngineEvaluation;
|
|
23
|
+
engineEnabled: boolean;
|
|
24
|
+
lastMove: {
|
|
25
|
+
from: string;
|
|
26
|
+
to: string;
|
|
27
|
+
} | null;
|
|
28
|
+
checkSquare: string | null;
|
|
29
|
+
onSelectPly: (ply: number) => void;
|
|
30
|
+
onSelectHistoryRow: (row: AnalysisHistoryRow) => void;
|
|
31
|
+
isHistoryRowSelected: (row: AnalysisHistoryRow) => boolean;
|
|
32
|
+
onPieceDrop: (sourceSquare: string, targetSquare: string, piece: string) => boolean;
|
|
33
|
+
onBackdropMouseDown: () => void;
|
|
34
|
+
onClose: () => void;
|
|
35
|
+
};
|
|
36
|
+
export declare const useAnalysisBoardModel: ({ analysisContext, onClose, theme, boardWidth, engine, }: UseAnalysisBoardModelArgs) => AnalysisBoardModel;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PuzzlePosition } from '../../position/Position';
|
|
2
|
+
import { PuzzleResultStatus } from './analysisContext';
|
|
3
|
+
import { PuzzleAnalysisContext } from './analysisContext';
|
|
4
|
+
export declare const usePuzzleAnalysis: (position: PuzzlePosition | null, resultStatus: PuzzleResultStatus, puzzleNum: number) => {
|
|
5
|
+
canOpen: boolean;
|
|
6
|
+
isOpen: boolean;
|
|
7
|
+
snapshot: PuzzleAnalysisContext | null;
|
|
8
|
+
openAnalysis: () => void;
|
|
9
|
+
closeAnalysis: () => void;
|
|
10
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AnalysisBoardCoreProps } from '../core/AnalysisBoardCore';
|
|
3
|
+
import { AnalysisLayoutConfig } from '../core/analysisLayoutConfig';
|
|
4
|
+
import { AnalysisContainerRenderProps, AnalysisMainRenderProps, AnalysisSidebarRenderProps, EngineEvaluationRenderProps } from '../core/renderProps';
|
|
5
|
+
export interface AnalysisBoardProps extends Omit<AnalysisBoardCoreProps, 'renderContainer' | 'renderMain' | 'renderSidebar' | 'renderEngineEvaluation' | 'boardWidth'> {
|
|
6
|
+
layout?: AnalysisLayoutConfig;
|
|
7
|
+
renderContainer?: (props: AnalysisContainerRenderProps) => React.ReactNode;
|
|
8
|
+
renderMain?: (props: AnalysisMainRenderProps) => React.ReactNode;
|
|
9
|
+
renderSidebar?: (props: AnalysisSidebarRenderProps) => React.ReactNode;
|
|
10
|
+
renderEngineEvaluation?: (props: EngineEvaluationRenderProps) => React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Full analysis UI with library defaults: modal shell, grid layout, sidebar, engine panel.
|
|
14
|
+
* For host-owned UI only, use {@link AnalysisBoardCore} and pass all render props.
|
|
15
|
+
*/
|
|
16
|
+
export declare const AnalysisBoard: ({ layout, renderContainer, renderMain, renderSidebar, renderEngineEvaluation, engine, ...modelArgs }: AnalysisBoardProps) => React.JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AnalysisLayoutConfig } from '../core/analysisLayoutConfig';
|
|
3
|
+
import { AnalysisBoardModel } from '../core/useAnalysisBoardModel';
|
|
4
|
+
export type AnalysisBoardLayoutProps = {
|
|
5
|
+
layout: AnalysisLayoutConfig;
|
|
6
|
+
model: AnalysisBoardModel;
|
|
7
|
+
board: React.ReactNode;
|
|
8
|
+
sidebar: React.ReactNode;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Optional grid helper: board column + sidebar column.
|
|
12
|
+
* Hosts may use this in `renderMain` or supply their own layout.
|
|
13
|
+
*/
|
|
14
|
+
export declare const AnalysisBoardLayout: ({ layout, model, board, sidebar, }: AnalysisBoardLayoutProps) => React.JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AnalysisContainerRenderProps } from '../core/renderProps';
|
|
3
|
+
/** Default full-screen modal shell for analysis (library preset UI). */
|
|
4
|
+
export declare const DefaultAnalysisContainer: ({ theme, onClose, onBackdropMouseDown, children, }: AnalysisContainerRenderProps) => React.JSX.Element;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AnalysisSidebarRenderProps } from '../core/renderProps';
|
|
3
|
+
export declare const DefaultAnalysisSidebar: ({ historyRows, isHistoryRowSelected, onSelectHistoryRow, ply, maxPly, onSelectPly, theme, engineEvaluationPanel, }: AnalysisSidebarRenderProps) => React.JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Move-list colors for the analysis board sidebar.
|
|
3
|
+
* Tweak values here when iterating on history row striping.
|
|
4
|
+
*/
|
|
5
|
+
export declare const analysisSidebarColors: {
|
|
6
|
+
/** Selected move row */
|
|
7
|
+
readonly activeMove: {
|
|
8
|
+
readonly light: "rgba(119, 177, 212, 1)";
|
|
9
|
+
readonly dark: "rgba(90, 159, 190, 1)";
|
|
10
|
+
};
|
|
11
|
+
/** Start row */
|
|
12
|
+
readonly start: {
|
|
13
|
+
readonly light: "#e8e8e8";
|
|
14
|
+
readonly dark: "#262626";
|
|
15
|
+
};
|
|
16
|
+
/** Alternating main-line rows (index 0 = darker, 1 = lighter). */
|
|
17
|
+
readonly mainStripe: readonly [{
|
|
18
|
+
readonly light: "#c9c9c9";
|
|
19
|
+
readonly dark: "#1c1c1c";
|
|
20
|
+
}, {
|
|
21
|
+
readonly light: "#f2f2f2";
|
|
22
|
+
readonly dark: "#383838";
|
|
23
|
+
}];
|
|
24
|
+
/** Alternating user-variation rows (index 0 = slightly tinted, 1 = lighter). */
|
|
25
|
+
readonly variationStripe: readonly [{
|
|
26
|
+
readonly light: "#eef5fb";
|
|
27
|
+
readonly dark: "#2c3540";
|
|
28
|
+
}, {
|
|
29
|
+
readonly light: "#f7fbfe";
|
|
30
|
+
readonly dark: "#343f4c";
|
|
31
|
+
}];
|
|
32
|
+
/** Text on variation rows (light backgrounds need dark type). */
|
|
33
|
+
readonly variationText: {
|
|
34
|
+
readonly light: "rgba(0, 0, 0, 0.87)";
|
|
35
|
+
readonly dark: "rgba(0, 0, 0, 0.87)";
|
|
36
|
+
};
|
|
37
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnalysisHistoryRow } from '../core/AnalysisPosition';
|
|
2
|
+
export type SidebarRowBandCounters = {
|
|
3
|
+
main: number;
|
|
4
|
+
variation: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const createSidebarRowBandCounters: () => SidebarRowBandCounters;
|
|
7
|
+
/** Background for one analysis history row; mutates `bands` while iterating rows in order. */
|
|
8
|
+
export declare const getSidebarRowBackground: (theme: "light" | "dark", row: AnalysisHistoryRow, bands: SidebarRowBandCounters) => string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './analysisModalStyles';
|
|
2
|
+
export * from './analysisSidebarColors';
|
|
3
|
+
export * from './analysisSidebarRowStyle';
|
|
4
|
+
export * from './analysisLayout';
|
|
5
|
+
export * from './AnalysisBoard';
|
|
6
|
+
export * from './AnalysisBoardLayout';
|
|
7
|
+
export * from './DefaultAnalysisContainer';
|
|
8
|
+
export * from './DefaultAnalysisSidebar';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { EngineEvaluation } from '../engine/types';
|
|
3
|
+
import { AnalysisHistoryRow, SolutionMoveDisplay } from './AnalysisPosition';
|
|
4
|
+
import { AnalysisBoardModel } from './useAnalysisBoardModel';
|
|
5
|
+
export type AnalysisControls = {
|
|
6
|
+
visible: boolean;
|
|
7
|
+
openAnalysis: () => void;
|
|
8
|
+
};
|
|
9
|
+
export type EngineEvaluationRenderProps = {
|
|
10
|
+
fen: string;
|
|
11
|
+
evaluation: EngineEvaluation;
|
|
12
|
+
theme: 'light' | 'dark';
|
|
13
|
+
};
|
|
14
|
+
export type AnalysisSidebarRenderProps = {
|
|
15
|
+
/** Main-line moves (legacy; prefer historyRows). */
|
|
16
|
+
moves: SolutionMoveDisplay[];
|
|
17
|
+
historyRows: AnalysisHistoryRow[];
|
|
18
|
+
isHistoryRowSelected: (row: AnalysisHistoryRow) => boolean;
|
|
19
|
+
onSelectHistoryRow: (row: AnalysisHistoryRow) => void;
|
|
20
|
+
ply: number;
|
|
21
|
+
maxPly: number;
|
|
22
|
+
onSelectPly: (ply: number) => void;
|
|
23
|
+
theme: 'light' | 'dark';
|
|
24
|
+
/** Host-rendered engine UI from `renderEngineEvaluation`. */
|
|
25
|
+
engineEvaluationPanel: ReactNode | null;
|
|
26
|
+
};
|
|
27
|
+
export type AnalysisContainerRenderProps = {
|
|
28
|
+
theme: 'light' | 'dark';
|
|
29
|
+
onClose: () => void;
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
/** Used by {@link DefaultAnalysisContainer} for overlay dismiss (ignored by most hosts). */
|
|
32
|
+
onBackdropMouseDown?: () => void;
|
|
33
|
+
};
|
|
34
|
+
/** Place board + sidebar inside the analysis shell (host or default grid). */
|
|
35
|
+
export type AnalysisMainRenderProps = {
|
|
36
|
+
model: AnalysisBoardModel;
|
|
37
|
+
board: ReactNode;
|
|
38
|
+
sidebar: ReactNode;
|
|
39
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AnalysisHistoryRow, SolutionMoveDisplay } from './AnalysisPosition';
|
|
2
|
+
import { PuzzleAnalysisContext } from './analysisContext';
|
|
3
|
+
import { AnalysisEngineOptions, EngineEvaluation } from '../engine';
|
|
4
|
+
export type UseAnalysisBoardModelArgs = {
|
|
5
|
+
analysisContext: PuzzleAnalysisContext;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
theme: 'light' | 'dark';
|
|
8
|
+
engine?: AnalysisEngineOptions;
|
|
9
|
+
};
|
|
10
|
+
export type AnalysisBoardModel = {
|
|
11
|
+
theme: 'light' | 'dark';
|
|
12
|
+
analysisContext: PuzzleAnalysisContext;
|
|
13
|
+
fen: string;
|
|
14
|
+
ply: number;
|
|
15
|
+
maxPly: number;
|
|
16
|
+
historyRows: AnalysisHistoryRow[];
|
|
17
|
+
solutionSans: SolutionMoveDisplay[];
|
|
18
|
+
boardOrientation: 'white' | 'black';
|
|
19
|
+
engineEvaluation: EngineEvaluation;
|
|
20
|
+
engineEnabled: boolean;
|
|
21
|
+
lastMove: {
|
|
22
|
+
from: string;
|
|
23
|
+
to: string;
|
|
24
|
+
} | null;
|
|
25
|
+
checkSquare: string | null;
|
|
26
|
+
onSelectPly: (ply: number) => void;
|
|
27
|
+
onSelectHistoryRow: (row: AnalysisHistoryRow) => void;
|
|
28
|
+
isHistoryRowSelected: (row: AnalysisHistoryRow) => boolean;
|
|
29
|
+
onPieceDrop: (sourceSquare: string, targetSquare: string, piece: string) => boolean;
|
|
30
|
+
onBackdropMouseDown: () => void;
|
|
31
|
+
onClose: () => void;
|
|
32
|
+
};
|
|
33
|
+
export declare const useAnalysisBoardModel: ({ analysisContext, onClose, theme, engine, }: UseAnalysisBoardModelArgs) => AnalysisBoardModel;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AnalysisContext } from 'react-chess-core';
|
|
2
|
+
import { PuzzlePosition } from '../position/Position';
|
|
3
|
+
import { PuzzleResultStatus } from './analysisContext';
|
|
4
|
+
export declare const usePuzzleAnalysis: (position: PuzzlePosition | null, resultStatus: PuzzleResultStatus, puzzleNum: number) => {
|
|
5
|
+
canOpen: boolean;
|
|
6
|
+
isOpen: boolean;
|
|
7
|
+
snapshot: AnalysisContext | null;
|
|
8
|
+
openAnalysis: () => void;
|
|
9
|
+
closeAnalysis: () => void;
|
|
10
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LineTrainSide } from './LineBoardWithControls';
|
|
2
|
+
export interface LineBoardProps {
|
|
3
|
+
fen: string;
|
|
4
|
+
orientation: 'white' | 'black';
|
|
5
|
+
trainSide: LineTrainSide;
|
|
6
|
+
draggable: boolean;
|
|
7
|
+
onPieceDrop: (source: string, target: string, piece: string) => boolean;
|
|
8
|
+
boardWidth: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Board view for line drilling: a plain themed board that only lets the trainer
|
|
12
|
+
* side's pieces be dragged. Move validation and sequencing live in
|
|
13
|
+
* {@link LineBoardWithControls}.
|
|
14
|
+
*/
|
|
15
|
+
export declare const LineBoard: ({ fen, orientation, trainSide, draggable, onPieceDrop, boardWidth, }: LineBoardProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type LineTrainSide = 'w' | 'b';
|
|
3
|
+
/** A line to drill: a start position plus the moves to walk, from one side. */
|
|
4
|
+
export interface LineSpec {
|
|
5
|
+
startFen: string;
|
|
6
|
+
movesUci: string[];
|
|
7
|
+
/** Optional SAN parallel to {@link movesUci} for nicer feedback labels. */
|
|
8
|
+
movesSan?: string[];
|
|
9
|
+
/** The side the user plays; the other side is auto-played. */
|
|
10
|
+
trainSide: LineTrainSide;
|
|
11
|
+
}
|
|
12
|
+
export interface LineMoveResult {
|
|
13
|
+
/** Index into {@link LineSpec.movesUci}. */
|
|
14
|
+
index: number;
|
|
15
|
+
isCorrect: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface LineMoveFeedback extends LineMoveResult {
|
|
18
|
+
expectedSan: string;
|
|
19
|
+
}
|
|
20
|
+
/** State handed to the controls renderer on every render. */
|
|
21
|
+
export interface LineControlsRenderProps {
|
|
22
|
+
trainSide: LineTrainSide;
|
|
23
|
+
/** 1-based number of the move currently in focus. */
|
|
24
|
+
moveNumber: number;
|
|
25
|
+
total: number;
|
|
26
|
+
finished: boolean;
|
|
27
|
+
isUserTurn: boolean;
|
|
28
|
+
feedback: LineMoveFeedback | null;
|
|
29
|
+
}
|
|
30
|
+
export interface LineBoardWithControlsProps {
|
|
31
|
+
theme: 'light' | 'dark';
|
|
32
|
+
line: LineSpec;
|
|
33
|
+
/** Called once when the whole line has been walked. */
|
|
34
|
+
onComplete: (perMove: LineMoveResult[]) => void;
|
|
35
|
+
/** Optional per-move callback as each user move is graded. */
|
|
36
|
+
onMove?: (feedback: LineMoveFeedback) => void;
|
|
37
|
+
/** Omit to use {@link defaultRenderLineControls}. */
|
|
38
|
+
renderControls?: (props: LineControlsRenderProps) => React.ReactNode;
|
|
39
|
+
boardWidth?: number;
|
|
40
|
+
/** Delay before auto-playing each opponent move (ms). */
|
|
41
|
+
opponentMoveDelayMs?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Guided line-drill board: walks a known move sequence, auto-playing the
|
|
45
|
+
* opponent and grading each of the trainer's moves against the line. Mirrors
|
|
46
|
+
* {@link PuzzleBoardWithControls} but for opening/line repetition rather than
|
|
47
|
+
* tactical puzzles. Mount one instance per drill (key it by line) so its
|
|
48
|
+
* internal state resets between lines.
|
|
49
|
+
*/
|
|
50
|
+
export declare const LineBoardWithControls: ({ theme, line, onComplete, onMove, renderControls, boardWidth, opponentMoveDelayMs, }: LineBoardWithControlsProps) => React.JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PuzzlePosition } from '../position/Position';
|
|
2
|
+
export interface PuzzleBoardProps {
|
|
3
|
+
position: PuzzlePosition;
|
|
4
|
+
onFeedback: (feedbackData: any) => void;
|
|
5
|
+
incInteractionNum: () => void;
|
|
6
|
+
boardWidth: number;
|
|
7
|
+
/** After a wrong guess, play the correct move instead of allowing retries. */
|
|
8
|
+
revealAnswerOnIncorrect?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const PuzzleBoard: ({ position, onFeedback, incInteractionNum, boardWidth, revealAnswerOnIncorrect, }: PuzzleBoardProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PuzzleResultStatus } from '../analysis';
|
|
3
|
+
import { AnalysisContainerRenderProps, AnalysisControls, AnalysisEngineOptions, AnalysisLayoutConfig, AnalysisMainRenderProps, AnalysisSidebarRenderProps, EngineEvaluationRenderProps } from 'react-chess-core';
|
|
4
|
+
import { type PuzzleControlState } from './defaults/DefaultPuzzleControls';
|
|
5
|
+
export type { PuzzleMoveRecord } from '../position/moveHistory';
|
|
6
|
+
export type { AnalysisContainerRenderProps, AnalysisControls, AnalysisLayoutConfig, AnalysisMainRenderProps, AnalysisSidebarRenderProps, EngineEvaluationRenderProps, } from 'react-chess-core';
|
|
7
|
+
export type { PuzzleAnalysisContext, PuzzleResultStatus } from '../analysis';
|
|
8
|
+
export { DEFAULT_ANALYSIS_LAYOUT } from 'react-chess-core';
|
|
9
|
+
export { DEFAULT_PUZZLE_BOARD_WIDTH } from './puzzleBoardLayout';
|
|
10
|
+
export { DefaultPuzzleControls, defaultRenderControls, } from './defaults/DefaultPuzzleControls';
|
|
11
|
+
export type { PuzzleControlState, PuzzleControlsRenderProps, } from './defaults/DefaultPuzzleControls';
|
|
12
|
+
export interface PuzzleBoardWithControlsProps {
|
|
13
|
+
theme: 'light' | 'dark';
|
|
14
|
+
apiProxy: {
|
|
15
|
+
onFetch: () => Promise<{
|
|
16
|
+
fen: string;
|
|
17
|
+
moves: string[];
|
|
18
|
+
}>;
|
|
19
|
+
/** Called when {@link onFetch} rejects (e.g. network / server down). */
|
|
20
|
+
onFetchError?: (error: unknown) => void;
|
|
21
|
+
onFeedback: (feedbackData: {
|
|
22
|
+
index: number;
|
|
23
|
+
guess?: {
|
|
24
|
+
sourceSquare: string;
|
|
25
|
+
targetSquare: string;
|
|
26
|
+
piece: string;
|
|
27
|
+
};
|
|
28
|
+
hintRequested?: boolean;
|
|
29
|
+
solutionShown?: boolean;
|
|
30
|
+
isCorrect?: boolean;
|
|
31
|
+
isFinished?: boolean;
|
|
32
|
+
}) => void;
|
|
33
|
+
};
|
|
34
|
+
/** Omit to use {@link defaultRenderControls} / {@link DefaultPuzzleControls}. */
|
|
35
|
+
renderControls?: (showHint: () => void, showSolution: () => void, nextPuzzle: () => void, resultStatus: PuzzleResultStatus, analysis: AnalysisControls, controlState: PuzzleControlState) => React.ReactNode;
|
|
36
|
+
renderAnalysisSidebar?: (props: AnalysisSidebarRenderProps) => React.ReactNode;
|
|
37
|
+
renderAnalysisContainer?: (props: AnalysisContainerRenderProps) => React.ReactNode;
|
|
38
|
+
renderEngineEvaluation?: (props: EngineEvaluationRenderProps) => React.ReactNode;
|
|
39
|
+
/** Pixel width of the live puzzle board (separate from analysis). */
|
|
40
|
+
puzzleBoardWidth?: number;
|
|
41
|
+
/** Board + sidebar grid sizes when analysis is open. */
|
|
42
|
+
analysisLayout?: AnalysisLayoutConfig;
|
|
43
|
+
/** Custom board/sidebar placement (overrides {@link analysisLayout} grid). */
|
|
44
|
+
renderAnalysisMain?: (props: AnalysisMainRenderProps) => React.ReactNode;
|
|
45
|
+
engine?: AnalysisEngineOptions;
|
|
46
|
+
/** After a clean solve (no wrong move, hint, or solution reveal), load the next card. */
|
|
47
|
+
autoAdvanceOnComplete?: boolean;
|
|
48
|
+
/** After a wrong guess, play the correct move and wait for the user to advance. */
|
|
49
|
+
revealAnswerOnIncorrect?: boolean;
|
|
50
|
+
}
|
|
51
|
+
export declare const PuzzleBoardWithControls: ({ theme, apiProxy, renderControls, renderAnalysisSidebar, renderAnalysisContainer, renderEngineEvaluation, puzzleBoardWidth, analysisLayout, renderAnalysisMain, engine, autoAdvanceOnComplete, revealAnswerOnIncorrect, }: PuzzleBoardWithControlsProps) => React.JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PuzzlePosition } from '../position/Position';
|
|
2
|
+
export interface PuzzlePlaySurfaceProps {
|
|
3
|
+
position: PuzzlePosition | null;
|
|
4
|
+
onFeedback: (feedbackData: {
|
|
5
|
+
index: number;
|
|
6
|
+
guess?: {
|
|
7
|
+
sourceSquare: string;
|
|
8
|
+
targetSquare: string;
|
|
9
|
+
piece: string;
|
|
10
|
+
};
|
|
11
|
+
hintRequested?: boolean;
|
|
12
|
+
solutionShown?: boolean;
|
|
13
|
+
isCorrect?: boolean;
|
|
14
|
+
isFinished?: boolean;
|
|
15
|
+
}) => void;
|
|
16
|
+
incInteractionNum: () => void;
|
|
17
|
+
boardWidth: number;
|
|
18
|
+
/** After a wrong guess, play the correct move instead of allowing retries. */
|
|
19
|
+
revealAnswerOnIncorrect?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Single mounted board for puzzle play. Shows an empty board while the next
|
|
23
|
+
* position loads so the layout and controls do not flicker between cards.
|
|
24
|
+
*/
|
|
25
|
+
export declare const PuzzlePlaySurface: ({ position, onFeedback, incInteractionNum, boardWidth, revealAnswerOnIncorrect, }: PuzzlePlaySurfaceProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { boardSquareHighlightColors } from 'react-chess-core';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { LineControlsRenderProps } from '../LineBoardWithControls';
|
|
3
|
+
/** Library default line-drill status controls (unstyled). */
|
|
4
|
+
export declare const DefaultLineControls: ({ moveNumber, total, finished, isUserTurn, feedback, }: LineControlsRenderProps) => React.JSX.Element;
|
|
5
|
+
export declare const defaultRenderLineControls: (props: LineControlsRenderProps) => React.JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PuzzleResultStatus } from '../../analysis';
|
|
3
|
+
import { AnalysisControls } from 'react-chess-core';
|
|
4
|
+
export type PuzzleControlState = {
|
|
5
|
+
canShowHint: boolean;
|
|
6
|
+
canShowSolution: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type PuzzleControlsRenderProps = {
|
|
9
|
+
showHint: () => void;
|
|
10
|
+
showSolution: () => void;
|
|
11
|
+
nextPuzzle: () => void;
|
|
12
|
+
resultStatus: PuzzleResultStatus;
|
|
13
|
+
analysis: AnalysisControls;
|
|
14
|
+
controlState: PuzzleControlState;
|
|
15
|
+
};
|
|
16
|
+
/** Library default hint / next / analysis / result controls (unstyled buttons). */
|
|
17
|
+
export declare const DefaultPuzzleControls: ({ showHint, showSolution, nextPuzzle, resultStatus, analysis, controlState, }: PuzzleControlsRenderProps) => React.JSX.Element;
|
|
18
|
+
export declare const defaultRenderControls: (showHint: () => void, showSolution: () => void, nextPuzzle: () => void, resultStatus: PuzzleResultStatus, analysis: AnalysisControls, controlState: PuzzleControlState) => React.JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DefaultPuzzleControls';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
/** Default pixel width for the live puzzle board (analysis uses {@link DEFAULT_ANALYSIS_LAYOUT}). */
|
|
3
|
+
export declare const DEFAULT_PUZZLE_BOARD_WIDTH = 480;
|
|
4
|
+
/** Minimum height reserved below the board so controls do not shift when status changes. */
|
|
5
|
+
export declare const PUZZLE_CONTROLS_MIN_HEIGHT = 96;
|
|
6
|
+
export declare const puzzlePlayColumnStyle: (boardWidth: number) => CSSProperties;
|
|
7
|
+
export declare const puzzleBoardSlotStyle: () => CSSProperties;
|
|
8
|
+
export declare const puzzleControlsSlotStyle: () => CSSProperties;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type EngineEvaluation } from 'react-chess-core';
|
|
3
|
+
export interface EngineEvaluationPanelProps {
|
|
4
|
+
fen: string;
|
|
5
|
+
evaluation: EngineEvaluation;
|
|
6
|
+
theme: 'light' | 'dark';
|
|
7
|
+
}
|
|
8
|
+
export declare const EngineEvaluationPanel: ({ fen, evaluation, theme, }: EngineEvaluationPanelProps) => React.JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StockfishBrowserEngine } from 'react-chess-core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { formatEvaluation, formatPvPreview, normalizeEvalForWhite, uciPvToSan, } from 'react-chess-core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { EngineEvaluationPanel, type EngineEvaluationPanelProps, } from './EngineEvaluationPanel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { isAnalyzableFen } from 'react-chess-core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parseUciInfoLine } from 'react-chess-core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { resolveStockfishScriptUrl, resolveStockfishWasmUrl, resolveStockfishWorkerUrl, } from 'react-chess-core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'react-chess-core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useAnalysisEngine } from 'react-chess-core';
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Traversable } from './Traversable';
|
|
2
|
+
import { Chess } from 'chess.js';
|
|
3
|
+
import { PuzzleMoveRecord } from './moveHistory';
|
|
4
|
+
/** Apply a UCI move (e.g. `e7e8q`) without throwing. */
|
|
5
|
+
export declare function applyUciMove(chess: Chess, uci: string): boolean;
|
|
6
|
+
export declare abstract class Position implements Traversable {
|
|
7
|
+
protected chess: Chess;
|
|
8
|
+
protected moves: string[];
|
|
9
|
+
protected i: number;
|
|
10
|
+
constructor();
|
|
11
|
+
getIndex(): number;
|
|
12
|
+
next(): boolean;
|
|
13
|
+
prev(): boolean;
|
|
14
|
+
isFinished(): boolean;
|
|
15
|
+
/** True when a correct guess at the current index completes the puzzle. */
|
|
16
|
+
isCompletedByCorrectGuess(): boolean;
|
|
17
|
+
fen(): string;
|
|
18
|
+
getCheckSquare(): string;
|
|
19
|
+
}
|
|
20
|
+
export declare function getCheckSquareFromChess(chess: Chess): string;
|
|
21
|
+
/** Side to move for the final (user) ply in a puzzle line. */
|
|
22
|
+
export declare function playerColorForSolution(initialFen: string, moves: string[]): 'white' | 'black';
|
|
23
|
+
export declare class PuzzlePosition extends Position {
|
|
24
|
+
protected isCorrect: boolean;
|
|
25
|
+
protected guessedMove: string;
|
|
26
|
+
protected isHintWanted: boolean;
|
|
27
|
+
protected solutionRevealed: boolean;
|
|
28
|
+
protected playerColor: string;
|
|
29
|
+
protected readonly initialFen: string;
|
|
30
|
+
protected moveHistory: PuzzleMoveRecord[];
|
|
31
|
+
private usedAlternativeCheckmate;
|
|
32
|
+
constructor(initialFEN: string, moves: string[]);
|
|
33
|
+
next(): boolean;
|
|
34
|
+
getInitialFen(): string;
|
|
35
|
+
getSolutionMoves(): string[];
|
|
36
|
+
getMoveHistory(): PuzzleMoveRecord[];
|
|
37
|
+
recordHint(): void;
|
|
38
|
+
recordSolutionShown(): void;
|
|
39
|
+
setSolutionRevealed(revealed: boolean): void;
|
|
40
|
+
isSolutionRevealed(): boolean;
|
|
41
|
+
/** Reset the board to replay an already-revealed solution walkthrough. */
|
|
42
|
+
replaySolution(): void;
|
|
43
|
+
/** Chess-legal move from the current puzzle position (ignores solution line). */
|
|
44
|
+
isLegalMove(sourceSquare: string, targetSquare: string): boolean;
|
|
45
|
+
private buildCandidateUcis;
|
|
46
|
+
private tryMakeUciMove;
|
|
47
|
+
private isCheckmatingMove;
|
|
48
|
+
private applyCheckmateGuess;
|
|
49
|
+
tryGuess: (sourceSquare: string, targetSquare: string, piece: string) => {
|
|
50
|
+
accepted: boolean;
|
|
51
|
+
finished: boolean;
|
|
52
|
+
};
|
|
53
|
+
judgeGuess: (sourceSquare: string, targetSquare: string, piece: string) => boolean;
|
|
54
|
+
resetInteractions(): void;
|
|
55
|
+
/** Play the expected move at the current index and lock further input. */
|
|
56
|
+
revealCorrectMove(): boolean;
|
|
57
|
+
/** True when the last correct guess applied an alternative checkmate. */
|
|
58
|
+
isAlternativeCheckmate(): boolean;
|
|
59
|
+
wantsHint(wants: boolean): void;
|
|
60
|
+
getHintSquare(): string;
|
|
61
|
+
private hint;
|
|
62
|
+
getIncorrectMoveSquare(): string;
|
|
63
|
+
getPlayerColor(): string;
|
|
64
|
+
}
|
|
65
|
+
export declare class GamePosition extends Position {
|
|
66
|
+
constructor(PGN: string);
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|