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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 anas-asghar4831
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# react-native-chess-kit
|
|
2
|
+
|
|
3
|
+
High-performance chess board for React Native. Built for 60fps on budget Android devices.
|
|
4
|
+
|
|
5
|
+
## Performance
|
|
6
|
+
|
|
7
|
+
| Metric | react-native-chess-kit | expo-chessboard |
|
|
8
|
+
|--------|----------------------|-----------------|
|
|
9
|
+
| Gesture handlers | 1 (centralized) | 32 (one per piece) |
|
|
10
|
+
| Mounted components | ~40 | ~281 |
|
|
11
|
+
| Native views | ~75 | ~470 |
|
|
12
|
+
| React Context providers | 0 | 8 |
|
|
13
|
+
| Re-renders during drag | 0 | Per-frame |
|
|
14
|
+
|
|
15
|
+
Zero React re-renders during drag -- all animation runs on the UI thread via Reanimated worklets. Pieces animate only `transform` + `opacity` (Reanimated's fast path). Stable piece IDs survive position changes without unmount/remount cycles.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install react-native-chess-kit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Peer dependencies
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install react-native-reanimated react-native-gesture-handler chess.js
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| Package | Version |
|
|
30
|
+
|---------|---------|
|
|
31
|
+
| react-native-reanimated | >= 3.0.0 |
|
|
32
|
+
| react-native-gesture-handler | >= 2.0.0 |
|
|
33
|
+
| chess.js | >= 1.0.0 |
|
|
34
|
+
| react | >= 18.0.0 |
|
|
35
|
+
| react-native | >= 0.70.0 |
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { useRef } from 'react';
|
|
41
|
+
import { Board } from 'react-native-chess-kit';
|
|
42
|
+
import type { BoardRef } from 'react-native-chess-kit';
|
|
43
|
+
|
|
44
|
+
function ChessScreen() {
|
|
45
|
+
const boardRef = useRef<BoardRef>(null);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Board
|
|
49
|
+
ref={boardRef}
|
|
50
|
+
fen="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
|
51
|
+
orientation="white"
|
|
52
|
+
boardSize={360}
|
|
53
|
+
gestureEnabled={true}
|
|
54
|
+
player="white"
|
|
55
|
+
colors={{ light: '#eeeed2', dark: '#769656' }}
|
|
56
|
+
moveDuration={200}
|
|
57
|
+
withLetters={true}
|
|
58
|
+
withNumbers={true}
|
|
59
|
+
showLegalMoves={true}
|
|
60
|
+
moveMethod="both"
|
|
61
|
+
onMove={({ from, to }) => {
|
|
62
|
+
console.log(`Moved from ${from} to ${to}`);
|
|
63
|
+
}}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Props
|
|
70
|
+
|
|
71
|
+
| Prop | Type | Default | Description |
|
|
72
|
+
|------|------|---------|-------------|
|
|
73
|
+
| `fen` | `string` | required | Board position in FEN notation |
|
|
74
|
+
| `orientation` | `'white' \| 'black'` | required | Which color is at the bottom |
|
|
75
|
+
| `boardSize` | `number` | required | Board width/height in pixels |
|
|
76
|
+
| `gestureEnabled` | `boolean` | required | Whether touch interaction is enabled |
|
|
77
|
+
| `player` | `'white' \| 'black' \| 'both'` | required | Which side can move pieces |
|
|
78
|
+
| `colors` | `{ light: string, dark: string }` | required | Square colors |
|
|
79
|
+
| `moveDuration` | `number` | required | Animation duration in ms (0 = instant) |
|
|
80
|
+
| `withLetters` | `boolean` | required | Show file labels (a-h) |
|
|
81
|
+
| `withNumbers` | `boolean` | required | Show rank numbers (1-8) |
|
|
82
|
+
| `showLegalMoves` | `boolean` | required | Show legal move dots on piece selection |
|
|
83
|
+
| `moveMethod` | `'drag' \| 'click' \| 'both'` | required | How the user moves pieces |
|
|
84
|
+
| `onMove` | `(info: { from, to }) => void` | optional | Called after a move gesture completes |
|
|
85
|
+
| `renderPiece` | `(code, size) => ReactElement` | optional | Custom piece renderer |
|
|
86
|
+
|
|
87
|
+
## Ref API
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const boardRef = useRef<BoardRef>(null);
|
|
91
|
+
|
|
92
|
+
// Programmatic move (e.g. opponent's move, puzzle auto-play)
|
|
93
|
+
boardRef.current?.move({ from: 'e2', to: 'e4' });
|
|
94
|
+
|
|
95
|
+
// Highlight a square
|
|
96
|
+
boardRef.current?.highlight('e4', 'rgba(255, 255, 0, 0.5)');
|
|
97
|
+
|
|
98
|
+
// Clear all highlights
|
|
99
|
+
boardRef.current?.clearHighlights();
|
|
100
|
+
|
|
101
|
+
// Reset to a new position
|
|
102
|
+
boardRef.current?.resetBoard('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');
|
|
103
|
+
|
|
104
|
+
// Undo the last visual move (snap back)
|
|
105
|
+
boardRef.current?.undo();
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Custom Piece Rendering
|
|
109
|
+
|
|
110
|
+
Use `renderPiece` to provide your own piece images:
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
import { Image } from 'expo-image';
|
|
114
|
+
|
|
115
|
+
const PIECE_IMAGES = {
|
|
116
|
+
wp: require('./assets/pieces/wp.png'),
|
|
117
|
+
wn: require('./assets/pieces/wn.png'),
|
|
118
|
+
// ... etc
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
<Board
|
|
122
|
+
renderPiece={(code, size) => (
|
|
123
|
+
<Image
|
|
124
|
+
source={PIECE_IMAGES[code]}
|
|
125
|
+
style={{ width: size, height: size }}
|
|
126
|
+
cachePolicy="memory-disk"
|
|
127
|
+
/>
|
|
128
|
+
)}
|
|
129
|
+
// ... other props
|
|
130
|
+
/>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Exports
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
// Component
|
|
137
|
+
export { Board } from 'react-native-chess-kit';
|
|
138
|
+
|
|
139
|
+
// Types
|
|
140
|
+
export type {
|
|
141
|
+
BoardRef,
|
|
142
|
+
BoardProps,
|
|
143
|
+
BoardColors,
|
|
144
|
+
BoardPiece,
|
|
145
|
+
ChessColor,
|
|
146
|
+
MoveMethod,
|
|
147
|
+
GestureState,
|
|
148
|
+
LegalMoveTarget,
|
|
149
|
+
ParsedPiece,
|
|
150
|
+
} from 'react-native-chess-kit';
|
|
151
|
+
|
|
152
|
+
// Utilities (useful for overlay positioning)
|
|
153
|
+
export { squareToXY, xyToSquare } from 'react-native-chess-kit';
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Architecture
|
|
157
|
+
|
|
158
|
+
The board follows the chess.com / lichess pattern:
|
|
159
|
+
|
|
160
|
+
- **Single gesture handler** at the board level (not per-piece)
|
|
161
|
+
- **Reanimated shared values** for drag state (zero JS thread work during drag)
|
|
162
|
+
- **Stable piece IDs** via smart FEN diffing (pieces survive position changes)
|
|
163
|
+
- **chess.js** for internal legal move validation
|
|
164
|
+
- **Worklet-only animation** using transform + opacity (Reanimated fast path)
|
|
165
|
+
|
|
166
|
+
## License
|
|
167
|
+
|
|
168
|
+
MIT
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BoardBackground = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
/**
|
|
12
|
+
* 64 static colored squares forming the chess board grid.
|
|
13
|
+
*
|
|
14
|
+
* These are plain Views with backgroundColor — no animations, no gesture
|
|
15
|
+
* handlers. They never re-render after mount unless the board theme changes.
|
|
16
|
+
*/
|
|
17
|
+
const BoardBackground = exports.BoardBackground = /*#__PURE__*/_react.default.memo(function BoardBackground({
|
|
18
|
+
boardSize,
|
|
19
|
+
lightColor,
|
|
20
|
+
darkColor
|
|
21
|
+
}) {
|
|
22
|
+
const squareSize = boardSize / 8;
|
|
23
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
24
|
+
style: {
|
|
25
|
+
width: boardSize,
|
|
26
|
+
height: boardSize,
|
|
27
|
+
flexDirection: 'row',
|
|
28
|
+
flexWrap: 'wrap'
|
|
29
|
+
},
|
|
30
|
+
children: SQUARE_INDICES.map(i => {
|
|
31
|
+
const row = Math.floor(i / 8);
|
|
32
|
+
const col = i % 8;
|
|
33
|
+
const isLight = (row + col) % 2 === 0;
|
|
34
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
35
|
+
style: {
|
|
36
|
+
width: squareSize,
|
|
37
|
+
height: squareSize,
|
|
38
|
+
backgroundColor: isLight ? lightColor : darkColor
|
|
39
|
+
}
|
|
40
|
+
}, i);
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Pre-computed array of 0-63 to avoid allocation on every render
|
|
46
|
+
const SQUARE_INDICES = Array.from({
|
|
47
|
+
length: 64
|
|
48
|
+
}, (_, i) => i);
|
|
49
|
+
//# sourceMappingURL=board-background.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireDefault","require","_reactNative","_jsxRuntime","e","__esModule","default","BoardBackground","exports","React","memo","boardSize","lightColor","darkColor","squareSize","jsx","View","style","width","height","flexDirection","flexWrap","children","SQUARE_INDICES","map","i","row","Math","floor","col","isLight","backgroundColor","Array","from","length","_"],"sourceRoot":"..\\..\\src","sources":["board-background.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAAoC,IAAAE,WAAA,GAAAF,OAAA;AAAA,SAAAD,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAQpC;AACA;AACA;AACA;AACA;AACA;AACO,MAAMG,eAAe,GAAAC,OAAA,CAAAD,eAAA,gBAAGE,cAAK,CAACC,IAAI,CAAC,SAASH,eAAeA,CAAC;EACjEI,SAAS;EACTC,UAAU;EACVC;AACoB,CAAC,EAAE;EACvB,MAAMC,UAAU,GAAGH,SAAS,GAAG,CAAC;EAEhC,oBACE,IAAAR,WAAA,CAAAY,GAAA,EAACb,YAAA,CAAAc,IAAI;IAACC,KAAK,EAAE;MAAEC,KAAK,EAAEP,SAAS;MAAEQ,MAAM,EAAER,SAAS;MAAES,aAAa,EAAE,KAAK;MAAEC,QAAQ,EAAE;IAAO,CAAE;IAAAC,QAAA,EAC1FC,cAAc,CAACC,GAAG,CAAEC,CAAC,IAAK;MACzB,MAAMC,GAAG,GAAGC,IAAI,CAACC,KAAK,CAACH,CAAC,GAAG,CAAC,CAAC;MAC7B,MAAMI,GAAG,GAAGJ,CAAC,GAAG,CAAC;MACjB,MAAMK,OAAO,GAAG,CAACJ,GAAG,GAAGG,GAAG,IAAI,CAAC,KAAK,CAAC;MAErC,oBACE,IAAA1B,WAAA,CAAAY,GAAA,EAACb,YAAA,CAAAc,IAAI;QAEHC,KAAK,EAAE;UACLC,KAAK,EAAEJ,UAAU;UACjBK,MAAM,EAAEL,UAAU;UAClBiB,eAAe,EAAED,OAAO,GAAGlB,UAAU,GAAGC;QAC1C;MAAE,GALGY,CAMN,CAAC;IAEN,CAAC;EAAC,CACE,CAAC;AAEX,CAAC,CAAC;;AAEF;AACA,MAAMF,cAAc,GAAGS,KAAK,CAACC,IAAI,CAAC;EAAEC,MAAM,EAAE;AAAG,CAAC,EAAE,CAACC,CAAC,EAAEV,CAAC,KAAKA,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BoardCoordinates = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
const FILES_WHITE = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
|
|
12
|
+
const FILES_BLACK = ['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'];
|
|
13
|
+
const RANKS_WHITE = ['8', '7', '6', '5', '4', '3', '2', '1'];
|
|
14
|
+
const RANKS_BLACK = ['1', '2', '3', '4', '5', '6', '7', '8'];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* File letters (a-h) and rank numbers (1-8) drawn on the board edges.
|
|
18
|
+
*
|
|
19
|
+
* Rendered as absolute-positioned Text components inside each corner square.
|
|
20
|
+
* File letters appear on the bottom rank, rank numbers on the left file.
|
|
21
|
+
* Colors alternate to contrast with the square behind them.
|
|
22
|
+
*/
|
|
23
|
+
const BoardCoordinates = exports.BoardCoordinates = /*#__PURE__*/_react.default.memo(function BoardCoordinates({
|
|
24
|
+
boardSize,
|
|
25
|
+
orientation,
|
|
26
|
+
lightColor,
|
|
27
|
+
darkColor,
|
|
28
|
+
withLetters,
|
|
29
|
+
withNumbers
|
|
30
|
+
}) {
|
|
31
|
+
if (!withLetters && !withNumbers) return null;
|
|
32
|
+
const squareSize = boardSize / 8;
|
|
33
|
+
const fontSize = squareSize * 0.22;
|
|
34
|
+
const padding = squareSize * 0.06;
|
|
35
|
+
const files = orientation === 'white' ? FILES_WHITE : FILES_BLACK;
|
|
36
|
+
const ranks = orientation === 'white' ? RANKS_WHITE : RANKS_BLACK;
|
|
37
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
38
|
+
style: {
|
|
39
|
+
position: 'absolute',
|
|
40
|
+
width: boardSize,
|
|
41
|
+
height: boardSize
|
|
42
|
+
},
|
|
43
|
+
pointerEvents: "none",
|
|
44
|
+
children: [withNumbers && ranks.map((rank, row) => {
|
|
45
|
+
// First column square: row 0 col 0 = light if (0+0)%2===0
|
|
46
|
+
const isLight = row % 2 === 0;
|
|
47
|
+
const textColor = isLight ? darkColor : lightColor;
|
|
48
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
49
|
+
style: {
|
|
50
|
+
position: 'absolute',
|
|
51
|
+
left: padding,
|
|
52
|
+
top: row * squareSize + padding,
|
|
53
|
+
fontSize,
|
|
54
|
+
fontWeight: '700',
|
|
55
|
+
color: textColor
|
|
56
|
+
},
|
|
57
|
+
children: rank
|
|
58
|
+
}, `r-${rank}`);
|
|
59
|
+
}), withLetters && files.map((file, col) => {
|
|
60
|
+
// Last row (7), column col: light if (7+col)%2===0
|
|
61
|
+
const isLight = (7 + col) % 2 === 0;
|
|
62
|
+
const textColor = isLight ? darkColor : lightColor;
|
|
63
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
64
|
+
style: {
|
|
65
|
+
position: 'absolute',
|
|
66
|
+
right: (7 - col) * squareSize + padding,
|
|
67
|
+
bottom: padding,
|
|
68
|
+
fontSize,
|
|
69
|
+
fontWeight: '700',
|
|
70
|
+
color: textColor,
|
|
71
|
+
textAlign: 'right'
|
|
72
|
+
},
|
|
73
|
+
children: file
|
|
74
|
+
}, `f-${file}`);
|
|
75
|
+
})]
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=board-coordinates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireDefault","require","_reactNative","_jsxRuntime","e","__esModule","default","FILES_WHITE","FILES_BLACK","RANKS_WHITE","RANKS_BLACK","BoardCoordinates","exports","React","memo","boardSize","orientation","lightColor","darkColor","withLetters","withNumbers","squareSize","fontSize","padding","files","ranks","jsxs","View","style","position","width","height","pointerEvents","children","map","rank","row","isLight","textColor","jsx","Text","left","top","fontWeight","color","file","col","right","bottom","textAlign"],"sourceRoot":"..\\..\\src","sources":["board-coordinates.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BoardDragGhost = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
|
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
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
|
+
const BoardDragGhost = exports.BoardDragGhost = /*#__PURE__*/_react.default.memo(function BoardDragGhost({
|
|
20
|
+
squareSize,
|
|
21
|
+
isDragging,
|
|
22
|
+
dragX,
|
|
23
|
+
dragY,
|
|
24
|
+
dragPieceCode,
|
|
25
|
+
renderPiece
|
|
26
|
+
}) {
|
|
27
|
+
const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
28
|
+
if (!isDragging.value || !dragPieceCode.value) {
|
|
29
|
+
return {
|
|
30
|
+
opacity: 0,
|
|
31
|
+
transform: [{
|
|
32
|
+
translateX: 0
|
|
33
|
+
}, {
|
|
34
|
+
translateY: 0
|
|
35
|
+
}]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
opacity: 1,
|
|
40
|
+
// Center the piece on the finger, slightly above for visibility
|
|
41
|
+
transform: [{
|
|
42
|
+
translateX: dragX.value - squareSize / 2
|
|
43
|
+
}, {
|
|
44
|
+
translateY: dragY.value - squareSize
|
|
45
|
+
}, {
|
|
46
|
+
scale: 1.1
|
|
47
|
+
}]
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
51
|
+
style: [{
|
|
52
|
+
position: 'absolute',
|
|
53
|
+
width: squareSize,
|
|
54
|
+
height: squareSize,
|
|
55
|
+
zIndex: 100
|
|
56
|
+
}, animatedStyle],
|
|
57
|
+
pointerEvents: "none",
|
|
58
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(DragGhostContent, {
|
|
59
|
+
renderPiece: renderPiece,
|
|
60
|
+
squareSize: squareSize,
|
|
61
|
+
dragPieceCode: dragPieceCode
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Inner content that renders the actual piece image.
|
|
68
|
+
* Separate component so the Animated.View wrapper doesn't need
|
|
69
|
+
* to re-render when the piece code changes — it uses shared value.
|
|
70
|
+
*/
|
|
71
|
+
const DragGhostContent = /*#__PURE__*/_react.default.memo(function DragGhostContent({
|
|
72
|
+
renderPiece,
|
|
73
|
+
squareSize,
|
|
74
|
+
dragPieceCode
|
|
75
|
+
}) {
|
|
76
|
+
// We render all 12 possible piece types and show/hide based on dragPieceCode.
|
|
77
|
+
// This avoids re-mounting the Image component during drag.
|
|
78
|
+
// Only the opacity changes — pure worklet animation.
|
|
79
|
+
const codes = PIECE_CODES;
|
|
80
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
81
|
+
children: codes.map(code => /*#__PURE__*/(0, _jsxRuntime.jsx)(GhostPieceSlot, {
|
|
82
|
+
code: code,
|
|
83
|
+
squareSize: squareSize,
|
|
84
|
+
dragPieceCode: dragPieceCode,
|
|
85
|
+
renderPiece: renderPiece
|
|
86
|
+
}, code))
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
const GhostPieceSlot = /*#__PURE__*/_react.default.memo(function GhostPieceSlot({
|
|
90
|
+
code,
|
|
91
|
+
squareSize,
|
|
92
|
+
dragPieceCode,
|
|
93
|
+
renderPiece
|
|
94
|
+
}) {
|
|
95
|
+
const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
|
|
96
|
+
opacity: dragPieceCode.value === code ? 1 : 0
|
|
97
|
+
}));
|
|
98
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
99
|
+
style: [{
|
|
100
|
+
position: 'absolute',
|
|
101
|
+
width: squareSize,
|
|
102
|
+
height: squareSize
|
|
103
|
+
}, animatedStyle],
|
|
104
|
+
children: renderPiece(code, squareSize)
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// All 12 piece codes — pre-computed to avoid allocation
|
|
109
|
+
const PIECE_CODES = ['wp', 'wn', 'wb', 'wr', 'wq', 'wk', 'bp', 'bn', 'bb', 'br', 'bq', 'bk'];
|
|
110
|
+
//# sourceMappingURL=board-drag-ghost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireDefault","require","_reactNativeReanimated","_interopRequireWildcard","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","BoardDragGhost","exports","React","memo","squareSize","isDragging","dragX","dragY","dragPieceCode","renderPiece","animatedStyle","useAnimatedStyle","value","opacity","transform","translateX","translateY","scale","jsx","View","style","position","width","height","zIndex","pointerEvents","children","DragGhostContent","codes","PIECE_CODES","Fragment","map","code","GhostPieceSlot"],"sourceRoot":"..\\..\\src","sources":["board-drag-ghost.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BoardLegalDots = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _useBoardPieces = require("./use-board-pieces");
|
|
10
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
/**
|
|
13
|
+
* Legal move indicator dots, rendered only when a piece is selected.
|
|
14
|
+
*
|
|
15
|
+
* Dots are CONDITIONALLY rendered (only for actual legal move squares,
|
|
16
|
+
* typically 5-15) instead of always mounting 64 invisible dot views.
|
|
17
|
+
*/
|
|
18
|
+
const BoardLegalDots = exports.BoardLegalDots = /*#__PURE__*/_react.default.memo(function BoardLegalDots({
|
|
19
|
+
legalMoves,
|
|
20
|
+
squareSize,
|
|
21
|
+
orientation
|
|
22
|
+
}) {
|
|
23
|
+
if (legalMoves.length === 0) return null;
|
|
24
|
+
const dotSize = squareSize * 0.28;
|
|
25
|
+
const ringSize = squareSize * 0.85;
|
|
26
|
+
const borderWidth = squareSize * 0.08;
|
|
27
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
28
|
+
style: {
|
|
29
|
+
position: 'absolute',
|
|
30
|
+
width: squareSize * 8,
|
|
31
|
+
height: squareSize * 8
|
|
32
|
+
},
|
|
33
|
+
pointerEvents: "none",
|
|
34
|
+
children: legalMoves.map(move => {
|
|
35
|
+
const {
|
|
36
|
+
x,
|
|
37
|
+
y
|
|
38
|
+
} = (0, _useBoardPieces.squareToXY)(move.square, squareSize, orientation);
|
|
39
|
+
if (move.isCapture) {
|
|
40
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
41
|
+
style: {
|
|
42
|
+
position: 'absolute',
|
|
43
|
+
left: x + (squareSize - ringSize) / 2,
|
|
44
|
+
top: y + (squareSize - ringSize) / 2,
|
|
45
|
+
width: ringSize,
|
|
46
|
+
height: ringSize,
|
|
47
|
+
borderRadius: ringSize / 2,
|
|
48
|
+
borderWidth,
|
|
49
|
+
borderColor: 'rgba(0, 0, 0, 0.25)'
|
|
50
|
+
}
|
|
51
|
+
}, move.square);
|
|
52
|
+
}
|
|
53
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
54
|
+
style: {
|
|
55
|
+
position: 'absolute',
|
|
56
|
+
left: x + (squareSize - dotSize) / 2,
|
|
57
|
+
top: y + (squareSize - dotSize) / 2,
|
|
58
|
+
width: dotSize,
|
|
59
|
+
height: dotSize,
|
|
60
|
+
borderRadius: dotSize / 2,
|
|
61
|
+
backgroundColor: 'rgba(0, 0, 0, 0.25)'
|
|
62
|
+
}
|
|
63
|
+
}, move.square);
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=board-legal-dots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireDefault","require","_reactNative","_useBoardPieces","_jsxRuntime","e","__esModule","default","BoardLegalDots","exports","React","memo","legalMoves","squareSize","orientation","length","dotSize","ringSize","borderWidth","jsx","View","style","position","width","height","pointerEvents","children","map","move","x","y","squareToXY","square","isCapture","left","top","borderRadius","borderColor","backgroundColor"],"sourceRoot":"..\\..\\src","sources":["board-legal-dots.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAGA,IAAAE,eAAA,GAAAF,OAAA;AAAgD,IAAAG,WAAA,GAAAH,OAAA;AAAA,SAAAD,uBAAAK,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAQhD;AACA;AACA;AACA;AACA;AACA;AACO,MAAMG,cAAc,GAAAC,OAAA,CAAAD,cAAA,gBAAGE,cAAK,CAACC,IAAI,CAAC,SAASH,cAAcA,CAAC;EAC/DI,UAAU;EACVC,UAAU;EACVC;AACmB,CAAC,EAAE;EACtB,IAAIF,UAAU,CAACG,MAAM,KAAK,CAAC,EAAE,OAAO,IAAI;EAExC,MAAMC,OAAO,GAAGH,UAAU,GAAG,IAAI;EACjC,MAAMI,QAAQ,GAAGJ,UAAU,GAAG,IAAI;EAClC,MAAMK,WAAW,GAAGL,UAAU,GAAG,IAAI;EAErC,oBACE,IAAAT,WAAA,CAAAe,GAAA,EAACjB,YAAA,CAAAkB,IAAI;IACHC,KAAK,EAAE;MAAEC,QAAQ,EAAE,UAAU;MAAEC,KAAK,EAAEV,UAAU,GAAG,CAAC;MAAEW,MAAM,EAAEX,UAAU,GAAG;IAAE,CAAE;IAC/EY,aAAa,EAAC,MAAM;IAAAC,QAAA,EAEnBd,UAAU,CAACe,GAAG,CAAEC,IAAI,IAAK;MACxB,MAAM;QAAEC,CAAC;QAAEC;MAAE,CAAC,GAAG,IAAAC,0BAAU,EAACH,IAAI,CAACI,MAAM,EAAEnB,UAAU,EAAEC,WAAW,CAAC;MAEjE,IAAIc,IAAI,CAACK,SAAS,EAAE;QAClB,oBACE,IAAA7B,WAAA,CAAAe,GAAA,EAACjB,YAAA,CAAAkB,IAAI;UAEHC,KAAK,EAAE;YACLC,QAAQ,EAAE,UAAU;YACpBY,IAAI,EAAEL,CAAC,GAAG,CAAChB,UAAU,GAAGI,QAAQ,IAAI,CAAC;YACrCkB,GAAG,EAAEL,CAAC,GAAG,CAACjB,UAAU,GAAGI,QAAQ,IAAI,CAAC;YACpCM,KAAK,EAAEN,QAAQ;YACfO,MAAM,EAAEP,QAAQ;YAChBmB,YAAY,EAAEnB,QAAQ,GAAG,CAAC;YAC1BC,WAAW;YACXmB,WAAW,EAAE;UACf;QAAE,GAVGT,IAAI,CAACI,MAWX,CAAC;MAEN;MAEA,oBACE,IAAA5B,WAAA,CAAAe,GAAA,EAACjB,YAAA,CAAAkB,IAAI;QAEHC,KAAK,EAAE;UACLC,QAAQ,EAAE,UAAU;UACpBY,IAAI,EAAEL,CAAC,GAAG,CAAChB,UAAU,GAAGG,OAAO,IAAI,CAAC;UACpCmB,GAAG,EAAEL,CAAC,GAAG,CAACjB,UAAU,GAAGG,OAAO,IAAI,CAAC;UACnCO,KAAK,EAAEP,OAAO;UACdQ,MAAM,EAAER,OAAO;UACfoB,YAAY,EAAEpB,OAAO,GAAG,CAAC;UACzBsB,eAAe,EAAE;QACnB;MAAE,GATGV,IAAI,CAACI,MAUX,CAAC;IAEN,CAAC;EAAC,CACE,CAAC;AAEX,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BoardPieceView = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
|
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
+
/**
|
|
12
|
+
* A single animated chess piece.
|
|
13
|
+
*
|
|
14
|
+
* Animates ONLY `transform` and `opacity` — Reanimated's fast path on Android.
|
|
15
|
+
* No layout properties (top/left/width/height) are animated, avoiding costly
|
|
16
|
+
* layout recalculations on low-end devices.
|
|
17
|
+
*
|
|
18
|
+
* During drag:
|
|
19
|
+
* - Original piece hides (opacity: 0) — the drag ghost shows instead
|
|
20
|
+
* - No position changes on the original piece during drag
|
|
21
|
+
*
|
|
22
|
+
* After a move:
|
|
23
|
+
* - Snaps to new position via withTiming on translateX/translateY
|
|
24
|
+
* - Duration controlled by user's animation speed setting
|
|
25
|
+
*/
|
|
26
|
+
const BoardPieceView = exports.BoardPieceView = /*#__PURE__*/_react.default.memo(function BoardPieceView({
|
|
27
|
+
targetX,
|
|
28
|
+
targetY,
|
|
29
|
+
squareSize,
|
|
30
|
+
moveDuration,
|
|
31
|
+
children,
|
|
32
|
+
activeSquare,
|
|
33
|
+
isDragging,
|
|
34
|
+
square
|
|
35
|
+
}) {
|
|
36
|
+
// Shared values for smooth animated position — written from JS, read on UI thread
|
|
37
|
+
const currentX = (0, _reactNativeReanimated.useSharedValue)(targetX);
|
|
38
|
+
const currentY = (0, _reactNativeReanimated.useSharedValue)(targetY);
|
|
39
|
+
|
|
40
|
+
// When target position changes (piece moved), animate to the new square.
|
|
41
|
+
// useEffect is the correct pattern for reacting to JS prop changes —
|
|
42
|
+
// useDerivedValue is meant for shared-value-to-shared-value derivation.
|
|
43
|
+
(0, _react.useEffect)(() => {
|
|
44
|
+
currentX.value = moveDuration > 0 ? (0, _reactNativeReanimated.withTiming)(targetX, {
|
|
45
|
+
duration: moveDuration
|
|
46
|
+
}) : targetX;
|
|
47
|
+
currentY.value = moveDuration > 0 ? (0, _reactNativeReanimated.withTiming)(targetY, {
|
|
48
|
+
duration: moveDuration
|
|
49
|
+
}) : targetY;
|
|
50
|
+
}, [targetX, targetY, moveDuration, currentX, currentY]);
|
|
51
|
+
const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
52
|
+
const isBeingDragged = isDragging.value && activeSquare.value === square;
|
|
53
|
+
return {
|
|
54
|
+
transform: [{
|
|
55
|
+
translateX: currentX.value
|
|
56
|
+
}, {
|
|
57
|
+
translateY: currentY.value
|
|
58
|
+
}],
|
|
59
|
+
// Hide original piece during drag — drag ghost renders on top
|
|
60
|
+
opacity: isBeingDragged ? 0 : 1
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
64
|
+
style: [{
|
|
65
|
+
position: 'absolute',
|
|
66
|
+
width: squareSize,
|
|
67
|
+
height: squareSize
|
|
68
|
+
}, animatedStyle],
|
|
69
|
+
children: children
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
// Custom comparator: only re-render when position or square changes
|
|
73
|
+
(prev, next) => prev.targetX === next.targetX && prev.targetY === next.targetY && prev.square === next.square && prev.squareSize === next.squareSize && prev.moveDuration === next.moveDuration && prev.children === next.children);
|
|
74
|
+
//# sourceMappingURL=board-piece.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNativeReanimated","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","BoardPieceView","exports","React","memo","targetX","targetY","squareSize","moveDuration","children","activeSquare","isDragging","square","currentX","useSharedValue","currentY","useEffect","value","withTiming","duration","animatedStyle","useAnimatedStyle","isBeingDragged","transform","translateX","translateY","opacity","jsx","View","style","position","width","height","prev","next"],"sourceRoot":"..\\..\\src","sources":["board-piece.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BoardPiecesLayer = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _boardPiece = require("./board-piece");
|
|
9
|
+
var _useBoardPieces = require("./use-board-pieces");
|
|
10
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
/**
|
|
13
|
+
* Renders all pieces on the board.
|
|
14
|
+
*
|
|
15
|
+
* Each piece gets a stable key (from useBoardPieces) so React doesn't
|
|
16
|
+
* unmount/remount pieces that moved — it updates their position props
|
|
17
|
+
* and the BoardPieceView animates the transition.
|
|
18
|
+
*/
|
|
19
|
+
const BoardPiecesLayer = exports.BoardPiecesLayer = /*#__PURE__*/_react.default.memo(function BoardPiecesLayer({
|
|
20
|
+
pieces,
|
|
21
|
+
squareSize,
|
|
22
|
+
orientation,
|
|
23
|
+
moveDuration,
|
|
24
|
+
renderPiece,
|
|
25
|
+
activeSquare,
|
|
26
|
+
isDragging
|
|
27
|
+
}) {
|
|
28
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
29
|
+
children: pieces.map(piece => {
|
|
30
|
+
const {
|
|
31
|
+
x,
|
|
32
|
+
y
|
|
33
|
+
} = (0, _useBoardPieces.squareToXY)(piece.square, squareSize, orientation);
|
|
34
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_boardPiece.BoardPieceView, {
|
|
35
|
+
targetX: x,
|
|
36
|
+
targetY: y,
|
|
37
|
+
squareSize: squareSize,
|
|
38
|
+
moveDuration: moveDuration,
|
|
39
|
+
activeSquare: activeSquare,
|
|
40
|
+
isDragging: isDragging,
|
|
41
|
+
square: piece.square,
|
|
42
|
+
children: renderPiece(piece.code, squareSize)
|
|
43
|
+
}, piece.id);
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=board-pieces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireDefault","require","_boardPiece","_useBoardPieces","_jsxRuntime","e","__esModule","default","BoardPiecesLayer","exports","React","memo","pieces","squareSize","orientation","moveDuration","renderPiece","activeSquare","isDragging","jsx","Fragment","children","map","piece","x","y","squareToXY","square","BoardPieceView","targetX","targetY","code","id"],"sourceRoot":"..\\..\\src","sources":["board-pieces.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAIA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,eAAA,GAAAF,OAAA;AAAgD,IAAAG,WAAA,GAAAH,OAAA;AAAA,SAAAD,uBAAAK,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAYhD;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMG,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,gBAAGE,cAAK,CAACC,IAAI,CAAC,SAASH,gBAAgBA,CAAC;EACnEI,MAAM;EACNC,UAAU;EACVC,WAAW;EACXC,YAAY;EACZC,WAAW;EACXC,YAAY;EACZC;AACgB,CAAC,EAAE;EACnB,oBACE,IAAAd,WAAA,CAAAe,GAAA,EAAAf,WAAA,CAAAgB,QAAA;IAAAC,QAAA,EACGT,MAAM,CAACU,GAAG,CAAEC,KAAK,IAAK;MACrB,MAAM;QAAEC,CAAC;QAAEC;MAAE,CAAC,GAAG,IAAAC,0BAAU,EAACH,KAAK,CAACI,MAAM,EAAEd,UAAU,EAAEC,WAAW,CAAC;MAElE,oBACE,IAAAV,WAAA,CAAAe,GAAA,EAACjB,WAAA,CAAA0B,cAAc;QAEbC,OAAO,EAAEL,CAAE;QACXM,OAAO,EAAEL,CAAE;QACXZ,UAAU,EAAEA,UAAW;QACvBE,YAAY,EAAEA,YAAa;QAC3BE,YAAY,EAAEA,YAAa;QAC3BC,UAAU,EAAEA,UAAW;QACvBS,MAAM,EAAEJ,KAAK,CAACI,MAAO;QAAAN,QAAA,EAEpBL,WAAW,CAACO,KAAK,CAACQ,IAAI,EAAElB,UAAU;MAAC,GAT/BU,KAAK,CAACS,EAUG,CAAC;IAErB,CAAC;EAAC,CACF,CAAC;AAEP,CAAC,CAAC","ignoreList":[]}
|