react-native-chess-kit 0.5.2 → 0.5.3

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 (106) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +187 -168
  3. package/lib/commonjs/board-annotations.js +8 -8
  4. package/lib/commonjs/board-annotations.js.map +1 -1
  5. package/lib/commonjs/board-arrows.js.map +1 -1
  6. package/lib/commonjs/board-background.js +5 -5
  7. package/lib/commonjs/board-background.js.map +1 -1
  8. package/lib/commonjs/board-coordinates.js +8 -8
  9. package/lib/commonjs/board-coordinates.js.map +1 -1
  10. package/lib/commonjs/board-drag-ghost.js +10 -10
  11. package/lib/commonjs/board-drag-ghost.js.map +1 -1
  12. package/lib/commonjs/board-highlights.js +15 -15
  13. package/lib/commonjs/board-highlights.js.map +1 -1
  14. package/lib/commonjs/board-legal-dots.js +5 -5
  15. package/lib/commonjs/board-legal-dots.js.map +1 -1
  16. package/lib/commonjs/board-piece.js +25 -25
  17. package/lib/commonjs/board-piece.js.map +1 -1
  18. package/lib/commonjs/board-pieces.js +6 -6
  19. package/lib/commonjs/board-pieces.js.map +1 -1
  20. package/lib/commonjs/board.js +68 -63
  21. package/lib/commonjs/board.js.map +1 -1
  22. package/lib/commonjs/constants.js.map +1 -1
  23. package/lib/commonjs/index.js.map +1 -1
  24. package/lib/commonjs/pieces/default-pieces.js.map +1 -1
  25. package/lib/commonjs/pieces/index.js.map +1 -1
  26. package/lib/commonjs/promotion-picker.js +9 -9
  27. package/lib/commonjs/promotion-picker.js.map +1 -1
  28. package/lib/commonjs/static-board.js +7 -7
  29. package/lib/commonjs/static-board.js.map +1 -1
  30. package/lib/commonjs/themes.js.map +1 -1
  31. package/lib/commonjs/types.js.map +1 -1
  32. package/lib/commonjs/use-board-gesture.js +26 -26
  33. package/lib/commonjs/use-board-gesture.js.map +1 -1
  34. package/lib/commonjs/use-board-pieces.js +15 -15
  35. package/lib/commonjs/use-board-pieces.js.map +1 -1
  36. package/lib/commonjs/use-board-state.js +21 -12
  37. package/lib/commonjs/use-board-state.js.map +1 -1
  38. package/lib/commonjs/use-premove.js +12 -12
  39. package/lib/commonjs/use-premove.js.map +1 -1
  40. package/lib/module/board-annotations.js +8 -8
  41. package/lib/module/board-annotations.js.map +1 -1
  42. package/lib/module/board-arrows.js.map +1 -1
  43. package/lib/module/board-background.js +5 -5
  44. package/lib/module/board-background.js.map +1 -1
  45. package/lib/module/board-coordinates.js +8 -8
  46. package/lib/module/board-coordinates.js.map +1 -1
  47. package/lib/module/board-drag-ghost.js +10 -10
  48. package/lib/module/board-drag-ghost.js.map +1 -1
  49. package/lib/module/board-highlights.js +15 -15
  50. package/lib/module/board-highlights.js.map +1 -1
  51. package/lib/module/board-legal-dots.js +5 -5
  52. package/lib/module/board-legal-dots.js.map +1 -1
  53. package/lib/module/board-piece.js +25 -25
  54. package/lib/module/board-piece.js.map +1 -1
  55. package/lib/module/board-pieces.js +6 -6
  56. package/lib/module/board-pieces.js.map +1 -1
  57. package/lib/module/board.js +68 -63
  58. package/lib/module/board.js.map +1 -1
  59. package/lib/module/constants.js.map +1 -1
  60. package/lib/module/index.js.map +1 -1
  61. package/lib/module/pieces/default-pieces.js.map +1 -1
  62. package/lib/module/pieces/index.js.map +1 -1
  63. package/lib/module/promotion-picker.js +9 -9
  64. package/lib/module/promotion-picker.js.map +1 -1
  65. package/lib/module/static-board.js +7 -7
  66. package/lib/module/static-board.js.map +1 -1
  67. package/lib/module/themes.js.map +1 -1
  68. package/lib/module/types.js.map +1 -1
  69. package/lib/module/use-board-gesture.js +26 -26
  70. package/lib/module/use-board-gesture.js.map +1 -1
  71. package/lib/module/use-board-pieces.js +15 -15
  72. package/lib/module/use-board-pieces.js.map +1 -1
  73. package/lib/module/use-board-state.js +21 -12
  74. package/lib/module/use-board-state.js.map +1 -1
  75. package/lib/module/use-premove.js +12 -12
  76. package/lib/module/use-premove.js.map +1 -1
  77. package/lib/typescript/board-coordinates.d.ts.map +1 -1
  78. package/lib/typescript/board.d.ts.map +1 -1
  79. package/lib/typescript/promotion-picker.d.ts.map +1 -1
  80. package/lib/typescript/static-board.d.ts.map +1 -1
  81. package/lib/typescript/types.d.ts +12 -2
  82. package/lib/typescript/types.d.ts.map +1 -1
  83. package/lib/typescript/use-board-gesture.d.ts.map +1 -1
  84. package/lib/typescript/use-board-state.d.ts.map +1 -1
  85. package/package.json +23 -3
  86. package/src/board-annotations.tsx +147 -147
  87. package/src/board-background.tsx +46 -46
  88. package/src/board-coordinates.tsx +192 -192
  89. package/src/board-drag-ghost.tsx +132 -132
  90. package/src/board-highlights.tsx +226 -226
  91. package/src/board-legal-dots.tsx +73 -73
  92. package/src/board-piece.tsx +160 -160
  93. package/src/board-pieces.tsx +63 -63
  94. package/src/board.tsx +688 -685
  95. package/src/constants.ts +103 -103
  96. package/src/index.ts +101 -101
  97. package/src/pieces/default-pieces.tsx +383 -383
  98. package/src/pieces/index.ts +1 -1
  99. package/src/promotion-picker.tsx +147 -147
  100. package/src/static-board.tsx +186 -187
  101. package/src/themes.ts +129 -129
  102. package/src/types.ts +394 -373
  103. package/src/use-board-gesture.ts +459 -429
  104. package/src/use-board-pieces.ts +158 -158
  105. package/src/use-board-state.ts +120 -111
  106. package/src/use-premove.ts +59 -59
@@ -1,187 +1,186 @@
1
- import React, { useState, useCallback, useMemo } from 'react';
2
- import { View, type LayoutChangeEvent } from 'react-native';
3
-
4
- import type { StaticBoardProps, ChessColor, PieceCode } from './types';
5
- import { DEFAULT_BOARD_COLORS, DEFAULT_LAST_MOVE_COLOR, COORDINATE_GUTTER_SCALE } from './constants';
6
- import { DefaultPieceSet } from './pieces';
7
- import { useBoardPieces, squareToXY } from './use-board-pieces';
8
- import { BoardBackground } from './board-background';
9
- import { BoardCoordinates } from './board-coordinates';
10
- import { BoardHighlights } from './board-highlights';
11
- import { BoardArrows } from './board-arrows';
12
- import { BoardAnnotations } from './board-annotations';
13
-
14
- /**
15
- * Non-interactive chess board — optimized for lists, thumbnails, and analysis previews.
16
- *
17
- * No gesture handler, no drag ghost, no legal move dots.
18
- * Just: background + coordinates + highlights + pieces + arrows + annotations.
19
- *
20
- * Significantly lighter than the full Board component.
21
- */
22
- export const StaticBoard = React.memo(function StaticBoard({
23
- fen,
24
- orientation = 'white',
25
- boardSize: boardSizeProp,
26
- colors,
27
- coordinatePosition: coordinatePositionProp,
28
- withCoordinates,
29
- renderPiece,
30
- pieceSet,
31
- lastMove,
32
- highlights,
33
- arrows,
34
- annotations,
35
- }: StaticBoardProps) {
36
- // --- Auto-sizing via onLayout when boardSize not provided ---
37
- const [measuredSize, setMeasuredSize] = useState(0);
38
- const handleLayout = useCallback((e: LayoutChangeEvent) => {
39
- const { width, height } = e.nativeEvent.layout;
40
- setMeasuredSize(Math.min(width, height));
41
- }, []);
42
-
43
- const outerSize = boardSizeProp ?? measuredSize;
44
- const boardColors = colors ?? DEFAULT_BOARD_COLORS;
45
-
46
- // Resolve coordinate position: new prop > legacy boolean > 'none'
47
- const coordinatePosition = coordinatePositionProp
48
- ?? (withCoordinates ? 'inside' : 'none');
49
- const isOutside = coordinatePosition === 'outside';
50
- const isCoordVisible = coordinatePosition !== 'none';
51
-
52
- const gutterWidth = isOutside ? Math.round((outerSize / 8) * COORDINATE_GUTTER_SCALE) : 0;
53
- const boardSize = isOutside ? outerSize - gutterWidth : outerSize;
54
- const squareSize = boardSize / 8;
55
-
56
- // --- Piece data from FEN ---
57
- const pieces = useBoardPieces(fen);
58
-
59
- // --- Resolve piece renderer: renderPiece > pieceSet > DefaultPieceSet ---
60
- const resolvedRenderer = useMemo(() => {
61
- if (renderPiece) return renderPiece;
62
- const set = pieceSet ?? DefaultPieceSet;
63
- return (code: string, size: number) => {
64
- const renderer = set[code as PieceCode];
65
- if (renderer) return renderer(size);
66
- // Fallback for unknown piece codes
67
- return <View style={{ width: size, height: size }} />;
68
- };
69
- }, [renderPiece, pieceSet]);
70
-
71
- // If no size yet (auto-sizing), render invisible container for measurement
72
- if (outerSize === 0) {
73
- return (
74
- <View style={{ flex: 1, aspectRatio: 1 }} onLayout={handleLayout} />
75
- );
76
- }
77
-
78
- const boardContent = (
79
- <View
80
- style={isOutside
81
- ? { width: boardSize, height: boardSize, position: 'absolute', top: 0, right: 0 }
82
- : { width: boardSize, height: boardSize }}
83
- onLayout={!isOutside && !boardSizeProp ? handleLayout : undefined}
84
- accessibilityLabel="Chess board"
85
- accessibilityRole="image"
86
- >
87
- {/* Layer 1: Board background */}
88
- <BoardBackground
89
- boardSize={boardSize}
90
- lightColor={boardColors.light}
91
- darkColor={boardColors.dark}
92
- />
93
-
94
- {/* Layer 2: Inside coordinates */}
95
- {isCoordVisible && !isOutside && (
96
- <BoardCoordinates
97
- boardSize={boardSize}
98
- orientation={orientation}
99
- lightColor={boardColors.light}
100
- darkColor={boardColors.dark}
101
- withLetters
102
- withNumbers
103
- position="inside"
104
- />
105
- )}
106
-
107
- {/* Layer 3: Highlights */}
108
- <BoardHighlights
109
- boardSize={boardSize}
110
- orientation={orientation}
111
- squareSize={squareSize}
112
- lastMove={lastMove}
113
- lastMoveColor={DEFAULT_LAST_MOVE_COLOR}
114
- checkColor="transparent"
115
- selectedColor="transparent"
116
- premoveColor="transparent"
117
- highlights={highlights}
118
- />
119
-
120
- {/* Layer 4: Pieces (static — no animation needed) */}
121
- <View
122
- style={{ position: 'absolute', width: boardSize, height: boardSize }}
123
- pointerEvents="none"
124
- >
125
- {pieces.map((piece) => {
126
- const { x, y } = squareToXY(piece.square, squareSize, orientation);
127
- return (
128
- <View
129
- key={piece.id}
130
- style={{
131
- position: 'absolute',
132
- width: squareSize,
133
- height: squareSize,
134
- transform: [{ translateX: x }, { translateY: y }],
135
- }}
136
- >
137
- {resolvedRenderer(piece.code, squareSize)}
138
- </View>
139
- );
140
- })}
141
- </View>
142
-
143
- {/* Layer 5: Arrows */}
144
- {arrows && arrows.length > 0 && (
145
- <BoardArrows
146
- boardSize={boardSize}
147
- orientation={orientation}
148
- arrows={arrows}
149
- />
150
- )}
151
-
152
- {/* Layer 6: Annotations */}
153
- {annotations && annotations.length > 0 && (
154
- <BoardAnnotations
155
- boardSize={boardSize}
156
- orientation={orientation}
157
- squareSize={squareSize}
158
- annotations={annotations}
159
- />
160
- )}
161
- </View>
162
- );
163
-
164
- if (isOutside) {
165
- return (
166
- <View
167
- style={{ width: outerSize, height: boardSize + gutterWidth }}
168
- onLayout={boardSizeProp ? undefined : handleLayout}
169
- >
170
- {boardContent}
171
-
172
- <BoardCoordinates
173
- boardSize={boardSize}
174
- orientation={orientation}
175
- lightColor={boardColors.light}
176
- darkColor={boardColors.dark}
177
- withLetters
178
- withNumbers
179
- position="outside"
180
- gutterWidth={gutterWidth}
181
- />
182
- </View>
183
- );
184
- }
185
-
186
- return boardContent;
187
- });
1
+ import React, { useState, useCallback, useMemo } from 'react';
2
+ import { View, type LayoutChangeEvent } from 'react-native';
3
+
4
+ import type { StaticBoardProps, PieceCode } from './types';
5
+ import {
6
+ DEFAULT_BOARD_COLORS,
7
+ DEFAULT_LAST_MOVE_COLOR,
8
+ COORDINATE_GUTTER_SCALE,
9
+ } from './constants';
10
+ import { DefaultPieceSet } from './pieces';
11
+ import { useBoardPieces, squareToXY } from './use-board-pieces';
12
+ import { BoardBackground } from './board-background';
13
+ import { BoardCoordinates } from './board-coordinates';
14
+ import { BoardHighlights } from './board-highlights';
15
+ import { BoardArrows } from './board-arrows';
16
+ import { BoardAnnotations } from './board-annotations';
17
+
18
+ /**
19
+ * Non-interactive chess board — optimized for lists, thumbnails, and analysis previews.
20
+ *
21
+ * No gesture handler, no drag ghost, no legal move dots.
22
+ * Just: background + coordinates + highlights + pieces + arrows + annotations.
23
+ *
24
+ * Significantly lighter than the full Board component.
25
+ */
26
+ export const StaticBoard = React.memo(function StaticBoard({
27
+ fen,
28
+ orientation = 'white',
29
+ boardSize: boardSizeProp,
30
+ colors,
31
+ coordinatePosition: coordinatePositionProp,
32
+ withCoordinates,
33
+ renderPiece,
34
+ pieceSet,
35
+ lastMove,
36
+ highlights,
37
+ arrows,
38
+ annotations,
39
+ }: StaticBoardProps) {
40
+ // --- Auto-sizing via onLayout when boardSize not provided ---
41
+ const [measuredSize, setMeasuredSize] = useState(0);
42
+ const handleLayout = useCallback((e: LayoutChangeEvent) => {
43
+ const { width, height } = e.nativeEvent.layout;
44
+ setMeasuredSize(Math.min(width, height));
45
+ }, []);
46
+
47
+ const outerSize = boardSizeProp ?? measuredSize;
48
+ const boardColors = colors ?? DEFAULT_BOARD_COLORS;
49
+
50
+ // Resolve coordinate position: new prop > legacy boolean > 'none'
51
+ const coordinatePosition = coordinatePositionProp ?? (withCoordinates ? 'inside' : 'none');
52
+ const isOutside = coordinatePosition === 'outside';
53
+ const isCoordVisible = coordinatePosition !== 'none';
54
+
55
+ const gutterWidth = isOutside ? Math.round((outerSize / 8) * COORDINATE_GUTTER_SCALE) : 0;
56
+ const boardSize = isOutside ? outerSize - gutterWidth : outerSize;
57
+ const squareSize = boardSize / 8;
58
+
59
+ // --- Piece data from FEN ---
60
+ const pieces = useBoardPieces(fen);
61
+
62
+ // --- Resolve piece renderer: renderPiece > pieceSet > DefaultPieceSet ---
63
+ const resolvedRenderer = useMemo(() => {
64
+ if (renderPiece) return renderPiece;
65
+ const set = pieceSet ?? DefaultPieceSet;
66
+ return (code: string, size: number) => {
67
+ const renderer = set[code as PieceCode];
68
+ if (renderer) return renderer(size);
69
+ // Fallback for unknown piece codes
70
+ return <View style={{ width: size, height: size }} />;
71
+ };
72
+ }, [renderPiece, pieceSet]);
73
+
74
+ // If no size yet (auto-sizing), render invisible container for measurement
75
+ if (outerSize === 0) {
76
+ return <View style={{ flex: 1, aspectRatio: 1 }} onLayout={handleLayout} />;
77
+ }
78
+
79
+ const boardContent = (
80
+ <View
81
+ style={
82
+ isOutside
83
+ ? { width: boardSize, height: boardSize, position: 'absolute', top: 0, right: 0 }
84
+ : { width: boardSize, height: boardSize }
85
+ }
86
+ onLayout={!isOutside && !boardSizeProp ? handleLayout : undefined}
87
+ accessibilityLabel="Chess board"
88
+ accessibilityRole="image"
89
+ >
90
+ {/* Layer 1: Board background */}
91
+ <BoardBackground
92
+ boardSize={boardSize}
93
+ lightColor={boardColors.light}
94
+ darkColor={boardColors.dark}
95
+ />
96
+
97
+ {/* Layer 2: Inside coordinates */}
98
+ {isCoordVisible && !isOutside && (
99
+ <BoardCoordinates
100
+ boardSize={boardSize}
101
+ orientation={orientation}
102
+ lightColor={boardColors.light}
103
+ darkColor={boardColors.dark}
104
+ withLetters
105
+ withNumbers
106
+ position="inside"
107
+ />
108
+ )}
109
+
110
+ {/* Layer 3: Highlights */}
111
+ <BoardHighlights
112
+ boardSize={boardSize}
113
+ orientation={orientation}
114
+ squareSize={squareSize}
115
+ lastMove={lastMove}
116
+ lastMoveColor={DEFAULT_LAST_MOVE_COLOR}
117
+ checkColor="transparent"
118
+ selectedColor="transparent"
119
+ premoveColor="transparent"
120
+ highlights={highlights}
121
+ />
122
+
123
+ {/* Layer 4: Pieces (static — no animation needed) */}
124
+ <View
125
+ style={{ position: 'absolute', width: boardSize, height: boardSize }}
126
+ pointerEvents="none"
127
+ >
128
+ {pieces.map((piece) => {
129
+ const { x, y } = squareToXY(piece.square, squareSize, orientation);
130
+ return (
131
+ <View
132
+ key={piece.id}
133
+ style={{
134
+ position: 'absolute',
135
+ width: squareSize,
136
+ height: squareSize,
137
+ transform: [{ translateX: x }, { translateY: y }],
138
+ }}
139
+ >
140
+ {resolvedRenderer(piece.code, squareSize)}
141
+ </View>
142
+ );
143
+ })}
144
+ </View>
145
+
146
+ {/* Layer 5: Arrows */}
147
+ {arrows && arrows.length > 0 && (
148
+ <BoardArrows boardSize={boardSize} orientation={orientation} arrows={arrows} />
149
+ )}
150
+
151
+ {/* Layer 6: Annotations */}
152
+ {annotations && annotations.length > 0 && (
153
+ <BoardAnnotations
154
+ boardSize={boardSize}
155
+ orientation={orientation}
156
+ squareSize={squareSize}
157
+ annotations={annotations}
158
+ />
159
+ )}
160
+ </View>
161
+ );
162
+
163
+ if (isOutside) {
164
+ return (
165
+ <View
166
+ style={{ width: outerSize, height: boardSize + gutterWidth }}
167
+ onLayout={boardSizeProp ? undefined : handleLayout}
168
+ >
169
+ {boardContent}
170
+
171
+ <BoardCoordinates
172
+ boardSize={boardSize}
173
+ orientation={orientation}
174
+ lightColor={boardColors.light}
175
+ darkColor={boardColors.dark}
176
+ withLetters
177
+ withNumbers
178
+ position="outside"
179
+ gutterWidth={gutterWidth}
180
+ />
181
+ </View>
182
+ );
183
+ }
184
+
185
+ return boardContent;
186
+ });
package/src/themes.ts CHANGED
@@ -1,129 +1,129 @@
1
- import type { BoardTheme, BoardColors } from './types';
2
-
3
- // ---------------------------------------------------------------------------
4
- // Board color presets (matching popular chess platforms)
5
- // ---------------------------------------------------------------------------
6
-
7
- const greenTheme: BoardTheme = {
8
- name: 'Green',
9
- board: { light: '#eeeed2', dark: '#769656' },
10
- lastMove: 'rgba(255, 255, 0, 0.4)',
11
- check: 'rgba(235, 97, 80, 0.8)',
12
- selected: 'rgba(20, 85, 200, 0.5)',
13
- legalDot: 'rgba(0, 0, 0, 0.25)',
14
- premove: 'rgba(20, 85, 200, 0.3)',
15
- arrow: 'rgba(243, 166, 50, 0.85)',
16
- coordinates: { light: '#769656', dark: '#eeeed2' },
17
- };
18
-
19
- const brownTheme: BoardTheme = {
20
- name: 'Brown',
21
- board: { light: '#f0d9b5', dark: '#b58863' },
22
- lastMove: 'rgba(255, 255, 0, 0.4)',
23
- check: 'rgba(235, 97, 80, 0.8)',
24
- selected: 'rgba(20, 85, 200, 0.5)',
25
- legalDot: 'rgba(0, 0, 0, 0.25)',
26
- premove: 'rgba(20, 85, 200, 0.3)',
27
- arrow: 'rgba(243, 166, 50, 0.85)',
28
- coordinates: { light: '#b58863', dark: '#f0d9b5' },
29
- };
30
-
31
- const blueTheme: BoardTheme = {
32
- name: 'Blue',
33
- board: { light: '#dee3e6', dark: '#8ca2ad' },
34
- lastMove: 'rgba(255, 255, 0, 0.4)',
35
- check: 'rgba(235, 97, 80, 0.8)',
36
- selected: 'rgba(20, 85, 200, 0.5)',
37
- legalDot: 'rgba(0, 0, 0, 0.25)',
38
- premove: 'rgba(20, 85, 200, 0.3)',
39
- arrow: 'rgba(243, 166, 50, 0.85)',
40
- coordinates: { light: '#8ca2ad', dark: '#dee3e6' },
41
- };
42
-
43
- const purpleTheme: BoardTheme = {
44
- name: 'Purple',
45
- board: { light: '#e8daf0', dark: '#9b72b0' },
46
- lastMove: 'rgba(255, 255, 0, 0.4)',
47
- check: 'rgba(235, 97, 80, 0.8)',
48
- selected: 'rgba(20, 85, 200, 0.5)',
49
- legalDot: 'rgba(0, 0, 0, 0.25)',
50
- premove: 'rgba(20, 85, 200, 0.3)',
51
- arrow: 'rgba(243, 166, 50, 0.85)',
52
- coordinates: { light: '#9b72b0', dark: '#e8daf0' },
53
- };
54
-
55
- const grayTheme: BoardTheme = {
56
- name: 'Gray',
57
- board: { light: '#e0e0e0', dark: '#888888' },
58
- lastMove: 'rgba(255, 255, 0, 0.4)',
59
- check: 'rgba(235, 97, 80, 0.8)',
60
- selected: 'rgba(20, 85, 200, 0.5)',
61
- legalDot: 'rgba(0, 0, 0, 0.25)',
62
- premove: 'rgba(20, 85, 200, 0.3)',
63
- arrow: 'rgba(243, 166, 50, 0.85)',
64
- coordinates: { light: '#888888', dark: '#e0e0e0' },
65
- };
66
-
67
- const woodTheme: BoardTheme = {
68
- name: 'Wood',
69
- board: { light: '#e6c88c', dark: '#a67c52' },
70
- lastMove: 'rgba(255, 255, 0, 0.35)',
71
- check: 'rgba(235, 97, 80, 0.8)',
72
- selected: 'rgba(20, 85, 200, 0.5)',
73
- legalDot: 'rgba(0, 0, 0, 0.2)',
74
- premove: 'rgba(20, 85, 200, 0.3)',
75
- arrow: 'rgba(243, 166, 50, 0.85)',
76
- coordinates: { light: '#a67c52', dark: '#e6c88c' },
77
- };
78
-
79
- const iceTheme: BoardTheme = {
80
- name: 'Ice',
81
- board: { light: '#e8f0f8', dark: '#7ba0c4' },
82
- lastMove: 'rgba(255, 255, 0, 0.35)',
83
- check: 'rgba(235, 97, 80, 0.8)',
84
- selected: 'rgba(20, 85, 200, 0.5)',
85
- legalDot: 'rgba(0, 0, 0, 0.25)',
86
- premove: 'rgba(20, 85, 200, 0.3)',
87
- arrow: 'rgba(243, 166, 50, 0.85)',
88
- coordinates: { light: '#7ba0c4', dark: '#e8f0f8' },
89
- };
90
-
91
- const tournamentTheme: BoardTheme = {
92
- name: 'Tournament',
93
- board: { light: '#fffff0', dark: '#3d945e' },
94
- lastMove: 'rgba(255, 255, 0, 0.4)',
95
- check: 'rgba(235, 97, 80, 0.8)',
96
- selected: 'rgba(20, 85, 200, 0.5)',
97
- legalDot: 'rgba(0, 0, 0, 0.25)',
98
- premove: 'rgba(20, 85, 200, 0.3)',
99
- arrow: 'rgba(243, 166, 50, 0.85)',
100
- coordinates: { light: '#3d945e', dark: '#fffff0' },
101
- };
102
-
103
- // ---------------------------------------------------------------------------
104
- // Exports
105
- // ---------------------------------------------------------------------------
106
-
107
- /** All built-in board themes */
108
- export const BOARD_THEMES = {
109
- green: greenTheme,
110
- brown: brownTheme,
111
- blue: blueTheme,
112
- purple: purpleTheme,
113
- gray: grayTheme,
114
- wood: woodTheme,
115
- ice: iceTheme,
116
- tournament: tournamentTheme,
117
- } as const;
118
-
119
- /** Shorthand board color presets (just light/dark, no overlay colors) */
120
- export const BOARD_COLORS: Record<keyof typeof BOARD_THEMES, BoardColors> = {
121
- green: greenTheme.board,
122
- brown: brownTheme.board,
123
- blue: blueTheme.board,
124
- purple: purpleTheme.board,
125
- gray: grayTheme.board,
126
- wood: woodTheme.board,
127
- ice: iceTheme.board,
128
- tournament: tournamentTheme.board,
129
- };
1
+ import type { BoardTheme, BoardColors } from './types';
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Board color presets (matching popular chess platforms)
5
+ // ---------------------------------------------------------------------------
6
+
7
+ const greenTheme: BoardTheme = {
8
+ name: 'Green',
9
+ board: { light: '#eeeed2', dark: '#769656' },
10
+ lastMove: 'rgba(255, 255, 0, 0.4)',
11
+ check: 'rgba(235, 97, 80, 0.8)',
12
+ selected: 'rgba(20, 85, 200, 0.5)',
13
+ legalDot: 'rgba(0, 0, 0, 0.25)',
14
+ premove: 'rgba(20, 85, 200, 0.3)',
15
+ arrow: 'rgba(243, 166, 50, 0.85)',
16
+ coordinates: { light: '#769656', dark: '#eeeed2' },
17
+ };
18
+
19
+ const brownTheme: BoardTheme = {
20
+ name: 'Brown',
21
+ board: { light: '#f0d9b5', dark: '#b58863' },
22
+ lastMove: 'rgba(255, 255, 0, 0.4)',
23
+ check: 'rgba(235, 97, 80, 0.8)',
24
+ selected: 'rgba(20, 85, 200, 0.5)',
25
+ legalDot: 'rgba(0, 0, 0, 0.25)',
26
+ premove: 'rgba(20, 85, 200, 0.3)',
27
+ arrow: 'rgba(243, 166, 50, 0.85)',
28
+ coordinates: { light: '#b58863', dark: '#f0d9b5' },
29
+ };
30
+
31
+ const blueTheme: BoardTheme = {
32
+ name: 'Blue',
33
+ board: { light: '#dee3e6', dark: '#8ca2ad' },
34
+ lastMove: 'rgba(255, 255, 0, 0.4)',
35
+ check: 'rgba(235, 97, 80, 0.8)',
36
+ selected: 'rgba(20, 85, 200, 0.5)',
37
+ legalDot: 'rgba(0, 0, 0, 0.25)',
38
+ premove: 'rgba(20, 85, 200, 0.3)',
39
+ arrow: 'rgba(243, 166, 50, 0.85)',
40
+ coordinates: { light: '#8ca2ad', dark: '#dee3e6' },
41
+ };
42
+
43
+ const purpleTheme: BoardTheme = {
44
+ name: 'Purple',
45
+ board: { light: '#e8daf0', dark: '#9b72b0' },
46
+ lastMove: 'rgba(255, 255, 0, 0.4)',
47
+ check: 'rgba(235, 97, 80, 0.8)',
48
+ selected: 'rgba(20, 85, 200, 0.5)',
49
+ legalDot: 'rgba(0, 0, 0, 0.25)',
50
+ premove: 'rgba(20, 85, 200, 0.3)',
51
+ arrow: 'rgba(243, 166, 50, 0.85)',
52
+ coordinates: { light: '#9b72b0', dark: '#e8daf0' },
53
+ };
54
+
55
+ const grayTheme: BoardTheme = {
56
+ name: 'Gray',
57
+ board: { light: '#e0e0e0', dark: '#888888' },
58
+ lastMove: 'rgba(255, 255, 0, 0.4)',
59
+ check: 'rgba(235, 97, 80, 0.8)',
60
+ selected: 'rgba(20, 85, 200, 0.5)',
61
+ legalDot: 'rgba(0, 0, 0, 0.25)',
62
+ premove: 'rgba(20, 85, 200, 0.3)',
63
+ arrow: 'rgba(243, 166, 50, 0.85)',
64
+ coordinates: { light: '#888888', dark: '#e0e0e0' },
65
+ };
66
+
67
+ const woodTheme: BoardTheme = {
68
+ name: 'Wood',
69
+ board: { light: '#e6c88c', dark: '#a67c52' },
70
+ lastMove: 'rgba(255, 255, 0, 0.35)',
71
+ check: 'rgba(235, 97, 80, 0.8)',
72
+ selected: 'rgba(20, 85, 200, 0.5)',
73
+ legalDot: 'rgba(0, 0, 0, 0.2)',
74
+ premove: 'rgba(20, 85, 200, 0.3)',
75
+ arrow: 'rgba(243, 166, 50, 0.85)',
76
+ coordinates: { light: '#a67c52', dark: '#e6c88c' },
77
+ };
78
+
79
+ const iceTheme: BoardTheme = {
80
+ name: 'Ice',
81
+ board: { light: '#e8f0f8', dark: '#7ba0c4' },
82
+ lastMove: 'rgba(255, 255, 0, 0.35)',
83
+ check: 'rgba(235, 97, 80, 0.8)',
84
+ selected: 'rgba(20, 85, 200, 0.5)',
85
+ legalDot: 'rgba(0, 0, 0, 0.25)',
86
+ premove: 'rgba(20, 85, 200, 0.3)',
87
+ arrow: 'rgba(243, 166, 50, 0.85)',
88
+ coordinates: { light: '#7ba0c4', dark: '#e8f0f8' },
89
+ };
90
+
91
+ const tournamentTheme: BoardTheme = {
92
+ name: 'Tournament',
93
+ board: { light: '#fffff0', dark: '#3d945e' },
94
+ lastMove: 'rgba(255, 255, 0, 0.4)',
95
+ check: 'rgba(235, 97, 80, 0.8)',
96
+ selected: 'rgba(20, 85, 200, 0.5)',
97
+ legalDot: 'rgba(0, 0, 0, 0.25)',
98
+ premove: 'rgba(20, 85, 200, 0.3)',
99
+ arrow: 'rgba(243, 166, 50, 0.85)',
100
+ coordinates: { light: '#3d945e', dark: '#fffff0' },
101
+ };
102
+
103
+ // ---------------------------------------------------------------------------
104
+ // Exports
105
+ // ---------------------------------------------------------------------------
106
+
107
+ /** All built-in board themes */
108
+ export const BOARD_THEMES = {
109
+ green: greenTheme,
110
+ brown: brownTheme,
111
+ blue: blueTheme,
112
+ purple: purpleTheme,
113
+ gray: grayTheme,
114
+ wood: woodTheme,
115
+ ice: iceTheme,
116
+ tournament: tournamentTheme,
117
+ } as const;
118
+
119
+ /** Shorthand board color presets (just light/dark, no overlay colors) */
120
+ export const BOARD_COLORS: Record<keyof typeof BOARD_THEMES, BoardColors> = {
121
+ green: greenTheme.board,
122
+ brown: brownTheme.board,
123
+ blue: blueTheme.board,
124
+ purple: purpleTheme.board,
125
+ gray: grayTheme.board,
126
+ wood: woodTheme.board,
127
+ ice: iceTheme.board,
128
+ tournament: tournamentTheme.board,
129
+ };