react-native-chess-kit 0.1.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 +168 -0
- package/lib/commonjs/board-background.js +49 -0
- package/lib/commonjs/board-background.js.map +1 -0
- package/lib/commonjs/board-coordinates.js +78 -0
- package/lib/commonjs/board-coordinates.js.map +1 -0
- package/lib/commonjs/board-drag-ghost.js +110 -0
- package/lib/commonjs/board-drag-ghost.js.map +1 -0
- package/lib/commonjs/board-legal-dots.js +67 -0
- package/lib/commonjs/board-legal-dots.js.map +1 -0
- package/lib/commonjs/board-piece.js +74 -0
- package/lib/commonjs/board-piece.js.map +1 -0
- package/lib/commonjs/board-pieces.js +47 -0
- package/lib/commonjs/board-pieces.js.map +1 -0
- package/lib/commonjs/board.js +188 -0
- package/lib/commonjs/board.js.map +1 -0
- package/lib/commonjs/index.js +26 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/use-board-gesture.js +158 -0
- package/lib/commonjs/use-board-gesture.js.map +1 -0
- package/lib/commonjs/use-board-pieces.js +195 -0
- package/lib/commonjs/use-board-pieces.js.map +1 -0
- package/lib/commonjs/use-board-state.js +78 -0
- package/lib/commonjs/use-board-state.js.map +1 -0
- package/lib/module/board-background.js +44 -0
- package/lib/module/board-background.js.map +1 -0
- package/lib/module/board-coordinates.js +73 -0
- package/lib/module/board-coordinates.js.map +1 -0
- package/lib/module/board-drag-ghost.js +104 -0
- package/lib/module/board-drag-ghost.js.map +1 -0
- package/lib/module/board-legal-dots.js +62 -0
- package/lib/module/board-legal-dots.js.map +1 -0
- package/lib/module/board-piece.js +69 -0
- package/lib/module/board-piece.js.map +1 -0
- package/lib/module/board-pieces.js +42 -0
- package/lib/module/board-pieces.js.map +1 -0
- package/lib/module/board.js +184 -0
- package/lib/module/board.js.map +1 -0
- package/lib/module/index.js +21 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/use-board-gesture.js +154 -0
- package/lib/module/use-board-gesture.js.map +1 -0
- package/lib/module/use-board-pieces.js +189 -0
- package/lib/module/use-board-pieces.js.map +1 -0
- package/lib/module/use-board-state.js +74 -0
- package/lib/module/use-board-state.js.map +1 -0
- package/lib/typescript/board-background.d.ts +15 -0
- package/lib/typescript/board-background.d.ts.map +1 -0
- package/lib/typescript/board-coordinates.d.ts +20 -0
- package/lib/typescript/board-coordinates.d.ts.map +1 -0
- package/lib/typescript/board-drag-ghost.d.ts +21 -0
- package/lib/typescript/board-drag-ghost.d.ts.map +1 -0
- package/lib/typescript/board-legal-dots.d.ts +16 -0
- package/lib/typescript/board-legal-dots.d.ts.map +1 -0
- package/lib/typescript/board-piece.d.ts +36 -0
- package/lib/typescript/board-piece.d.ts.map +1 -0
- package/lib/typescript/board-pieces.d.ts +22 -0
- package/lib/typescript/board-pieces.d.ts.map +1 -0
- package/lib/typescript/board.d.ts +17 -0
- package/lib/typescript/board.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +4 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +88 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/use-board-gesture.d.ts +46 -0
- package/lib/typescript/use-board-gesture.d.ts.map +1 -0
- package/lib/typescript/use-board-pieces.d.ts +23 -0
- package/lib/typescript/use-board-pieces.d.ts.map +1 -0
- package/lib/typescript/use-board-state.d.ts +35 -0
- package/lib/typescript/use-board-state.d.ts.map +1 -0
- package/package.json +73 -0
- package/src/board-background.tsx +46 -0
- package/src/board-coordinates.tsx +98 -0
- package/src/board-drag-ghost.tsx +132 -0
- package/src/board-legal-dots.tsx +73 -0
- package/src/board-piece.tsx +104 -0
- package/src/board-pieces.tsx +56 -0
- package/src/board.tsx +203 -0
- package/src/index.ts +39 -0
- package/src/types.ts +114 -0
- package/src/use-board-gesture.ts +201 -0
- package/src/use-board-pieces.ts +158 -0
- package/src/use-board-state.ts +104 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useRef","useCallback","Chess","useBoardState","initialFen","chessRef","current","getLegalMoves","square","moves","verbose","map","m","to","isCapture","captured","undefined","isPlayerPiece","pieces","player","piece","find","p","pieceColor","color","applyMove","from","promotion","move","applied","fen","undoMove","result","undo","loadFen","load","getFen","getTurn","turn"],"sourceRoot":"..\\..\\src","sources":["use-board-state.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type BoardBackgroundProps = {
|
|
3
|
+
boardSize: number;
|
|
4
|
+
lightColor: string;
|
|
5
|
+
darkColor: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* 64 static colored squares forming the chess board grid.
|
|
9
|
+
*
|
|
10
|
+
* These are plain Views with backgroundColor — no animations, no gesture
|
|
11
|
+
* handlers. They never re-render after mount unless the board theme changes.
|
|
12
|
+
*/
|
|
13
|
+
export declare const BoardBackground: React.NamedExoticComponent<BoardBackgroundProps>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=board-background.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-background.d.ts","sourceRoot":"","sources":["../../src/board-background.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,KAAK,oBAAoB,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,kDA2B1B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ChessColor } from './types';
|
|
3
|
+
type BoardCoordinatesProps = {
|
|
4
|
+
boardSize: number;
|
|
5
|
+
orientation: ChessColor;
|
|
6
|
+
lightColor: string;
|
|
7
|
+
darkColor: string;
|
|
8
|
+
withLetters: boolean;
|
|
9
|
+
withNumbers: boolean;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* File letters (a-h) and rank numbers (1-8) drawn on the board edges.
|
|
13
|
+
*
|
|
14
|
+
* Rendered as absolute-positioned Text components inside each corner square.
|
|
15
|
+
* File letters appear on the bottom rank, rank numbers on the left file.
|
|
16
|
+
* Colors alternate to contrast with the square behind them.
|
|
17
|
+
*/
|
|
18
|
+
export declare const BoardCoordinates: React.NamedExoticComponent<BoardCoordinatesProps>;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=board-coordinates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-coordinates.d.ts","sourceRoot":"","sources":["../../src/board-coordinates.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,KAAK,qBAAqB,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,UAAU,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAOF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,mDAuE3B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type SharedValue } from 'react-native-reanimated';
|
|
3
|
+
type BoardDragGhostProps = {
|
|
4
|
+
squareSize: number;
|
|
5
|
+
isDragging: SharedValue<boolean>;
|
|
6
|
+
dragX: SharedValue<number>;
|
|
7
|
+
dragY: SharedValue<number>;
|
|
8
|
+
dragPieceCode: SharedValue<string | null>;
|
|
9
|
+
/** Render the piece image for a given piece code */
|
|
10
|
+
renderPiece: (code: string, size: number) => React.ReactElement;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Floating piece that follows the user's finger during drag.
|
|
14
|
+
*
|
|
15
|
+
* Only ONE instance exists — not one per piece. It reads drag position
|
|
16
|
+
* from shared values on the UI thread, so zero JS bridge calls and
|
|
17
|
+
* zero re-renders while dragging.
|
|
18
|
+
*/
|
|
19
|
+
export declare const BoardDragGhost: React.NamedExoticComponent<BoardDragGhostProps>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=board-drag-ghost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-drag-ghost.d.ts","sourceRoot":"","sources":["../../src/board-drag-ghost.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAiB,EAEf,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAC;AAEjC,KAAK,mBAAmB,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACjC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,aAAa,EAAE,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1C,oDAAoD;IACpD,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,YAAY,CAAC;CACjE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,iDA4CzB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ChessColor, LegalMoveTarget } from './types';
|
|
3
|
+
type BoardLegalDotsProps = {
|
|
4
|
+
legalMoves: LegalMoveTarget[];
|
|
5
|
+
squareSize: number;
|
|
6
|
+
orientation: ChessColor;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Legal move indicator dots, rendered only when a piece is selected.
|
|
10
|
+
*
|
|
11
|
+
* Dots are CONDITIONALLY rendered (only for actual legal move squares,
|
|
12
|
+
* typically 5-15) instead of always mounting 64 invisible dot views.
|
|
13
|
+
*/
|
|
14
|
+
export declare const BoardLegalDots: React.NamedExoticComponent<BoardLegalDotsProps>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=board-legal-dots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-legal-dots.d.ts","sourceRoot":"","sources":["../../src/board-legal-dots.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG3D,KAAK,mBAAmB,GAAG;IACzB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,iDAsDzB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type SharedValue } from 'react-native-reanimated';
|
|
3
|
+
type BoardPieceProps = {
|
|
4
|
+
/** Target pixel position (top-left of destination square) */
|
|
5
|
+
targetX: number;
|
|
6
|
+
targetY: number;
|
|
7
|
+
/** Square size in pixels */
|
|
8
|
+
squareSize: number;
|
|
9
|
+
/** Move animation duration in ms */
|
|
10
|
+
moveDuration: number;
|
|
11
|
+
/** The piece visual (rendered by parent via renderPiece) */
|
|
12
|
+
children: React.ReactElement;
|
|
13
|
+
/** Gesture state: is this piece currently being dragged? */
|
|
14
|
+
activeSquare: SharedValue<string | null>;
|
|
15
|
+
isDragging: SharedValue<boolean>;
|
|
16
|
+
/** This piece's current square */
|
|
17
|
+
square: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* A single animated chess piece.
|
|
21
|
+
*
|
|
22
|
+
* Animates ONLY `transform` and `opacity` — Reanimated's fast path on Android.
|
|
23
|
+
* No layout properties (top/left/width/height) are animated, avoiding costly
|
|
24
|
+
* layout recalculations on low-end devices.
|
|
25
|
+
*
|
|
26
|
+
* During drag:
|
|
27
|
+
* - Original piece hides (opacity: 0) — the drag ghost shows instead
|
|
28
|
+
* - No position changes on the original piece during drag
|
|
29
|
+
*
|
|
30
|
+
* After a move:
|
|
31
|
+
* - Snaps to new position via withTiming on translateX/translateY
|
|
32
|
+
* - Duration controlled by user's animation speed setting
|
|
33
|
+
*/
|
|
34
|
+
export declare const BoardPieceView: React.NamedExoticComponent<BoardPieceProps>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=board-piece.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-piece.d.ts","sourceRoot":"","sources":["../../src/board-piece.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAiB,EAIf,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAC;AAEjC,KAAK,eAAe,GAAG;IACrB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC;IAC7B,4DAA4D;IAC5D,YAAY,EAAE,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACjC,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc,6CA+D1B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SharedValue } from 'react-native-reanimated';
|
|
3
|
+
import type { ChessColor, BoardPiece } from './types';
|
|
4
|
+
type BoardPiecesProps = {
|
|
5
|
+
pieces: BoardPiece[];
|
|
6
|
+
squareSize: number;
|
|
7
|
+
orientation: ChessColor;
|
|
8
|
+
moveDuration: number;
|
|
9
|
+
renderPiece: (code: string, size: number) => React.ReactElement;
|
|
10
|
+
activeSquare: SharedValue<string | null>;
|
|
11
|
+
isDragging: SharedValue<boolean>;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Renders all pieces on the board.
|
|
15
|
+
*
|
|
16
|
+
* Each piece gets a stable key (from useBoardPieces) so React doesn't
|
|
17
|
+
* unmount/remount pieces that moved — it updates their position props
|
|
18
|
+
* and the BoardPieceView animates the transition.
|
|
19
|
+
*/
|
|
20
|
+
export declare const BoardPiecesLayer: React.NamedExoticComponent<BoardPiecesProps>;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=board-pieces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-pieces.d.ts","sourceRoot":"","sources":["../../src/board-pieces.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAItD,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,UAAU,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,YAAY,CAAC;IAChE,YAAY,EAAE,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,8CA+B3B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { BoardRef, BoardProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* High-performance custom chess board built on Reanimated + Gesture Handler.
|
|
5
|
+
*
|
|
6
|
+
* Architecture:
|
|
7
|
+
* - 1 gesture handler (vs 32 in typical implementations)
|
|
8
|
+
* - ~40 components mounted (vs ~281)
|
|
9
|
+
* - ~75 native views (vs ~470)
|
|
10
|
+
* - 0 React Context providers
|
|
11
|
+
* - 0 re-renders during drag (pure worklet — only 2 shared value writes per frame)
|
|
12
|
+
*
|
|
13
|
+
* Follows chess.com/lichess pattern: single gesture receiver on the board,
|
|
14
|
+
* coordinate math to determine touched piece, shared values for drag state.
|
|
15
|
+
*/
|
|
16
|
+
export declare const Board: React.ForwardRefExoticComponent<BoardProps & React.RefAttributes<BoardRef>>;
|
|
17
|
+
//# sourceMappingURL=board.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../../src/board.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4E,MAAM,OAAO,CAAC;AAIjG,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAmB,MAAM,SAAS,CAAC;AAUrE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,KAAK,6EA+KhB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { Board } from './board';
|
|
2
|
+
export type { ChessColor, MoveMethod, BoardRef, BoardProps, BoardColors, BoardPiece, ParsedPiece, GestureState, LegalMoveTarget, } from './types';
|
|
3
|
+
export { squareToXY, xyToSquare } from './use-board-pieces';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAMhC,YAAY,EAEV,UAAU,EACV,UAAU,EAGV,QAAQ,EACR,UAAU,EACV,WAAW,EAGX,UAAU,EACV,WAAW,EAGX,YAAY,EAGZ,eAAe,GAChB,MAAM,SAAS,CAAC;AAMjB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { SharedValue } from 'react-native-reanimated';
|
|
2
|
+
/** Board orientation / side color */
|
|
3
|
+
export type ChessColor = 'white' | 'black';
|
|
4
|
+
/** How the user interacts with pieces */
|
|
5
|
+
export type MoveMethod = 'drag' | 'click' | 'both';
|
|
6
|
+
/** A single piece on the board with its position and identity */
|
|
7
|
+
export type BoardPiece = {
|
|
8
|
+
/** Unique stable identifier (survives position changes): e.g. "wp-0", "bk-0" */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Piece code matching standard notation: 'wp', 'wn', 'wb', 'wr', 'wq', 'wk', 'bp', etc. */
|
|
11
|
+
code: string;
|
|
12
|
+
/** Current square in algebraic notation: 'a1'..'h8' */
|
|
13
|
+
square: string;
|
|
14
|
+
/** 'w' or 'b' */
|
|
15
|
+
color: 'w' | 'b';
|
|
16
|
+
};
|
|
17
|
+
/** Intermediate representation from FEN parsing (before ID assignment) */
|
|
18
|
+
export type ParsedPiece = {
|
|
19
|
+
code: string;
|
|
20
|
+
square: string;
|
|
21
|
+
color: 'w' | 'b';
|
|
22
|
+
};
|
|
23
|
+
export type BoardRef = {
|
|
24
|
+
/** Pre-apply a move to internal state. Visual animation happens when parent updates the FEN prop. */
|
|
25
|
+
move: (move: {
|
|
26
|
+
from: string;
|
|
27
|
+
to: string;
|
|
28
|
+
}) => void;
|
|
29
|
+
/** Highlight a square with a color */
|
|
30
|
+
highlight: (square: string, color: string) => void;
|
|
31
|
+
/** Clear all imperative highlights */
|
|
32
|
+
clearHighlights: () => void;
|
|
33
|
+
/** Reset board to a new FEN position */
|
|
34
|
+
resetBoard: (fen: string) => void;
|
|
35
|
+
/** Undo the last visually applied move (snap back to previous position) */
|
|
36
|
+
undo: () => void;
|
|
37
|
+
};
|
|
38
|
+
export type BoardColors = {
|
|
39
|
+
light: string;
|
|
40
|
+
dark: string;
|
|
41
|
+
};
|
|
42
|
+
export type BoardProps = {
|
|
43
|
+
/** Current board position in FEN notation */
|
|
44
|
+
fen: string;
|
|
45
|
+
/** Which color is at the bottom of the board */
|
|
46
|
+
orientation: ChessColor;
|
|
47
|
+
/** Board width/height in pixels */
|
|
48
|
+
boardSize: number;
|
|
49
|
+
/** Whether gesture interaction is enabled */
|
|
50
|
+
gestureEnabled: boolean;
|
|
51
|
+
/** Which side can interact: 'white', 'black', or 'both' */
|
|
52
|
+
player: ChessColor | 'both';
|
|
53
|
+
/** Called after a visual move is applied */
|
|
54
|
+
onMove?: (info: {
|
|
55
|
+
from: string;
|
|
56
|
+
to: string;
|
|
57
|
+
}) => void;
|
|
58
|
+
/** Board square colors */
|
|
59
|
+
colors: BoardColors;
|
|
60
|
+
/** Move animation duration in ms (0 = instant) */
|
|
61
|
+
moveDuration: number;
|
|
62
|
+
/** Whether to show file labels (a-h) */
|
|
63
|
+
withLetters: boolean;
|
|
64
|
+
/** Whether to show rank numbers (1-8) */
|
|
65
|
+
withNumbers: boolean;
|
|
66
|
+
/** Custom piece renderer. Receives piece code ('wp', 'bk', etc.) and pixel size. */
|
|
67
|
+
renderPiece?: (pieceCode: string, size: number) => React.ReactElement;
|
|
68
|
+
/** Whether to show legal move dots when a piece is selected */
|
|
69
|
+
showLegalMoves: boolean;
|
|
70
|
+
/** How the user moves pieces */
|
|
71
|
+
moveMethod: MoveMethod;
|
|
72
|
+
};
|
|
73
|
+
export type GestureState = {
|
|
74
|
+
/** Square the active piece started from (null if no drag/selection) */
|
|
75
|
+
activeSquare: SharedValue<string | null>;
|
|
76
|
+
/** Current drag position in board-local pixels */
|
|
77
|
+
dragX: SharedValue<number>;
|
|
78
|
+
dragY: SharedValue<number>;
|
|
79
|
+
/** Whether a drag gesture is currently active */
|
|
80
|
+
isDragging: SharedValue<boolean>;
|
|
81
|
+
/** The piece code being dragged (for rendering the ghost) */
|
|
82
|
+
dragPieceCode: SharedValue<string | null>;
|
|
83
|
+
};
|
|
84
|
+
export type LegalMoveTarget = {
|
|
85
|
+
square: string;
|
|
86
|
+
isCapture: boolean;
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Gesture } from 'react-native-gesture-handler';
|
|
2
|
+
import type { ChessColor, MoveMethod, BoardPiece, LegalMoveTarget, GestureState } from './types';
|
|
3
|
+
type GestureCallbacks = {
|
|
4
|
+
onPieceSelected: (square: string) => void;
|
|
5
|
+
onPieceMoved: (from: string, to: string) => void;
|
|
6
|
+
onSelectionCleared: () => void;
|
|
7
|
+
};
|
|
8
|
+
type UseBoardGestureParams = {
|
|
9
|
+
squareSize: number;
|
|
10
|
+
orientation: ChessColor;
|
|
11
|
+
gestureEnabled: boolean;
|
|
12
|
+
player: ChessColor | 'both';
|
|
13
|
+
moveMethod: MoveMethod;
|
|
14
|
+
pieces: BoardPiece[];
|
|
15
|
+
callbacks: GestureCallbacks;
|
|
16
|
+
/** Currently selected square (for tap-to-move second tap) */
|
|
17
|
+
selectedSquare: string | null;
|
|
18
|
+
/** Legal move targets from the currently selected piece */
|
|
19
|
+
legalMoves: LegalMoveTarget[];
|
|
20
|
+
};
|
|
21
|
+
type UseBoardGestureReturn = {
|
|
22
|
+
gesture: ReturnType<typeof Gesture.Pan>;
|
|
23
|
+
gestureState: GestureState;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Single centralized gesture handler for the entire board.
|
|
27
|
+
*
|
|
28
|
+
* Instead of 32 separate Gesture.Pan() handlers (one per piece), we use ONE
|
|
29
|
+
* handler on the board container. Touch -> coordinate math -> which piece.
|
|
30
|
+
*
|
|
31
|
+
* Supports three modes:
|
|
32
|
+
* - 'drag': drag piece to target square
|
|
33
|
+
* - 'click': tap source piece, then tap target square
|
|
34
|
+
* - 'both': drag or click (default)
|
|
35
|
+
*
|
|
36
|
+
* All drag position tracking uses shared values — zero JS bridge calls,
|
|
37
|
+
* zero re-renders during drag. Only the final move triggers JS via runOnJS.
|
|
38
|
+
*
|
|
39
|
+
* The gesture object is STABLE (only recreated when squareSize, orientation,
|
|
40
|
+
* gestureEnabled, player, or moveMethod change). Frequently-changing data
|
|
41
|
+
* (pieces, selectedSquare, legalMoves) is read from refs via runOnJS bridge
|
|
42
|
+
* functions, avoiding costly gesture teardown/rebuild on every move.
|
|
43
|
+
*/
|
|
44
|
+
export declare function useBoardGesture({ squareSize, orientation, gestureEnabled, player, moveMethod, pieces, callbacks, selectedSquare, legalMoves, }: UseBoardGestureParams): UseBoardGestureReturn;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=use-board-gesture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-board-gesture.d.ts","sourceRoot":"","sources":["../../src/use-board-gesture.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAMvD,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGjG,KAAK,gBAAgB,GAAG;IACtB,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,kBAAkB,EAAE,MAAM,IAAI,CAAC;CAChC,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,UAAU,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;IAC5B,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,6DAA6D;IAC7D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,2DAA2D;IAC3D,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,OAAO,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,YAAY,EAAE,YAAY,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EACV,WAAW,EACX,cAAc,EACd,MAAM,EACN,UAAU,EACV,MAAM,EACN,SAAS,EACT,cAAc,EACd,UAAU,GACX,EAAE,qBAAqB,GAAG,qBAAqB,CAwI/C"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ChessColor, BoardPiece } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Convert square notation to pixel coordinates (top-left corner).
|
|
4
|
+
* Orientation-aware: flips the board when playing as black.
|
|
5
|
+
*/
|
|
6
|
+
export declare function squareToXY(square: string, squareSize: number, orientation: ChessColor): {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Convert pixel coordinates to a square notation string.
|
|
12
|
+
* Clamps to board bounds. Orientation-aware.
|
|
13
|
+
*/
|
|
14
|
+
export declare function xyToSquare(x: number, y: number, squareSize: number, orientation: ChessColor): string;
|
|
15
|
+
/**
|
|
16
|
+
* Manages the piece list derived from FEN, with stable IDs for React keys.
|
|
17
|
+
*
|
|
18
|
+
* Stable IDs prevent unmount/remount cycles when pieces change position.
|
|
19
|
+
* A piece keeps its ID as long as it exists on the board — only capture
|
|
20
|
+
* (removal) or promotion (code change) creates a new ID.
|
|
21
|
+
*/
|
|
22
|
+
export declare function useBoardPieces(fen: string): BoardPiece[];
|
|
23
|
+
//# sourceMappingURL=use-board-pieces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-board-pieces.d.ts","sourceRoot":"","sources":["../../src/use-board-pieces.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAe,MAAM,SAAS,CAAC;AAmDnE;;;GAGG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,UAAU,GACtB;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAS1B;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,UAAU,GACtB,MAAM,CAWR;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,CAwDxD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ChessColor, BoardPiece, LegalMoveTarget } from './types';
|
|
2
|
+
type MoveResult = {
|
|
3
|
+
/** Whether the move was applied to the internal chess.js instance */
|
|
4
|
+
applied: boolean;
|
|
5
|
+
/** The new FEN after the move (if applied) */
|
|
6
|
+
fen?: string;
|
|
7
|
+
};
|
|
8
|
+
type BoardStateReturn = {
|
|
9
|
+
/** Get legal moves for a piece on the given square */
|
|
10
|
+
getLegalMoves: (square: string) => LegalMoveTarget[];
|
|
11
|
+
/** Check if a given square has a piece belonging to the active player */
|
|
12
|
+
isPlayerPiece: (square: string, pieces: BoardPiece[], player: ChessColor | 'both') => boolean;
|
|
13
|
+
/** Apply a move to the internal chess state. Returns the new FEN if valid. */
|
|
14
|
+
applyMove: (from: string, to: string, promotion?: string) => MoveResult;
|
|
15
|
+
/** Undo the last move on the internal chess state */
|
|
16
|
+
undoMove: () => string | null;
|
|
17
|
+
/** Load a new FEN into the internal chess state */
|
|
18
|
+
loadFen: (fen: string) => void;
|
|
19
|
+
/** Get the current FEN from internal state */
|
|
20
|
+
getFen: () => string;
|
|
21
|
+
/** Get the current turn from internal state */
|
|
22
|
+
getTurn: () => 'w' | 'b';
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Manages the internal chess.js instance for legal move validation.
|
|
26
|
+
*
|
|
27
|
+
* This mirrors the visual board state. When the parent passes a new FEN,
|
|
28
|
+
* the internal chess.js is synced. Legal move queries and move application
|
|
29
|
+
* happen against this instance.
|
|
30
|
+
*
|
|
31
|
+
* The chess.js instance lives in a ref — no React state, no re-renders.
|
|
32
|
+
*/
|
|
33
|
+
export declare function useBoardState(initialFen: string): BoardStateReturn;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=use-board-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-board-state.d.ts","sourceRoot":"","sources":["../../src/use-board-state.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvE,KAAK,UAAU,GAAG;IAChB,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,sDAAsD;IACtD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,eAAe,EAAE,CAAC;IACrD,yEAAyE;IACzE,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,KAAK,OAAO,CAAC;IAC9F,8EAA8E;IAC9E,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;IACxE,qDAAqD;IACrD,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC9B,mDAAmD;IACnD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,8CAA8C;IAC9C,MAAM,EAAE,MAAM,MAAM,CAAC;IACrB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,GAAG,GAAG,GAAG,CAAC;CAC1B,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,CAgElE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-chess-kit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "High-performance chess board for React Native. Single gesture handler, ~40 components, 0 re-renders during drag. Built on Reanimated + Gesture Handler.",
|
|
5
|
+
"main": "lib/commonjs/index.js",
|
|
6
|
+
"module": "lib/module/index.js",
|
|
7
|
+
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "src/index.ts",
|
|
9
|
+
"source": "src/index.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"lib",
|
|
13
|
+
"!**/__tests__",
|
|
14
|
+
"!**/__fixtures__",
|
|
15
|
+
"!**/__mocks__"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "bob build",
|
|
19
|
+
"typecheck": "tsc --noEmit",
|
|
20
|
+
"clean": "rimraf lib"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"react-native",
|
|
24
|
+
"chess",
|
|
25
|
+
"chessboard",
|
|
26
|
+
"chess-board",
|
|
27
|
+
"reanimated",
|
|
28
|
+
"gesture-handler",
|
|
29
|
+
"performance",
|
|
30
|
+
"60fps"
|
|
31
|
+
],
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/anas-asghar4831/react-native-chess-kit"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/anas-asghar4831/react-native-chess-kit#readme",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/anas-asghar4831/react-native-chess-kit/issues"
|
|
39
|
+
},
|
|
40
|
+
"author": "anas-asghar4831",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"chess.js": ">=1.0.0",
|
|
44
|
+
"react": ">=18.0.0",
|
|
45
|
+
"react-native": ">=0.70.0",
|
|
46
|
+
"react-native-gesture-handler": ">=2.0.0",
|
|
47
|
+
"react-native-reanimated": ">=3.0.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/react": "~19.1.0",
|
|
51
|
+
"chess.js": "^1.4.0",
|
|
52
|
+
"react": "19.1.0",
|
|
53
|
+
"react-native": "0.81.5",
|
|
54
|
+
"react-native-builder-bob": "^0.35.0",
|
|
55
|
+
"react-native-gesture-handler": "~2.28.0",
|
|
56
|
+
"react-native-reanimated": "~4.1.1",
|
|
57
|
+
"typescript": "~5.9.2"
|
|
58
|
+
},
|
|
59
|
+
"react-native-builder-bob": {
|
|
60
|
+
"source": "src",
|
|
61
|
+
"output": "lib",
|
|
62
|
+
"targets": [
|
|
63
|
+
"commonjs",
|
|
64
|
+
"module",
|
|
65
|
+
[
|
|
66
|
+
"typescript",
|
|
67
|
+
{
|
|
68
|
+
"project": "tsconfig.build.json"
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
type BoardBackgroundProps = {
|
|
5
|
+
boardSize: number;
|
|
6
|
+
lightColor: string;
|
|
7
|
+
darkColor: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 64 static colored squares forming the chess board grid.
|
|
12
|
+
*
|
|
13
|
+
* These are plain Views with backgroundColor — no animations, no gesture
|
|
14
|
+
* handlers. They never re-render after mount unless the board theme changes.
|
|
15
|
+
*/
|
|
16
|
+
export const BoardBackground = React.memo(function BoardBackground({
|
|
17
|
+
boardSize,
|
|
18
|
+
lightColor,
|
|
19
|
+
darkColor,
|
|
20
|
+
}: BoardBackgroundProps) {
|
|
21
|
+
const squareSize = boardSize / 8;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<View style={{ width: boardSize, height: boardSize, flexDirection: 'row', flexWrap: 'wrap' }}>
|
|
25
|
+
{SQUARE_INDICES.map((i) => {
|
|
26
|
+
const row = Math.floor(i / 8);
|
|
27
|
+
const col = i % 8;
|
|
28
|
+
const isLight = (row + col) % 2 === 0;
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<View
|
|
32
|
+
key={i}
|
|
33
|
+
style={{
|
|
34
|
+
width: squareSize,
|
|
35
|
+
height: squareSize,
|
|
36
|
+
backgroundColor: isLight ? lightColor : darkColor,
|
|
37
|
+
}}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
})}
|
|
41
|
+
</View>
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Pre-computed array of 0-63 to avoid allocation on every render
|
|
46
|
+
const SQUARE_INDICES = Array.from({ length: 64 }, (_, i) => i);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, Text } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { ChessColor } from './types';
|
|
5
|
+
|
|
6
|
+
type BoardCoordinatesProps = {
|
|
7
|
+
boardSize: number;
|
|
8
|
+
orientation: ChessColor;
|
|
9
|
+
lightColor: string;
|
|
10
|
+
darkColor: string;
|
|
11
|
+
withLetters: boolean;
|
|
12
|
+
withNumbers: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const FILES_WHITE = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
|
|
16
|
+
const FILES_BLACK = ['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'];
|
|
17
|
+
const RANKS_WHITE = ['8', '7', '6', '5', '4', '3', '2', '1'];
|
|
18
|
+
const RANKS_BLACK = ['1', '2', '3', '4', '5', '6', '7', '8'];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* File letters (a-h) and rank numbers (1-8) drawn on the board edges.
|
|
22
|
+
*
|
|
23
|
+
* Rendered as absolute-positioned Text components inside each corner square.
|
|
24
|
+
* File letters appear on the bottom rank, rank numbers on the left file.
|
|
25
|
+
* Colors alternate to contrast with the square behind them.
|
|
26
|
+
*/
|
|
27
|
+
export const BoardCoordinates = React.memo(function BoardCoordinates({
|
|
28
|
+
boardSize,
|
|
29
|
+
orientation,
|
|
30
|
+
lightColor,
|
|
31
|
+
darkColor,
|
|
32
|
+
withLetters,
|
|
33
|
+
withNumbers,
|
|
34
|
+
}: BoardCoordinatesProps) {
|
|
35
|
+
if (!withLetters && !withNumbers) return null;
|
|
36
|
+
|
|
37
|
+
const squareSize = boardSize / 8;
|
|
38
|
+
const fontSize = squareSize * 0.22;
|
|
39
|
+
const padding = squareSize * 0.06;
|
|
40
|
+
const files = orientation === 'white' ? FILES_WHITE : FILES_BLACK;
|
|
41
|
+
const ranks = orientation === 'white' ? RANKS_WHITE : RANKS_BLACK;
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<View
|
|
45
|
+
style={{ position: 'absolute', width: boardSize, height: boardSize }}
|
|
46
|
+
pointerEvents="none"
|
|
47
|
+
>
|
|
48
|
+
{/* Rank numbers along left edge (inside each row's first square) */}
|
|
49
|
+
{withNumbers &&
|
|
50
|
+
ranks.map((rank, row) => {
|
|
51
|
+
// First column square: row 0 col 0 = light if (0+0)%2===0
|
|
52
|
+
const isLight = row % 2 === 0;
|
|
53
|
+
const textColor = isLight ? darkColor : lightColor;
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<Text
|
|
57
|
+
key={`r-${rank}`}
|
|
58
|
+
style={{
|
|
59
|
+
position: 'absolute',
|
|
60
|
+
left: padding,
|
|
61
|
+
top: row * squareSize + padding,
|
|
62
|
+
fontSize,
|
|
63
|
+
fontWeight: '700',
|
|
64
|
+
color: textColor,
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
{rank}
|
|
68
|
+
</Text>
|
|
69
|
+
);
|
|
70
|
+
})}
|
|
71
|
+
|
|
72
|
+
{/* File letters along bottom edge (inside each column's last square) */}
|
|
73
|
+
{withLetters &&
|
|
74
|
+
files.map((file, col) => {
|
|
75
|
+
// Last row (7), column col: light if (7+col)%2===0
|
|
76
|
+
const isLight = (7 + col) % 2 === 0;
|
|
77
|
+
const textColor = isLight ? darkColor : lightColor;
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<Text
|
|
81
|
+
key={`f-${file}`}
|
|
82
|
+
style={{
|
|
83
|
+
position: 'absolute',
|
|
84
|
+
right: (7 - col) * squareSize + padding,
|
|
85
|
+
bottom: padding,
|
|
86
|
+
fontSize,
|
|
87
|
+
fontWeight: '700',
|
|
88
|
+
color: textColor,
|
|
89
|
+
textAlign: 'right',
|
|
90
|
+
}}
|
|
91
|
+
>
|
|
92
|
+
{file}
|
|
93
|
+
</Text>
|
|
94
|
+
);
|
|
95
|
+
})}
|
|
96
|
+
</View>
|
|
97
|
+
);
|
|
98
|
+
});
|