@react-chess-tools/react-chess-game 0.5.2 → 1.0.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 (48) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +399 -0
  3. package/dist/index.cjs +785 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +278 -0
  6. package/dist/index.d.ts +278 -0
  7. package/dist/{index.mjs → index.js} +339 -196
  8. package/dist/index.js.map +1 -0
  9. package/package.json +19 -9
  10. package/src/components/ChessGame/Theme.stories.tsx +242 -0
  11. package/src/components/ChessGame/ThemePresets.stories.tsx +144 -0
  12. package/src/components/ChessGame/parts/Board.tsx +215 -204
  13. package/src/components/ChessGame/parts/KeyboardControls.tsx +9 -0
  14. package/src/components/ChessGame/parts/Root.tsx +13 -1
  15. package/src/components/ChessGame/parts/Sounds.tsx +9 -0
  16. package/src/components/ChessGame/parts/__tests__/Board.test.tsx +122 -0
  17. package/src/components/ChessGame/parts/__tests__/KeyboardControls.test.tsx +34 -0
  18. package/src/components/ChessGame/parts/__tests__/Root.test.tsx +50 -0
  19. package/src/components/ChessGame/parts/__tests__/Sounds.test.tsx +22 -0
  20. package/src/docs/Theming.mdx +281 -0
  21. package/src/hooks/useChessGame.ts +23 -7
  22. package/src/index.ts +19 -0
  23. package/src/theme/__tests__/context.test.tsx +60 -0
  24. package/src/theme/__tests__/defaults.test.ts +61 -0
  25. package/src/theme/__tests__/utils.test.ts +106 -0
  26. package/src/theme/context.tsx +37 -0
  27. package/src/theme/defaults.ts +22 -0
  28. package/src/theme/index.ts +36 -0
  29. package/src/theme/presets.ts +41 -0
  30. package/src/theme/types.ts +56 -0
  31. package/src/theme/utils.ts +47 -0
  32. package/src/utils/__tests__/board.test.ts +118 -0
  33. package/src/utils/board.ts +18 -9
  34. package/src/utils/chess.ts +25 -5
  35. package/README.MD +0 -190
  36. package/coverage/clover.xml +0 -6
  37. package/coverage/coverage-final.json +0 -1
  38. package/coverage/lcov-report/base.css +0 -224
  39. package/coverage/lcov-report/block-navigation.js +0 -87
  40. package/coverage/lcov-report/favicon.png +0 -0
  41. package/coverage/lcov-report/index.html +0 -101
  42. package/coverage/lcov-report/prettify.css +0 -1
  43. package/coverage/lcov-report/prettify.js +0 -2
  44. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  45. package/coverage/lcov-report/sorter.js +0 -196
  46. package/coverage/lcov.info +0 -0
  47. package/dist/index.d.mts +0 -158
  48. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,278 @@
1
+ import * as React$1 from 'react';
2
+ import React__default, { CSSProperties } from 'react';
3
+ import { ChessboardOptions } from 'react-chessboard';
4
+ import * as chess_js from 'chess.js';
5
+ import { Color, Chess } from 'chess.js';
6
+
7
+ type Sound = "check" | "move" | "capture" | "gameOver";
8
+ type Sounds = Record<Sound, HTMLAudioElement>;
9
+
10
+ /**
11
+ * Props for the Sounds component
12
+ *
13
+ * Note: This is a logic-only component that returns null and does not render
14
+ * any DOM elements. It sets up board sounds via the useBoardSounds hook.
15
+ * Therefore, it does not accept HTML attributes like className, style, etc.
16
+ */
17
+ type SoundsProps = {
18
+ sounds?: Partial<Record<Sound, string>>;
19
+ };
20
+
21
+ interface ChessGameProps extends React__default.HTMLAttributes<HTMLDivElement> {
22
+ options?: ChessboardOptions;
23
+ }
24
+
25
+ /**
26
+ * Board appearance configuration - colors for light and dark squares
27
+ */
28
+ interface BoardTheme {
29
+ /** Style for light squares */
30
+ lightSquare: CSSProperties;
31
+ /** Style for dark squares */
32
+ darkSquare: CSSProperties;
33
+ }
34
+ /**
35
+ * Game state highlight colors (RGBA color strings)
36
+ */
37
+ interface StateTheme {
38
+ /** Background color for last move from/to squares */
39
+ lastMove: string;
40
+ /** Background color for king when in check */
41
+ check: string;
42
+ /** Background color for currently selected piece's square */
43
+ activeSquare: string;
44
+ /** Full CSSProperties for valid drop target squares */
45
+ dropSquare: CSSProperties;
46
+ }
47
+ /**
48
+ * Move indicator styling - colors for move dots and capture rings
49
+ */
50
+ interface IndicatorTheme {
51
+ /** Color for move dots on empty destination squares (used in radial-gradient) */
52
+ move: string;
53
+ /** Color for capture rings on capturable pieces (used in radial-gradient) */
54
+ capture: string;
55
+ }
56
+ /**
57
+ * Complete theme configuration for ChessGame component
58
+ */
59
+ interface ChessGameTheme {
60
+ board: BoardTheme;
61
+ state: StateTheme;
62
+ indicators: IndicatorTheme;
63
+ }
64
+ /**
65
+ * Utility type for creating partial versions of nested objects
66
+ */
67
+ type DeepPartial<T> = {
68
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
69
+ };
70
+ /**
71
+ * Partial theme for user customization - allows overriding only specific properties
72
+ */
73
+ type PartialChessGameTheme = DeepPartial<ChessGameTheme>;
74
+
75
+ interface RootProps {
76
+ fen?: string;
77
+ orientation?: Color;
78
+ /** Optional theme configuration. Supports partial themes - only override the colors you need. */
79
+ theme?: PartialChessGameTheme;
80
+ }
81
+
82
+ type useChessGameProps = {
83
+ fen?: string;
84
+ orientation?: Color;
85
+ };
86
+ declare const useChessGame: ({ fen, orientation: initialOrientation, }?: useChessGameProps) => {
87
+ game: Chess;
88
+ currentFen: string;
89
+ currentPosition: string;
90
+ orientation: Color;
91
+ currentMoveIndex: number;
92
+ isLatestMove: boolean;
93
+ info: {
94
+ turn: Color;
95
+ isPlayerTurn: boolean;
96
+ isOpponentTurn: boolean;
97
+ moveNumber: number;
98
+ lastMove: chess_js.Move | undefined;
99
+ isCheck: boolean;
100
+ isCheckmate: boolean;
101
+ isDraw: boolean;
102
+ isStalemate: boolean;
103
+ isThreefoldRepetition: boolean;
104
+ isInsufficientMaterial: boolean;
105
+ isGameOver: boolean;
106
+ isDrawn: boolean;
107
+ hasPlayerWon: boolean;
108
+ hasPlayerLost: boolean;
109
+ };
110
+ methods: {
111
+ makeMove: (move: Parameters<Chess["move"]>[0]) => boolean;
112
+ setPosition: (fen: string, orientation: Color) => void;
113
+ flipBoard: () => void;
114
+ goToMove: (moveIndex: number) => void;
115
+ goToStart: () => void;
116
+ goToEnd: () => void;
117
+ goToPreviousMove: () => void;
118
+ goToNextMove: () => void;
119
+ };
120
+ };
121
+
122
+ declare const useChessGameContext: () => {
123
+ game: chess_js.Chess;
124
+ currentFen: string;
125
+ currentPosition: string;
126
+ orientation: chess_js.Color;
127
+ currentMoveIndex: number;
128
+ isLatestMove: boolean;
129
+ info: {
130
+ turn: chess_js.Color;
131
+ isPlayerTurn: boolean;
132
+ isOpponentTurn: boolean;
133
+ moveNumber: number;
134
+ lastMove: chess_js.Move | undefined;
135
+ isCheck: boolean;
136
+ isCheckmate: boolean;
137
+ isDraw: boolean;
138
+ isStalemate: boolean;
139
+ isThreefoldRepetition: boolean;
140
+ isInsufficientMaterial: boolean;
141
+ isGameOver: boolean;
142
+ isDrawn: boolean;
143
+ hasPlayerWon: boolean;
144
+ hasPlayerLost: boolean;
145
+ };
146
+ methods: {
147
+ makeMove: (move: Parameters<chess_js.Chess["move"]>[0]) => boolean;
148
+ setPosition: (fen: string, orientation: chess_js.Color) => void;
149
+ flipBoard: () => void;
150
+ goToMove: (moveIndex: number) => void;
151
+ goToStart: () => void;
152
+ goToEnd: () => void;
153
+ goToPreviousMove: () => void;
154
+ goToNextMove: () => void;
155
+ };
156
+ };
157
+ type ChessGameContextType = ReturnType<typeof useChessGame>;
158
+
159
+ /**
160
+ * Props for the KeyboardControls component
161
+ *
162
+ * Note: This is a logic-only component that returns null and does not render
163
+ * any DOM elements. It sets up keyboard controls via the useKeyboardControls hook.
164
+ * Therefore, it does not accept HTML attributes like className, style, etc.
165
+ */
166
+ type KeyboardControlsProps = {
167
+ controls?: KeyboardControls;
168
+ };
169
+ type KeyboardControls = Record<string, (context: ChessGameContextType) => void>;
170
+ declare const KeyboardControls: React.FC<KeyboardControlsProps>;
171
+
172
+ declare const ChessGame: {
173
+ Root: React$1.FC<React$1.PropsWithChildren<RootProps>>;
174
+ Board: React$1.ForwardRefExoticComponent<ChessGameProps & React$1.RefAttributes<HTMLDivElement>>;
175
+ Sounds: React$1.FC<SoundsProps>;
176
+ KeyboardControls: React$1.FC<{
177
+ controls?: KeyboardControls;
178
+ }>;
179
+ };
180
+
181
+ /**
182
+ * Returns an object with information about the current state of the game. This can be determined
183
+ * using chess.js instance, but this function is provided for convenience.
184
+ * @param game - The Chess.js instance representing the game.
185
+ * @returns An object with information about the current state of the game.
186
+ */
187
+ declare const getGameInfo: (game: Chess, orientation: Color) => {
188
+ turn: Color;
189
+ isPlayerTurn: boolean;
190
+ isOpponentTurn: boolean;
191
+ moveNumber: number;
192
+ lastMove: chess_js.Move | undefined;
193
+ isCheck: boolean;
194
+ isCheckmate: boolean;
195
+ isDraw: boolean;
196
+ isStalemate: boolean;
197
+ isThreefoldRepetition: boolean;
198
+ isInsufficientMaterial: boolean;
199
+ isGameOver: boolean;
200
+ isDrawn: boolean;
201
+ hasPlayerWon: boolean;
202
+ hasPlayerLost: boolean;
203
+ };
204
+ type GameInfo = ReturnType<typeof getGameInfo>;
205
+
206
+ /**
207
+ * Smart deep merge for ChessboardOptions that handles different property types appropriately:
208
+ * - Functions: Overwrite (custom functions replace base functions)
209
+ * - Objects: Deep merge (nested objects merge recursively)
210
+ * - Primitives: Overwrite (custom values replace base values)
211
+ *
212
+ * This ensures that computed options (like squareStyles with move highlighting) are preserved
213
+ * while allowing custom options to extend or override them intelligently.
214
+ *
215
+ * @param baseOptions - The computed base options (e.g., computed squareStyles, event handlers)
216
+ * @param customOptions - Custom options provided by the user
217
+ * @returns Intelligently merged ChessboardOptions
218
+ */
219
+ declare const deepMergeChessboardOptions: (baseOptions: ChessboardOptions, customOptions?: Partial<ChessboardOptions>) => ChessboardOptions;
220
+
221
+ /**
222
+ * Default theme for ChessGame component.
223
+ * These values match the original hardcoded colors for backward compatibility.
224
+ */
225
+ declare const defaultGameTheme: ChessGameTheme;
226
+
227
+ /**
228
+ * Lichess-inspired theme with green highlights
229
+ */
230
+ declare const lichessTheme: ChessGameTheme;
231
+ /**
232
+ * Chess.com-inspired theme with green board and yellow highlights
233
+ */
234
+ declare const chessComTheme: ChessGameTheme;
235
+
236
+ /**
237
+ * Deep merges a partial theme with the default theme.
238
+ * Allows users to override only specific theme properties while keeping defaults for the rest.
239
+ *
240
+ * @param partialTheme - Partial theme with only the properties to override
241
+ * @returns Complete theme with overridden properties merged with defaults
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * const customTheme = mergeTheme({
246
+ * state: { lastMove: "rgba(100, 200, 100, 0.6)" }
247
+ * });
248
+ * // Returns full theme with only lastMove color changed
249
+ * ```
250
+ */
251
+ declare const mergeTheme: (partialTheme?: PartialChessGameTheme) => ChessGameTheme;
252
+ /**
253
+ * Deep merges a partial theme with a base theme.
254
+ * Useful when extending an existing theme.
255
+ *
256
+ * @param baseTheme - The base theme to extend
257
+ * @param partialTheme - Partial theme with properties to override
258
+ * @returns Complete theme with overridden properties
259
+ */
260
+ declare const mergeThemeWith: (baseTheme: ChessGameTheme, partialTheme?: PartialChessGameTheme) => ChessGameTheme;
261
+
262
+ /**
263
+ * Context for ChessGame theme
264
+ */
265
+ declare const ChessGameThemeContext: React__default.Context<ChessGameTheme>;
266
+ /**
267
+ * Hook to access the current ChessGame theme.
268
+ * Returns the default theme if no ThemeProvider is present.
269
+ */
270
+ declare const useChessGameTheme: () => ChessGameTheme;
271
+
272
+ declare const themes: {
273
+ readonly default: ChessGameTheme;
274
+ readonly lichess: ChessGameTheme;
275
+ readonly chessCom: ChessGameTheme;
276
+ };
277
+
278
+ export { type BoardTheme, ChessGame, type ChessGameContextType, type ChessGameProps, type ChessGameTheme, ChessGameThemeContext, type DeepPartial, type GameInfo, type IndicatorTheme, KeyboardControls, type PartialChessGameTheme, type RootProps, type Sound, type Sounds, type SoundsProps, type StateTheme, chessComTheme, deepMergeChessboardOptions, defaultGameTheme, lichessTheme, mergeTheme, mergeThemeWith, themes, useChessGame, useChessGameContext, type useChessGameProps, useChessGameTheme };