react-native-chess-kit 0.1.0 → 0.2.1

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 (109) hide show
  1. package/lib/commonjs/board-annotations.js +131 -0
  2. package/lib/commonjs/board-annotations.js.map +1 -0
  3. package/lib/commonjs/board-arrows.js +164 -0
  4. package/lib/commonjs/board-arrows.js.map +1 -0
  5. package/lib/commonjs/board-highlights.js +212 -0
  6. package/lib/commonjs/board-highlights.js.map +1 -0
  7. package/lib/commonjs/board-piece.js +71 -25
  8. package/lib/commonjs/board-piece.js.map +1 -1
  9. package/lib/commonjs/board-pieces.js +2 -0
  10. package/lib/commonjs/board-pieces.js.map +1 -1
  11. package/lib/commonjs/board.js +392 -42
  12. package/lib/commonjs/board.js.map +1 -1
  13. package/lib/commonjs/constants.js +104 -0
  14. package/lib/commonjs/constants.js.map +1 -0
  15. package/lib/commonjs/index.js +128 -0
  16. package/lib/commonjs/index.js.map +1 -1
  17. package/lib/commonjs/pieces/default-pieces.js +536 -0
  18. package/lib/commonjs/pieces/default-pieces.js.map +1 -0
  19. package/lib/commonjs/pieces/index.js +13 -0
  20. package/lib/commonjs/pieces/index.js.map +1 -0
  21. package/lib/commonjs/promotion-picker.js +129 -0
  22. package/lib/commonjs/promotion-picker.js.map +1 -0
  23. package/lib/commonjs/static-board.js +150 -0
  24. package/lib/commonjs/static-board.js.map +1 -0
  25. package/lib/commonjs/themes.js +175 -0
  26. package/lib/commonjs/themes.js.map +1 -0
  27. package/lib/commonjs/use-board-gesture.js +184 -11
  28. package/lib/commonjs/use-board-gesture.js.map +1 -1
  29. package/lib/commonjs/use-premove.js +44 -0
  30. package/lib/commonjs/use-premove.js.map +1 -0
  31. package/lib/module/board-annotations.js +126 -0
  32. package/lib/module/board-annotations.js.map +1 -0
  33. package/lib/module/board-arrows.js +161 -0
  34. package/lib/module/board-arrows.js.map +1 -0
  35. package/lib/module/board-highlights.js +206 -0
  36. package/lib/module/board-highlights.js.map +1 -0
  37. package/lib/module/board-piece.js +72 -26
  38. package/lib/module/board-piece.js.map +1 -1
  39. package/lib/module/board-pieces.js +2 -0
  40. package/lib/module/board-pieces.js.map +1 -1
  41. package/lib/module/board.js +395 -44
  42. package/lib/module/board.js.map +1 -1
  43. package/lib/module/constants.js +100 -0
  44. package/lib/module/constants.js.map +1 -0
  45. package/lib/module/index.js +29 -1
  46. package/lib/module/index.js.map +1 -1
  47. package/lib/module/pieces/default-pieces.js +530 -0
  48. package/lib/module/pieces/default-pieces.js.map +1 -0
  49. package/lib/module/pieces/index.js +4 -0
  50. package/lib/module/pieces/index.js.map +1 -0
  51. package/lib/module/promotion-picker.js +124 -0
  52. package/lib/module/promotion-picker.js.map +1 -0
  53. package/lib/module/static-board.js +146 -0
  54. package/lib/module/static-board.js.map +1 -0
  55. package/lib/module/themes.js +171 -0
  56. package/lib/module/themes.js.map +1 -0
  57. package/lib/module/use-board-gesture.js +185 -11
  58. package/lib/module/use-board-gesture.js.map +1 -1
  59. package/lib/module/use-premove.js +40 -0
  60. package/lib/module/use-premove.js.map +1 -0
  61. package/lib/typescript/board-annotations.d.ts +30 -0
  62. package/lib/typescript/board-annotations.d.ts.map +1 -0
  63. package/lib/typescript/board-arrows.d.ts +27 -0
  64. package/lib/typescript/board-arrows.d.ts.map +1 -0
  65. package/lib/typescript/board-highlights.d.ts +65 -0
  66. package/lib/typescript/board-highlights.d.ts.map +1 -0
  67. package/lib/typescript/board-piece.d.ts +19 -9
  68. package/lib/typescript/board-piece.d.ts.map +1 -1
  69. package/lib/typescript/board-pieces.d.ts +2 -1
  70. package/lib/typescript/board-pieces.d.ts.map +1 -1
  71. package/lib/typescript/board.d.ts +11 -2
  72. package/lib/typescript/board.d.ts.map +1 -1
  73. package/lib/typescript/constants.d.ts +54 -0
  74. package/lib/typescript/constants.d.ts.map +1 -0
  75. package/lib/typescript/index.d.ts +9 -1
  76. package/lib/typescript/index.d.ts.map +1 -1
  77. package/lib/typescript/pieces/default-pieces.d.ts +3 -0
  78. package/lib/typescript/pieces/default-pieces.d.ts.map +1 -0
  79. package/lib/typescript/pieces/index.d.ts +2 -0
  80. package/lib/typescript/pieces/index.d.ts.map +1 -0
  81. package/lib/typescript/promotion-picker.d.ts +30 -0
  82. package/lib/typescript/promotion-picker.d.ts.map +1 -0
  83. package/lib/typescript/static-board.d.ts +12 -0
  84. package/lib/typescript/static-board.d.ts.map +1 -0
  85. package/lib/typescript/themes.d.ts +15 -0
  86. package/lib/typescript/themes.d.ts.map +1 -0
  87. package/lib/typescript/types.d.ts +194 -24
  88. package/lib/typescript/types.d.ts.map +1 -1
  89. package/lib/typescript/use-board-gesture.d.ts +28 -2
  90. package/lib/typescript/use-board-gesture.d.ts.map +1 -1
  91. package/lib/typescript/use-premove.d.ts +31 -0
  92. package/lib/typescript/use-premove.d.ts.map +1 -0
  93. package/package.json +4 -2
  94. package/src/board-annotations.tsx +147 -0
  95. package/src/board-arrows.tsx +197 -0
  96. package/src/board-highlights.tsx +226 -0
  97. package/src/board-piece.tsx +77 -29
  98. package/src/board-pieces.tsx +4 -1
  99. package/src/board.tsx +462 -46
  100. package/src/constants.ts +100 -0
  101. package/src/index.ts +62 -1
  102. package/src/pieces/default-pieces.tsx +383 -0
  103. package/src/pieces/index.ts +1 -0
  104. package/src/promotion-picker.tsx +147 -0
  105. package/src/static-board.tsx +150 -0
  106. package/src/themes.ts +129 -0
  107. package/src/types.ts +251 -25
  108. package/src/use-board-gesture.ts +219 -8
  109. package/src/use-premove.ts +59 -0
@@ -0,0 +1,100 @@
1
+ import type { BoardColors } from './types';
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Default colors
5
+ // ---------------------------------------------------------------------------
6
+
7
+ /** Default board colors (chess.com green) */
8
+ export const DEFAULT_BOARD_COLORS: BoardColors = {
9
+ light: '#eeeed2',
10
+ dark: '#769656',
11
+ };
12
+
13
+ /** Default last-move highlight color */
14
+ export const DEFAULT_LAST_MOVE_COLOR = 'rgba(255, 255, 0, 0.4)';
15
+
16
+ /** Default check highlight color (red radial feel) */
17
+ export const DEFAULT_CHECK_COLOR = 'rgba(235, 97, 80, 0.8)';
18
+
19
+ /** Default selected piece square color */
20
+ export const DEFAULT_SELECTED_COLOR = 'rgba(20, 85, 200, 0.5)';
21
+
22
+ /** Default premove highlight color */
23
+ export const DEFAULT_PREMOVE_COLOR = 'rgba(20, 85, 200, 0.3)';
24
+
25
+ /** Default drag target highlight color */
26
+ export const DEFAULT_DRAG_TARGET_COLOR = 'rgba(0, 0, 0, 0.1)';
27
+
28
+ /** Default arrow color */
29
+ export const DEFAULT_ARROW_COLOR = 'rgba(243, 166, 50, 0.85)';
30
+
31
+ /** Default shape (circle) color */
32
+ export const DEFAULT_SHAPE_COLOR = 'rgba(21, 120, 27, 0.7)';
33
+
34
+ /** Default annotation background color */
35
+ export const DEFAULT_ANNOTATION_BG = 'rgba(235, 97, 80, 0.9)';
36
+
37
+ /** Default annotation text color */
38
+ export const DEFAULT_ANNOTATION_TEXT = '#ffffff';
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // Animation defaults
42
+ // ---------------------------------------------------------------------------
43
+
44
+ /** Default move animation duration in ms */
45
+ export const DEFAULT_MOVE_DURATION = 200;
46
+
47
+ /** Duration for capture fade-out animation in ms */
48
+ export const CAPTURE_FADE_DURATION = 150;
49
+
50
+ // ---------------------------------------------------------------------------
51
+ // Layout constants
52
+ // ---------------------------------------------------------------------------
53
+
54
+ /** Legal move dot size as fraction of square size */
55
+ export const DOT_SCALE = 0.28;
56
+
57
+ /** Legal move capture ring size as fraction of square size */
58
+ export const RING_SCALE = 0.85;
59
+
60
+ /** Legal move capture ring border as fraction of square size */
61
+ export const RING_BORDER_RATIO = 0.08;
62
+
63
+ /** Arrow stroke width as fraction of square size (percentage-based viewBox) */
64
+ export const ARROW_STROKE_WIDTH = 2.5;
65
+
66
+ /** Arrow head size */
67
+ export const ARROW_HEAD_SIZE = 2.5;
68
+
69
+ /** Arrow shorten amount (to avoid overlapping squares) */
70
+ export const ARROW_SHORTEN_BY = 4;
71
+
72
+ /** Annotation badge size as fraction of square size */
73
+ export const ANNOTATION_SCALE = 0.35;
74
+
75
+ /** Coordinate font size as fraction of square size */
76
+ export const COORDINATE_FONT_SCALE = 0.22;
77
+
78
+ /** Drag ghost scale factor (1.1x larger than normal piece) */
79
+ export const DRAG_GHOST_SCALE = 1.1;
80
+
81
+ /** Promotion picker piece padding as fraction of square size */
82
+ export const PROMOTION_PIECE_PADDING = 0.1;
83
+
84
+ // ---------------------------------------------------------------------------
85
+ // Piece codes (pre-computed to avoid allocation)
86
+ // ---------------------------------------------------------------------------
87
+
88
+ export const PIECE_CODES = [
89
+ 'wp', 'wn', 'wb', 'wr', 'wq', 'wk',
90
+ 'bp', 'bn', 'bb', 'br', 'bq', 'bk',
91
+ ] as const;
92
+
93
+ /** Board square indices 0-63 (pre-computed) */
94
+ export const SQUARE_INDICES = Array.from({ length: 64 }, (_, i) => i);
95
+
96
+ /** File letters in order */
97
+ export const FILES_WHITE = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] as const;
98
+ export const FILES_BLACK = ['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'] as const;
99
+ export const RANKS_WHITE = ['8', '7', '6', '5', '4', '3', '2', '1'] as const;
100
+ export const RANKS_BLACK = ['1', '2', '3', '4', '5', '6', '7', '8'] as const;
package/src/index.ts CHANGED
@@ -2,10 +2,51 @@
2
2
  // High-performance chess board for React Native
3
3
 
4
4
  // ---------------------------------------------------------------------------
5
- // Main component
5
+ // Main components
6
6
  // ---------------------------------------------------------------------------
7
7
 
8
8
  export { Board } from './board';
9
+ export { StaticBoard } from './static-board';
10
+
11
+ // ---------------------------------------------------------------------------
12
+ // Overlay primitives (for advanced consumers building custom layers)
13
+ // ---------------------------------------------------------------------------
14
+
15
+ export { SquareHighlight } from './board-highlights';
16
+ export { Arrow } from './board-arrows';
17
+ export { Annotation } from './board-annotations';
18
+ export { PromotionPicker } from './promotion-picker';
19
+
20
+ // ---------------------------------------------------------------------------
21
+ // Default piece set
22
+ // ---------------------------------------------------------------------------
23
+
24
+ export { DefaultPieceSet } from './pieces';
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Themes
28
+ // ---------------------------------------------------------------------------
29
+
30
+ export { BOARD_THEMES, BOARD_COLORS } from './themes';
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // Constants (useful for custom overlays matching library defaults)
34
+ // ---------------------------------------------------------------------------
35
+
36
+ export {
37
+ DEFAULT_BOARD_COLORS,
38
+ DEFAULT_LAST_MOVE_COLOR,
39
+ DEFAULT_CHECK_COLOR,
40
+ DEFAULT_SELECTED_COLOR,
41
+ DEFAULT_PREMOVE_COLOR,
42
+ DEFAULT_DRAG_TARGET_COLOR,
43
+ DEFAULT_ARROW_COLOR,
44
+ DEFAULT_SHAPE_COLOR,
45
+ DEFAULT_ANNOTATION_BG,
46
+ DEFAULT_ANNOTATION_TEXT,
47
+ DEFAULT_MOVE_DURATION,
48
+ CAPTURE_FADE_DURATION,
49
+ } from './constants';
9
50
 
10
51
  // ---------------------------------------------------------------------------
11
52
  // Types
@@ -15,15 +56,35 @@ export type {
15
56
  // Core chess types
16
57
  ChessColor,
17
58
  MoveMethod,
59
+ PromotionPiece,
60
+ HapticType,
61
+ PieceCode,
18
62
 
19
63
  // Board component API
20
64
  BoardRef,
21
65
  BoardProps,
22
66
  BoardColors,
67
+ StaticBoardProps,
23
68
 
24
69
  // Piece data (useful for custom piece renderers)
25
70
  BoardPiece,
26
71
  ParsedPiece,
72
+ PieceSetMap,
73
+
74
+ // Overlay data types
75
+ HighlightData,
76
+ ArrowData,
77
+ ShapeData,
78
+ AnnotationData,
79
+ PremoveData,
80
+
81
+ // Animation config
82
+ AnimationConfig,
83
+ TimingAnimationConfig,
84
+ SpringAnimationConfig,
85
+
86
+ // Board theme
87
+ BoardTheme,
27
88
 
28
89
  // Gesture state (useful for advanced overlays)
29
90
  GestureState,
@@ -0,0 +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
+ };
@@ -0,0 +1 @@
1
+ export { DefaultPieceSet } from './default-pieces';