react-native-chess-kit 0.5.0 → 0.5.2

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.
Files changed (62) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +168 -168
  3. package/lib/commonjs/board-annotations.js +8 -8
  4. package/lib/commonjs/board-arrows.js +2 -2
  5. package/lib/commonjs/board-arrows.js.map +1 -1
  6. package/lib/commonjs/board-background.js +5 -5
  7. package/lib/commonjs/board-coordinates.js +8 -8
  8. package/lib/commonjs/board-drag-ghost.js +10 -10
  9. package/lib/commonjs/board-highlights.js +15 -15
  10. package/lib/commonjs/board-legal-dots.js +5 -5
  11. package/lib/commonjs/board-piece.js +25 -25
  12. package/lib/commonjs/board-pieces.js +6 -6
  13. package/lib/commonjs/board.js +24 -24
  14. package/lib/commonjs/promotion-picker.js +8 -8
  15. package/lib/commonjs/static-board.js +7 -7
  16. package/lib/commonjs/use-board-gesture.js +52 -33
  17. package/lib/commonjs/use-board-gesture.js.map +1 -1
  18. package/lib/commonjs/use-board-pieces.js +15 -15
  19. package/lib/commonjs/use-board-state.js +8 -8
  20. package/lib/commonjs/use-premove.js +12 -12
  21. package/lib/module/board-annotations.js +8 -8
  22. package/lib/module/board-arrows.js +2 -2
  23. package/lib/module/board-arrows.js.map +1 -1
  24. package/lib/module/board-background.js +5 -5
  25. package/lib/module/board-coordinates.js +8 -8
  26. package/lib/module/board-drag-ghost.js +10 -10
  27. package/lib/module/board-highlights.js +15 -15
  28. package/lib/module/board-legal-dots.js +5 -5
  29. package/lib/module/board-piece.js +25 -25
  30. package/lib/module/board-pieces.js +6 -6
  31. package/lib/module/board.js +24 -24
  32. package/lib/module/promotion-picker.js +8 -8
  33. package/lib/module/static-board.js +7 -7
  34. package/lib/module/use-board-gesture.js +52 -33
  35. package/lib/module/use-board-gesture.js.map +1 -1
  36. package/lib/module/use-board-pieces.js +15 -15
  37. package/lib/module/use-board-state.js +8 -8
  38. package/lib/module/use-premove.js +12 -12
  39. package/lib/typescript/use-board-gesture.d.ts.map +1 -1
  40. package/package.json +1 -1
  41. package/src/board-annotations.tsx +147 -147
  42. package/src/board-arrows.tsx +2 -2
  43. package/src/board-background.tsx +46 -46
  44. package/src/board-coordinates.tsx +192 -192
  45. package/src/board-drag-ghost.tsx +132 -132
  46. package/src/board-highlights.tsx +226 -226
  47. package/src/board-legal-dots.tsx +73 -73
  48. package/src/board-piece.tsx +160 -160
  49. package/src/board-pieces.tsx +63 -63
  50. package/src/board.tsx +685 -685
  51. package/src/constants.ts +103 -103
  52. package/src/index.ts +101 -101
  53. package/src/pieces/default-pieces.tsx +383 -383
  54. package/src/pieces/index.ts +1 -1
  55. package/src/promotion-picker.tsx +147 -147
  56. package/src/static-board.tsx +187 -187
  57. package/src/themes.ts +129 -129
  58. package/src/types.ts +373 -373
  59. package/src/use-board-gesture.ts +429 -412
  60. package/src/use-board-pieces.ts +158 -158
  61. package/src/use-board-state.ts +111 -111
  62. package/src/use-premove.ts +59 -59
@@ -1,383 +1,383 @@
1
- import React from 'react';
2
- import Svg, { Path, Circle, G } from 'react-native-svg';
3
- import type { PieceSetMap } from '../types';
4
-
5
- // ---------------------------------------------------------------------------
6
- // Shared stroke / fill constants
7
- // ---------------------------------------------------------------------------
8
-
9
- const WHITE_FILL = '#ffffff';
10
- const WHITE_STROKE = '#333333';
11
- const BLACK_FILL = '#333333';
12
- const BLACK_STROKE = '#1a1a1a';
13
- const STROKE_WIDTH = 1.5;
14
-
15
- // ---------------------------------------------------------------------------
16
- // King
17
- // ---------------------------------------------------------------------------
18
-
19
- const WhiteKing = React.memo(({ size }: { size: number }) => (
20
- <Svg width={size} height={size} viewBox="0 0 45 45">
21
- <G
22
- fill={WHITE_FILL}
23
- stroke={WHITE_STROKE}
24
- strokeWidth={STROKE_WIDTH}
25
- strokeLinecap="round"
26
- strokeLinejoin="round"
27
- >
28
- {/* Cross */}
29
- <Path d="M 22.5,11.63 L 22.5,6" fill="none" />
30
- <Path d="M 20,8 L 25,8" fill="none" />
31
- {/* Head */}
32
- <Path d="M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25" />
33
- {/* Body and base */}
34
- <Path d="M 12.5,37 C 18,33.5 27,33.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 20,16 10.5,13 6.5,19.5 C 3.5,25.5 12.5,30 12.5,30 L 12.5,37" />
35
- {/* Base line */}
36
- <Path d="M 12,37.5 C 18,40.5 27,40.5 33,37.5" fill="none" />
37
- {/* Crown detail lines */}
38
- <Path d="M 20,8 L 25,8" fill="none" />
39
- <Path
40
- d="M 32,29.5 C 32,29.5 40.5,25.5 38.03,19.85 C 34.15,14 25,18 22.5,24.5 L 22.5,26.6 L 22.5,24.5 C 20,18 10.85,14 6.97,19.85 C 4.5,25.5 13,29.5 13,29.5"
41
- fill="none"
42
- stroke={WHITE_STROKE}
43
- strokeWidth={1}
44
- />
45
- </G>
46
- </Svg>
47
- ));
48
-
49
- const BlackKing = React.memo(({ size }: { size: number }) => (
50
- <Svg width={size} height={size} viewBox="0 0 45 45">
51
- <G
52
- fill={BLACK_FILL}
53
- stroke={BLACK_STROKE}
54
- strokeWidth={STROKE_WIDTH}
55
- strokeLinecap="round"
56
- strokeLinejoin="round"
57
- >
58
- {/* Cross */}
59
- <Path d="M 22.5,11.63 L 22.5,6" stroke={BLACK_STROKE} fill="none" />
60
- <Path d="M 20,8 L 25,8" stroke={BLACK_STROKE} fill="none" />
61
- {/* Head */}
62
- <Path d="M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25" />
63
- {/* Body and base */}
64
- <Path d="M 12.5,37 C 18,33.5 27,33.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 20,16 10.5,13 6.5,19.5 C 3.5,25.5 12.5,30 12.5,30 L 12.5,37" />
65
- {/* Base line */}
66
- <Path d="M 12,37.5 C 18,40.5 27,40.5 33,37.5" fill="none" />
67
- {/* Crown detail lines (white inner lines for contrast) */}
68
- <Path
69
- d="M 32,29.5 C 32,29.5 40.5,25.5 38.03,19.85 C 34.15,14 25,18 22.5,24.5 L 22.5,26.6 L 22.5,24.5 C 20,18 10.85,14 6.97,19.85 C 4.5,25.5 13,29.5 13,29.5"
70
- fill="none"
71
- stroke="#ffffff"
72
- strokeWidth={1}
73
- />
74
- </G>
75
- </Svg>
76
- ));
77
-
78
- // ---------------------------------------------------------------------------
79
- // Queen
80
- // ---------------------------------------------------------------------------
81
-
82
- const WhiteQueen = React.memo(({ size }: { size: number }) => (
83
- <Svg width={size} height={size} viewBox="0 0 45 45">
84
- <G
85
- fill={WHITE_FILL}
86
- stroke={WHITE_STROKE}
87
- strokeWidth={STROKE_WIDTH}
88
- strokeLinecap="round"
89
- strokeLinejoin="round"
90
- >
91
- {/* Crown tip circles */}
92
- <Circle cx={6} cy={12} r={2.75} />
93
- <Circle cx={14} cy={9} r={2.75} />
94
- <Circle cx={22.5} cy={8} r={2.75} />
95
- <Circle cx={31} cy={9} r={2.75} />
96
- <Circle cx={39} cy={12} r={2.75} />
97
- {/* Crown body */}
98
- <Path d="M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.5,10.5 L 26,27.5 L 22.5,10 L 19,27.5 L 14.5,10.5 L 14,25 L 6.5,13.5 L 9,26 Z" />
99
- {/* Lower body */}
100
- <Path d="M 9,26 C 9,28 10.5,29.5 11.5,30 C 17,31.5 28,31.5 33.5,30 C 34.5,29.5 36,28 36,26" />
101
- {/* Base curves */}
102
- <Path d="M 11.5,30 C 15,33.5 30,33.5 33.5,30" fill="none" />
103
- <Path d="M 12,33.5 C 18,37.5 27,37.5 33,33.5" fill="none" />
104
- </G>
105
- </Svg>
106
- ));
107
-
108
- const BlackQueen = React.memo(({ size }: { size: number }) => (
109
- <Svg width={size} height={size} viewBox="0 0 45 45">
110
- <G
111
- fill={BLACK_FILL}
112
- stroke={BLACK_STROKE}
113
- strokeWidth={STROKE_WIDTH}
114
- strokeLinecap="round"
115
- strokeLinejoin="round"
116
- >
117
- {/* Crown tip circles */}
118
- <Circle cx={6} cy={12} r={2.75} />
119
- <Circle cx={14} cy={9} r={2.75} />
120
- <Circle cx={22.5} cy={8} r={2.75} />
121
- <Circle cx={31} cy={9} r={2.75} />
122
- <Circle cx={39} cy={12} r={2.75} />
123
- {/* Crown body */}
124
- <Path d="M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.5,10.5 L 26,27.5 L 22.5,10 L 19,27.5 L 14.5,10.5 L 14,25 L 6.5,13.5 L 9,26 Z" />
125
- {/* Lower body */}
126
- <Path d="M 9,26 C 9,28 10.5,29.5 11.5,30 C 17,31.5 28,31.5 33.5,30 C 34.5,29.5 36,28 36,26" />
127
- {/* Base curves */}
128
- <Path d="M 11.5,30 C 15,33.5 30,33.5 33.5,30" fill="none" />
129
- <Path d="M 12,33.5 C 18,37.5 27,37.5 33,33.5" fill="none" />
130
- {/* Inner detail lines for contrast */}
131
- <Path
132
- d="M 11,29.5 C 15,32 30,32 34,29.5"
133
- fill="none"
134
- stroke="#ffffff"
135
- strokeWidth={1}
136
- />
137
- </G>
138
- </Svg>
139
- ));
140
-
141
- // ---------------------------------------------------------------------------
142
- // Rook
143
- // ---------------------------------------------------------------------------
144
-
145
- const WhiteRook = React.memo(({ size }: { size: number }) => (
146
- <Svg width={size} height={size} viewBox="0 0 45 45">
147
- <G
148
- fill={WHITE_FILL}
149
- stroke={WHITE_STROKE}
150
- strokeWidth={STROKE_WIDTH}
151
- strokeLinecap="round"
152
- strokeLinejoin="round"
153
- >
154
- {/* Crenellations (merlons) */}
155
- <Path d="M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 Z" />
156
- <Path d="M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 Z" />
157
- <Path d="M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14 L 11,14 Z" />
158
- {/* Body */}
159
- <Path d="M 34,14 L 31,17 L 14,17 L 11,14" />
160
- <Path d="M 31,17 L 31,29.5 L 14,29.5 L 14,17" fill={WHITE_FILL} />
161
- <Path d="M 31,29.5 L 33,32 L 12,32 L 14,29.5" />
162
- {/* Inner lines */}
163
- <Path d="M 14,17 L 31,17" fill="none" />
164
- <Path d="M 14,29.5 L 31,29.5" fill="none" />
165
- <Path d="M 14,17 L 14,29.5" fill="none" />
166
- <Path d="M 31,17 L 31,29.5" fill="none" />
167
- </G>
168
- </Svg>
169
- ));
170
-
171
- const BlackRook = React.memo(({ size }: { size: number }) => (
172
- <Svg width={size} height={size} viewBox="0 0 45 45">
173
- <G
174
- fill={BLACK_FILL}
175
- stroke={BLACK_STROKE}
176
- strokeWidth={STROKE_WIDTH}
177
- strokeLinecap="round"
178
- strokeLinejoin="round"
179
- >
180
- {/* Crenellations (merlons) */}
181
- <Path d="M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 Z" />
182
- <Path d="M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 Z" />
183
- <Path d="M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14 L 11,14 Z" />
184
- {/* Body */}
185
- <Path d="M 34,14 L 31,17 L 14,17 L 11,14" />
186
- <Path d="M 31,17 L 31,29.5 L 14,29.5 L 14,17" fill={BLACK_FILL} />
187
- <Path d="M 31,29.5 L 33,32 L 12,32 L 14,29.5" />
188
- {/* Inner lines for contrast */}
189
- <Path d="M 14,17 L 31,17" fill="none" stroke="#ffffff" strokeWidth={1} />
190
- <Path d="M 14,29.5 L 31,29.5" fill="none" stroke="#ffffff" strokeWidth={1} />
191
- <Path d="M 14,17 L 14,29.5" fill="none" stroke="#ffffff" strokeWidth={1} />
192
- <Path d="M 31,17 L 31,29.5" fill="none" stroke="#ffffff" strokeWidth={1} />
193
- </G>
194
- </Svg>
195
- ));
196
-
197
- // ---------------------------------------------------------------------------
198
- // Bishop
199
- // ---------------------------------------------------------------------------
200
-
201
- const WhiteBishop = React.memo(({ size }: { size: number }) => (
202
- <Svg width={size} height={size} viewBox="0 0 45 45">
203
- <G
204
- fill={WHITE_FILL}
205
- stroke={WHITE_STROKE}
206
- strokeWidth={STROKE_WIDTH}
207
- strokeLinecap="round"
208
- strokeLinejoin="round"
209
- >
210
- {/* Top ball */}
211
- <Circle cx={22.5} cy={8} r={2.5} />
212
- {/* Mitre (head) */}
213
- <Path d="M 17.5,26 L 15,13 L 22.5,7 L 30,13 L 27.5,26" />
214
- {/* Mitre slit */}
215
- <Path d="M 22.5,15.5 L 22.5,20.5" fill="none" strokeWidth={1.5} />
216
- <Path d="M 20,18 L 25,18" fill="none" strokeWidth={1.5} />
217
- {/* Collar */}
218
- <Path d="M 17.5,26 C 21,28 24,28 27.5,26 C 28.5,27.5 29,29 29,31 C 29,33 27.5,34.5 22.5,34.5 C 17.5,34.5 16,33 16,31 C 16,29 16.5,27.5 17.5,26" />
219
- {/* Base */}
220
- <Path d="M 14.5,34.5 C 18,37.5 27,37.5 30.5,34.5 L 31,39 L 14,39 L 14.5,34.5 Z" />
221
- </G>
222
- </Svg>
223
- ));
224
-
225
- const BlackBishop = React.memo(({ size }: { size: number }) => (
226
- <Svg width={size} height={size} viewBox="0 0 45 45">
227
- <G
228
- fill={BLACK_FILL}
229
- stroke={BLACK_STROKE}
230
- strokeWidth={STROKE_WIDTH}
231
- strokeLinecap="round"
232
- strokeLinejoin="round"
233
- >
234
- {/* Top ball */}
235
- <Circle cx={22.5} cy={8} r={2.5} />
236
- {/* Mitre (head) */}
237
- <Path d="M 17.5,26 L 15,13 L 22.5,7 L 30,13 L 27.5,26" />
238
- {/* Mitre slit */}
239
- <Path d="M 22.5,15.5 L 22.5,20.5" fill="none" stroke="#ffffff" strokeWidth={1.5} />
240
- <Path d="M 20,18 L 25,18" fill="none" stroke="#ffffff" strokeWidth={1.5} />
241
- {/* Collar */}
242
- <Path d="M 17.5,26 C 21,28 24,28 27.5,26 C 28.5,27.5 29,29 29,31 C 29,33 27.5,34.5 22.5,34.5 C 17.5,34.5 16,33 16,31 C 16,29 16.5,27.5 17.5,26" />
243
- {/* Base */}
244
- <Path d="M 14.5,34.5 C 18,37.5 27,37.5 30.5,34.5 L 31,39 L 14,39 L 14.5,34.5 Z" />
245
- {/* Inner detail line for contrast */}
246
- <Path
247
- d="M 17.5,26 C 21,28 24,28 27.5,26"
248
- fill="none"
249
- stroke="#ffffff"
250
- strokeWidth={1}
251
- />
252
- </G>
253
- </Svg>
254
- ));
255
-
256
- // ---------------------------------------------------------------------------
257
- // Knight
258
- // ---------------------------------------------------------------------------
259
-
260
- const WhiteKnight = React.memo(({ size }: { size: number }) => (
261
- <Svg width={size} height={size} viewBox="0 0 45 45">
262
- <G
263
- fill={WHITE_FILL}
264
- stroke={WHITE_STROKE}
265
- strokeWidth={STROKE_WIDTH}
266
- strokeLinecap="round"
267
- strokeLinejoin="round"
268
- >
269
- {/* Horse head */}
270
- <Path d="M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18" />
271
- <Path d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10" />
272
- {/* Eye */}
273
- <Circle cx={12} cy={25.5} r={0.5} fill={WHITE_STROKE} stroke="none" />
274
- {/* Nostril */}
275
- <Path
276
- d="M 17,34.5 C 18.5,32 19.28,30 19,28.25"
277
- fill="none"
278
- strokeWidth={1}
279
- />
280
- </G>
281
- </Svg>
282
- ));
283
-
284
- const BlackKnight = React.memo(({ size }: { size: number }) => (
285
- <Svg width={size} height={size} viewBox="0 0 45 45">
286
- <G
287
- fill={BLACK_FILL}
288
- stroke={BLACK_STROKE}
289
- strokeWidth={STROKE_WIDTH}
290
- strokeLinecap="round"
291
- strokeLinejoin="round"
292
- >
293
- {/* Horse head */}
294
- <Path d="M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18" />
295
- <Path d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10" />
296
- {/* Eye (white for contrast) */}
297
- <Circle cx={12} cy={25.5} r={0.5} fill="#ffffff" stroke="none" />
298
- {/* Nostril / mane detail */}
299
- <Path
300
- d="M 17,34.5 C 18.5,32 19.28,30 19,28.25"
301
- fill="none"
302
- stroke="#ffffff"
303
- strokeWidth={1}
304
- />
305
- {/* Mane line for contrast */}
306
- <Path
307
- d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31"
308
- fill="none"
309
- stroke="#ffffff"
310
- strokeWidth={1}
311
- />
312
- </G>
313
- </Svg>
314
- ));
315
-
316
- // ---------------------------------------------------------------------------
317
- // Pawn
318
- // ---------------------------------------------------------------------------
319
-
320
- const WhitePawn = React.memo(({ size }: { size: number }) => (
321
- <Svg width={size} height={size} viewBox="0 0 45 45">
322
- <G
323
- fill={WHITE_FILL}
324
- stroke={WHITE_STROKE}
325
- strokeWidth={STROKE_WIDTH}
326
- strokeLinecap="round"
327
- strokeLinejoin="round"
328
- >
329
- <Path d="M 22.5,9 C 19.79,9 17.609,11.19 17.609,13.9 C 17.609,15.42 18.34,16.77 19.47,17.62 C 16.98,19.04 15.35,21.72 15.35,24.79 C 15.35,25.87 15.59,26.88 15.99,27.81 C 13.08,29.21 11,32.16 11,35.6 L 11,37.5 C 11,38.33 11.67,39 12.5,39 L 32.5,39 C 33.33,39 34,38.33 34,37.5 L 34,35.6 C 34,32.16 31.92,29.21 29.01,27.81 C 29.41,26.88 29.65,25.87 29.65,24.79 C 29.65,21.72 28.02,19.04 25.53,17.62 C 26.66,16.77 27.39,15.42 27.39,13.9 C 27.39,11.19 25.21,9 22.5,9 Z" />
330
- </G>
331
- </Svg>
332
- ));
333
-
334
- const BlackPawn = React.memo(({ size }: { size: number }) => (
335
- <Svg width={size} height={size} viewBox="0 0 45 45">
336
- <G
337
- fill={BLACK_FILL}
338
- stroke={BLACK_STROKE}
339
- strokeWidth={STROKE_WIDTH}
340
- strokeLinecap="round"
341
- strokeLinejoin="round"
342
- >
343
- <Path d="M 22.5,9 C 19.79,9 17.609,11.19 17.609,13.9 C 17.609,15.42 18.34,16.77 19.47,17.62 C 16.98,19.04 15.35,21.72 15.35,24.79 C 15.35,25.87 15.59,26.88 15.99,27.81 C 13.08,29.21 11,32.16 11,35.6 L 11,37.5 C 11,38.33 11.67,39 12.5,39 L 32.5,39 C 33.33,39 34,38.33 34,37.5 L 34,35.6 C 34,32.16 31.92,29.21 29.01,27.81 C 29.41,26.88 29.65,25.87 29.65,24.79 C 29.65,21.72 28.02,19.04 25.53,17.62 C 26.66,16.77 27.39,15.42 27.39,13.9 C 27.39,11.19 25.21,9 22.5,9 Z" />
344
- </G>
345
- </Svg>
346
- ));
347
-
348
- // ---------------------------------------------------------------------------
349
- // Piece render functions
350
- // ---------------------------------------------------------------------------
351
-
352
- const wp = (size: number) => <WhitePawn size={size} />;
353
- const wn = (size: number) => <WhiteKnight size={size} />;
354
- const wb = (size: number) => <WhiteBishop size={size} />;
355
- const wr = (size: number) => <WhiteRook size={size} />;
356
- const wq = (size: number) => <WhiteQueen size={size} />;
357
- const wk = (size: number) => <WhiteKing size={size} />;
358
-
359
- const bp = (size: number) => <BlackPawn size={size} />;
360
- const bn = (size: number) => <BlackKnight size={size} />;
361
- const bb = (size: number) => <BlackBishop size={size} />;
362
- const br = (size: number) => <BlackRook size={size} />;
363
- const bq = (size: number) => <BlackQueen size={size} />;
364
- const bk = (size: number) => <BlackKing size={size} />;
365
-
366
- // ---------------------------------------------------------------------------
367
- // Default piece set
368
- // ---------------------------------------------------------------------------
369
-
370
- export const DefaultPieceSet: PieceSetMap = {
371
- wp,
372
- wn,
373
- wb,
374
- wr,
375
- wq,
376
- wk,
377
- bp,
378
- bn,
379
- bb,
380
- br,
381
- bq,
382
- bk,
383
- };
1
+ import React from 'react';
2
+ import Svg, { Path, Circle, G } from 'react-native-svg';
3
+ import type { PieceSetMap } from '../types';
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Shared stroke / fill constants
7
+ // ---------------------------------------------------------------------------
8
+
9
+ const WHITE_FILL = '#ffffff';
10
+ const WHITE_STROKE = '#333333';
11
+ const BLACK_FILL = '#333333';
12
+ const BLACK_STROKE = '#1a1a1a';
13
+ const STROKE_WIDTH = 1.5;
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // King
17
+ // ---------------------------------------------------------------------------
18
+
19
+ const WhiteKing = React.memo(({ size }: { size: number }) => (
20
+ <Svg width={size} height={size} viewBox="0 0 45 45">
21
+ <G
22
+ fill={WHITE_FILL}
23
+ stroke={WHITE_STROKE}
24
+ strokeWidth={STROKE_WIDTH}
25
+ strokeLinecap="round"
26
+ strokeLinejoin="round"
27
+ >
28
+ {/* Cross */}
29
+ <Path d="M 22.5,11.63 L 22.5,6" fill="none" />
30
+ <Path d="M 20,8 L 25,8" fill="none" />
31
+ {/* Head */}
32
+ <Path d="M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25" />
33
+ {/* Body and base */}
34
+ <Path d="M 12.5,37 C 18,33.5 27,33.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 20,16 10.5,13 6.5,19.5 C 3.5,25.5 12.5,30 12.5,30 L 12.5,37" />
35
+ {/* Base line */}
36
+ <Path d="M 12,37.5 C 18,40.5 27,40.5 33,37.5" fill="none" />
37
+ {/* Crown detail lines */}
38
+ <Path d="M 20,8 L 25,8" fill="none" />
39
+ <Path
40
+ d="M 32,29.5 C 32,29.5 40.5,25.5 38.03,19.85 C 34.15,14 25,18 22.5,24.5 L 22.5,26.6 L 22.5,24.5 C 20,18 10.85,14 6.97,19.85 C 4.5,25.5 13,29.5 13,29.5"
41
+ fill="none"
42
+ stroke={WHITE_STROKE}
43
+ strokeWidth={1}
44
+ />
45
+ </G>
46
+ </Svg>
47
+ ));
48
+
49
+ const BlackKing = React.memo(({ size }: { size: number }) => (
50
+ <Svg width={size} height={size} viewBox="0 0 45 45">
51
+ <G
52
+ fill={BLACK_FILL}
53
+ stroke={BLACK_STROKE}
54
+ strokeWidth={STROKE_WIDTH}
55
+ strokeLinecap="round"
56
+ strokeLinejoin="round"
57
+ >
58
+ {/* Cross */}
59
+ <Path d="M 22.5,11.63 L 22.5,6" stroke={BLACK_STROKE} fill="none" />
60
+ <Path d="M 20,8 L 25,8" stroke={BLACK_STROKE} fill="none" />
61
+ {/* Head */}
62
+ <Path d="M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25" />
63
+ {/* Body and base */}
64
+ <Path d="M 12.5,37 C 18,33.5 27,33.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 20,16 10.5,13 6.5,19.5 C 3.5,25.5 12.5,30 12.5,30 L 12.5,37" />
65
+ {/* Base line */}
66
+ <Path d="M 12,37.5 C 18,40.5 27,40.5 33,37.5" fill="none" />
67
+ {/* Crown detail lines (white inner lines for contrast) */}
68
+ <Path
69
+ d="M 32,29.5 C 32,29.5 40.5,25.5 38.03,19.85 C 34.15,14 25,18 22.5,24.5 L 22.5,26.6 L 22.5,24.5 C 20,18 10.85,14 6.97,19.85 C 4.5,25.5 13,29.5 13,29.5"
70
+ fill="none"
71
+ stroke="#ffffff"
72
+ strokeWidth={1}
73
+ />
74
+ </G>
75
+ </Svg>
76
+ ));
77
+
78
+ // ---------------------------------------------------------------------------
79
+ // Queen
80
+ // ---------------------------------------------------------------------------
81
+
82
+ const WhiteQueen = React.memo(({ size }: { size: number }) => (
83
+ <Svg width={size} height={size} viewBox="0 0 45 45">
84
+ <G
85
+ fill={WHITE_FILL}
86
+ stroke={WHITE_STROKE}
87
+ strokeWidth={STROKE_WIDTH}
88
+ strokeLinecap="round"
89
+ strokeLinejoin="round"
90
+ >
91
+ {/* Crown tip circles */}
92
+ <Circle cx={6} cy={12} r={2.75} />
93
+ <Circle cx={14} cy={9} r={2.75} />
94
+ <Circle cx={22.5} cy={8} r={2.75} />
95
+ <Circle cx={31} cy={9} r={2.75} />
96
+ <Circle cx={39} cy={12} r={2.75} />
97
+ {/* Crown body */}
98
+ <Path d="M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.5,10.5 L 26,27.5 L 22.5,10 L 19,27.5 L 14.5,10.5 L 14,25 L 6.5,13.5 L 9,26 Z" />
99
+ {/* Lower body */}
100
+ <Path d="M 9,26 C 9,28 10.5,29.5 11.5,30 C 17,31.5 28,31.5 33.5,30 C 34.5,29.5 36,28 36,26" />
101
+ {/* Base curves */}
102
+ <Path d="M 11.5,30 C 15,33.5 30,33.5 33.5,30" fill="none" />
103
+ <Path d="M 12,33.5 C 18,37.5 27,37.5 33,33.5" fill="none" />
104
+ </G>
105
+ </Svg>
106
+ ));
107
+
108
+ const BlackQueen = React.memo(({ size }: { size: number }) => (
109
+ <Svg width={size} height={size} viewBox="0 0 45 45">
110
+ <G
111
+ fill={BLACK_FILL}
112
+ stroke={BLACK_STROKE}
113
+ strokeWidth={STROKE_WIDTH}
114
+ strokeLinecap="round"
115
+ strokeLinejoin="round"
116
+ >
117
+ {/* Crown tip circles */}
118
+ <Circle cx={6} cy={12} r={2.75} />
119
+ <Circle cx={14} cy={9} r={2.75} />
120
+ <Circle cx={22.5} cy={8} r={2.75} />
121
+ <Circle cx={31} cy={9} r={2.75} />
122
+ <Circle cx={39} cy={12} r={2.75} />
123
+ {/* Crown body */}
124
+ <Path d="M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.5,10.5 L 26,27.5 L 22.5,10 L 19,27.5 L 14.5,10.5 L 14,25 L 6.5,13.5 L 9,26 Z" />
125
+ {/* Lower body */}
126
+ <Path d="M 9,26 C 9,28 10.5,29.5 11.5,30 C 17,31.5 28,31.5 33.5,30 C 34.5,29.5 36,28 36,26" />
127
+ {/* Base curves */}
128
+ <Path d="M 11.5,30 C 15,33.5 30,33.5 33.5,30" fill="none" />
129
+ <Path d="M 12,33.5 C 18,37.5 27,37.5 33,33.5" fill="none" />
130
+ {/* Inner detail lines for contrast */}
131
+ <Path
132
+ d="M 11,29.5 C 15,32 30,32 34,29.5"
133
+ fill="none"
134
+ stroke="#ffffff"
135
+ strokeWidth={1}
136
+ />
137
+ </G>
138
+ </Svg>
139
+ ));
140
+
141
+ // ---------------------------------------------------------------------------
142
+ // Rook
143
+ // ---------------------------------------------------------------------------
144
+
145
+ const WhiteRook = React.memo(({ size }: { size: number }) => (
146
+ <Svg width={size} height={size} viewBox="0 0 45 45">
147
+ <G
148
+ fill={WHITE_FILL}
149
+ stroke={WHITE_STROKE}
150
+ strokeWidth={STROKE_WIDTH}
151
+ strokeLinecap="round"
152
+ strokeLinejoin="round"
153
+ >
154
+ {/* Crenellations (merlons) */}
155
+ <Path d="M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 Z" />
156
+ <Path d="M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 Z" />
157
+ <Path d="M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14 L 11,14 Z" />
158
+ {/* Body */}
159
+ <Path d="M 34,14 L 31,17 L 14,17 L 11,14" />
160
+ <Path d="M 31,17 L 31,29.5 L 14,29.5 L 14,17" fill={WHITE_FILL} />
161
+ <Path d="M 31,29.5 L 33,32 L 12,32 L 14,29.5" />
162
+ {/* Inner lines */}
163
+ <Path d="M 14,17 L 31,17" fill="none" />
164
+ <Path d="M 14,29.5 L 31,29.5" fill="none" />
165
+ <Path d="M 14,17 L 14,29.5" fill="none" />
166
+ <Path d="M 31,17 L 31,29.5" fill="none" />
167
+ </G>
168
+ </Svg>
169
+ ));
170
+
171
+ const BlackRook = React.memo(({ size }: { size: number }) => (
172
+ <Svg width={size} height={size} viewBox="0 0 45 45">
173
+ <G
174
+ fill={BLACK_FILL}
175
+ stroke={BLACK_STROKE}
176
+ strokeWidth={STROKE_WIDTH}
177
+ strokeLinecap="round"
178
+ strokeLinejoin="round"
179
+ >
180
+ {/* Crenellations (merlons) */}
181
+ <Path d="M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 Z" />
182
+ <Path d="M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 Z" />
183
+ <Path d="M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14 L 11,14 Z" />
184
+ {/* Body */}
185
+ <Path d="M 34,14 L 31,17 L 14,17 L 11,14" />
186
+ <Path d="M 31,17 L 31,29.5 L 14,29.5 L 14,17" fill={BLACK_FILL} />
187
+ <Path d="M 31,29.5 L 33,32 L 12,32 L 14,29.5" />
188
+ {/* Inner lines for contrast */}
189
+ <Path d="M 14,17 L 31,17" fill="none" stroke="#ffffff" strokeWidth={1} />
190
+ <Path d="M 14,29.5 L 31,29.5" fill="none" stroke="#ffffff" strokeWidth={1} />
191
+ <Path d="M 14,17 L 14,29.5" fill="none" stroke="#ffffff" strokeWidth={1} />
192
+ <Path d="M 31,17 L 31,29.5" fill="none" stroke="#ffffff" strokeWidth={1} />
193
+ </G>
194
+ </Svg>
195
+ ));
196
+
197
+ // ---------------------------------------------------------------------------
198
+ // Bishop
199
+ // ---------------------------------------------------------------------------
200
+
201
+ const WhiteBishop = React.memo(({ size }: { size: number }) => (
202
+ <Svg width={size} height={size} viewBox="0 0 45 45">
203
+ <G
204
+ fill={WHITE_FILL}
205
+ stroke={WHITE_STROKE}
206
+ strokeWidth={STROKE_WIDTH}
207
+ strokeLinecap="round"
208
+ strokeLinejoin="round"
209
+ >
210
+ {/* Top ball */}
211
+ <Circle cx={22.5} cy={8} r={2.5} />
212
+ {/* Mitre (head) */}
213
+ <Path d="M 17.5,26 L 15,13 L 22.5,7 L 30,13 L 27.5,26" />
214
+ {/* Mitre slit */}
215
+ <Path d="M 22.5,15.5 L 22.5,20.5" fill="none" strokeWidth={1.5} />
216
+ <Path d="M 20,18 L 25,18" fill="none" strokeWidth={1.5} />
217
+ {/* Collar */}
218
+ <Path d="M 17.5,26 C 21,28 24,28 27.5,26 C 28.5,27.5 29,29 29,31 C 29,33 27.5,34.5 22.5,34.5 C 17.5,34.5 16,33 16,31 C 16,29 16.5,27.5 17.5,26" />
219
+ {/* Base */}
220
+ <Path d="M 14.5,34.5 C 18,37.5 27,37.5 30.5,34.5 L 31,39 L 14,39 L 14.5,34.5 Z" />
221
+ </G>
222
+ </Svg>
223
+ ));
224
+
225
+ const BlackBishop = React.memo(({ size }: { size: number }) => (
226
+ <Svg width={size} height={size} viewBox="0 0 45 45">
227
+ <G
228
+ fill={BLACK_FILL}
229
+ stroke={BLACK_STROKE}
230
+ strokeWidth={STROKE_WIDTH}
231
+ strokeLinecap="round"
232
+ strokeLinejoin="round"
233
+ >
234
+ {/* Top ball */}
235
+ <Circle cx={22.5} cy={8} r={2.5} />
236
+ {/* Mitre (head) */}
237
+ <Path d="M 17.5,26 L 15,13 L 22.5,7 L 30,13 L 27.5,26" />
238
+ {/* Mitre slit */}
239
+ <Path d="M 22.5,15.5 L 22.5,20.5" fill="none" stroke="#ffffff" strokeWidth={1.5} />
240
+ <Path d="M 20,18 L 25,18" fill="none" stroke="#ffffff" strokeWidth={1.5} />
241
+ {/* Collar */}
242
+ <Path d="M 17.5,26 C 21,28 24,28 27.5,26 C 28.5,27.5 29,29 29,31 C 29,33 27.5,34.5 22.5,34.5 C 17.5,34.5 16,33 16,31 C 16,29 16.5,27.5 17.5,26" />
243
+ {/* Base */}
244
+ <Path d="M 14.5,34.5 C 18,37.5 27,37.5 30.5,34.5 L 31,39 L 14,39 L 14.5,34.5 Z" />
245
+ {/* Inner detail line for contrast */}
246
+ <Path
247
+ d="M 17.5,26 C 21,28 24,28 27.5,26"
248
+ fill="none"
249
+ stroke="#ffffff"
250
+ strokeWidth={1}
251
+ />
252
+ </G>
253
+ </Svg>
254
+ ));
255
+
256
+ // ---------------------------------------------------------------------------
257
+ // Knight
258
+ // ---------------------------------------------------------------------------
259
+
260
+ const WhiteKnight = React.memo(({ size }: { size: number }) => (
261
+ <Svg width={size} height={size} viewBox="0 0 45 45">
262
+ <G
263
+ fill={WHITE_FILL}
264
+ stroke={WHITE_STROKE}
265
+ strokeWidth={STROKE_WIDTH}
266
+ strokeLinecap="round"
267
+ strokeLinejoin="round"
268
+ >
269
+ {/* Horse head */}
270
+ <Path d="M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18" />
271
+ <Path d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10" />
272
+ {/* Eye */}
273
+ <Circle cx={12} cy={25.5} r={0.5} fill={WHITE_STROKE} stroke="none" />
274
+ {/* Nostril */}
275
+ <Path
276
+ d="M 17,34.5 C 18.5,32 19.28,30 19,28.25"
277
+ fill="none"
278
+ strokeWidth={1}
279
+ />
280
+ </G>
281
+ </Svg>
282
+ ));
283
+
284
+ const BlackKnight = React.memo(({ size }: { size: number }) => (
285
+ <Svg width={size} height={size} viewBox="0 0 45 45">
286
+ <G
287
+ fill={BLACK_FILL}
288
+ stroke={BLACK_STROKE}
289
+ strokeWidth={STROKE_WIDTH}
290
+ strokeLinecap="round"
291
+ strokeLinejoin="round"
292
+ >
293
+ {/* Horse head */}
294
+ <Path d="M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18" />
295
+ <Path d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10" />
296
+ {/* Eye (white for contrast) */}
297
+ <Circle cx={12} cy={25.5} r={0.5} fill="#ffffff" stroke="none" />
298
+ {/* Nostril / mane detail */}
299
+ <Path
300
+ d="M 17,34.5 C 18.5,32 19.28,30 19,28.25"
301
+ fill="none"
302
+ stroke="#ffffff"
303
+ strokeWidth={1}
304
+ />
305
+ {/* Mane line for contrast */}
306
+ <Path
307
+ d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31"
308
+ fill="none"
309
+ stroke="#ffffff"
310
+ strokeWidth={1}
311
+ />
312
+ </G>
313
+ </Svg>
314
+ ));
315
+
316
+ // ---------------------------------------------------------------------------
317
+ // Pawn
318
+ // ---------------------------------------------------------------------------
319
+
320
+ const WhitePawn = React.memo(({ size }: { size: number }) => (
321
+ <Svg width={size} height={size} viewBox="0 0 45 45">
322
+ <G
323
+ fill={WHITE_FILL}
324
+ stroke={WHITE_STROKE}
325
+ strokeWidth={STROKE_WIDTH}
326
+ strokeLinecap="round"
327
+ strokeLinejoin="round"
328
+ >
329
+ <Path d="M 22.5,9 C 19.79,9 17.609,11.19 17.609,13.9 C 17.609,15.42 18.34,16.77 19.47,17.62 C 16.98,19.04 15.35,21.72 15.35,24.79 C 15.35,25.87 15.59,26.88 15.99,27.81 C 13.08,29.21 11,32.16 11,35.6 L 11,37.5 C 11,38.33 11.67,39 12.5,39 L 32.5,39 C 33.33,39 34,38.33 34,37.5 L 34,35.6 C 34,32.16 31.92,29.21 29.01,27.81 C 29.41,26.88 29.65,25.87 29.65,24.79 C 29.65,21.72 28.02,19.04 25.53,17.62 C 26.66,16.77 27.39,15.42 27.39,13.9 C 27.39,11.19 25.21,9 22.5,9 Z" />
330
+ </G>
331
+ </Svg>
332
+ ));
333
+
334
+ const BlackPawn = React.memo(({ size }: { size: number }) => (
335
+ <Svg width={size} height={size} viewBox="0 0 45 45">
336
+ <G
337
+ fill={BLACK_FILL}
338
+ stroke={BLACK_STROKE}
339
+ strokeWidth={STROKE_WIDTH}
340
+ strokeLinecap="round"
341
+ strokeLinejoin="round"
342
+ >
343
+ <Path d="M 22.5,9 C 19.79,9 17.609,11.19 17.609,13.9 C 17.609,15.42 18.34,16.77 19.47,17.62 C 16.98,19.04 15.35,21.72 15.35,24.79 C 15.35,25.87 15.59,26.88 15.99,27.81 C 13.08,29.21 11,32.16 11,35.6 L 11,37.5 C 11,38.33 11.67,39 12.5,39 L 32.5,39 C 33.33,39 34,38.33 34,37.5 L 34,35.6 C 34,32.16 31.92,29.21 29.01,27.81 C 29.41,26.88 29.65,25.87 29.65,24.79 C 29.65,21.72 28.02,19.04 25.53,17.62 C 26.66,16.77 27.39,15.42 27.39,13.9 C 27.39,11.19 25.21,9 22.5,9 Z" />
344
+ </G>
345
+ </Svg>
346
+ ));
347
+
348
+ // ---------------------------------------------------------------------------
349
+ // Piece render functions
350
+ // ---------------------------------------------------------------------------
351
+
352
+ const wp = (size: number) => <WhitePawn size={size} />;
353
+ const wn = (size: number) => <WhiteKnight size={size} />;
354
+ const wb = (size: number) => <WhiteBishop size={size} />;
355
+ const wr = (size: number) => <WhiteRook size={size} />;
356
+ const wq = (size: number) => <WhiteQueen size={size} />;
357
+ const wk = (size: number) => <WhiteKing size={size} />;
358
+
359
+ const bp = (size: number) => <BlackPawn size={size} />;
360
+ const bn = (size: number) => <BlackKnight size={size} />;
361
+ const bb = (size: number) => <BlackBishop size={size} />;
362
+ const br = (size: number) => <BlackRook size={size} />;
363
+ const bq = (size: number) => <BlackQueen size={size} />;
364
+ const bk = (size: number) => <BlackKing size={size} />;
365
+
366
+ // ---------------------------------------------------------------------------
367
+ // Default piece set
368
+ // ---------------------------------------------------------------------------
369
+
370
+ export const DefaultPieceSet: PieceSetMap = {
371
+ wp,
372
+ wn,
373
+ wb,
374
+ wr,
375
+ wq,
376
+ wk,
377
+ bp,
378
+ bn,
379
+ bb,
380
+ br,
381
+ bq,
382
+ bk,
383
+ };