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.
- package/lib/commonjs/board-annotations.js +131 -0
- package/lib/commonjs/board-annotations.js.map +1 -0
- package/lib/commonjs/board-arrows.js +164 -0
- package/lib/commonjs/board-arrows.js.map +1 -0
- package/lib/commonjs/board-highlights.js +212 -0
- package/lib/commonjs/board-highlights.js.map +1 -0
- package/lib/commonjs/board-piece.js +71 -25
- package/lib/commonjs/board-piece.js.map +1 -1
- package/lib/commonjs/board-pieces.js +2 -0
- package/lib/commonjs/board-pieces.js.map +1 -1
- package/lib/commonjs/board.js +392 -42
- package/lib/commonjs/board.js.map +1 -1
- package/lib/commonjs/constants.js +104 -0
- package/lib/commonjs/constants.js.map +1 -0
- package/lib/commonjs/index.js +128 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/pieces/default-pieces.js +536 -0
- package/lib/commonjs/pieces/default-pieces.js.map +1 -0
- package/lib/commonjs/pieces/index.js +13 -0
- package/lib/commonjs/pieces/index.js.map +1 -0
- package/lib/commonjs/promotion-picker.js +129 -0
- package/lib/commonjs/promotion-picker.js.map +1 -0
- package/lib/commonjs/static-board.js +150 -0
- package/lib/commonjs/static-board.js.map +1 -0
- package/lib/commonjs/themes.js +175 -0
- package/lib/commonjs/themes.js.map +1 -0
- package/lib/commonjs/use-board-gesture.js +184 -11
- package/lib/commonjs/use-board-gesture.js.map +1 -1
- package/lib/commonjs/use-premove.js +44 -0
- package/lib/commonjs/use-premove.js.map +1 -0
- package/lib/module/board-annotations.js +126 -0
- package/lib/module/board-annotations.js.map +1 -0
- package/lib/module/board-arrows.js +161 -0
- package/lib/module/board-arrows.js.map +1 -0
- package/lib/module/board-highlights.js +206 -0
- package/lib/module/board-highlights.js.map +1 -0
- package/lib/module/board-piece.js +72 -26
- package/lib/module/board-piece.js.map +1 -1
- package/lib/module/board-pieces.js +2 -0
- package/lib/module/board-pieces.js.map +1 -1
- package/lib/module/board.js +395 -44
- package/lib/module/board.js.map +1 -1
- package/lib/module/constants.js +100 -0
- package/lib/module/constants.js.map +1 -0
- package/lib/module/index.js +29 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/pieces/default-pieces.js +530 -0
- package/lib/module/pieces/default-pieces.js.map +1 -0
- package/lib/module/pieces/index.js +4 -0
- package/lib/module/pieces/index.js.map +1 -0
- package/lib/module/promotion-picker.js +124 -0
- package/lib/module/promotion-picker.js.map +1 -0
- package/lib/module/static-board.js +146 -0
- package/lib/module/static-board.js.map +1 -0
- package/lib/module/themes.js +171 -0
- package/lib/module/themes.js.map +1 -0
- package/lib/module/use-board-gesture.js +185 -11
- package/lib/module/use-board-gesture.js.map +1 -1
- package/lib/module/use-premove.js +40 -0
- package/lib/module/use-premove.js.map +1 -0
- package/lib/typescript/board-annotations.d.ts +30 -0
- package/lib/typescript/board-annotations.d.ts.map +1 -0
- package/lib/typescript/board-arrows.d.ts +27 -0
- package/lib/typescript/board-arrows.d.ts.map +1 -0
- package/lib/typescript/board-highlights.d.ts +65 -0
- package/lib/typescript/board-highlights.d.ts.map +1 -0
- package/lib/typescript/board-piece.d.ts +19 -9
- package/lib/typescript/board-piece.d.ts.map +1 -1
- package/lib/typescript/board-pieces.d.ts +2 -1
- package/lib/typescript/board-pieces.d.ts.map +1 -1
- package/lib/typescript/board.d.ts +11 -2
- package/lib/typescript/board.d.ts.map +1 -1
- package/lib/typescript/constants.d.ts +54 -0
- package/lib/typescript/constants.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +9 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/pieces/default-pieces.d.ts +3 -0
- package/lib/typescript/pieces/default-pieces.d.ts.map +1 -0
- package/lib/typescript/pieces/index.d.ts +2 -0
- package/lib/typescript/pieces/index.d.ts.map +1 -0
- package/lib/typescript/promotion-picker.d.ts +30 -0
- package/lib/typescript/promotion-picker.d.ts.map +1 -0
- package/lib/typescript/static-board.d.ts +12 -0
- package/lib/typescript/static-board.d.ts.map +1 -0
- package/lib/typescript/themes.d.ts +15 -0
- package/lib/typescript/themes.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +194 -24
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/use-board-gesture.d.ts +28 -2
- package/lib/typescript/use-board-gesture.d.ts.map +1 -1
- package/lib/typescript/use-premove.d.ts +31 -0
- package/lib/typescript/use-premove.d.ts.map +1 -0
- package/package.json +4 -2
- package/src/board-annotations.tsx +147 -0
- package/src/board-arrows.tsx +197 -0
- package/src/board-highlights.tsx +226 -0
- package/src/board-piece.tsx +77 -29
- package/src/board-pieces.tsx +4 -1
- package/src/board.tsx +462 -46
- package/src/constants.ts +100 -0
- package/src/index.ts +62 -1
- package/src/pieces/default-pieces.tsx +383 -0
- package/src/pieces/index.ts +1 -0
- package/src/promotion-picker.tsx +147 -0
- package/src/static-board.tsx +150 -0
- package/src/themes.ts +129 -0
- package/src/types.ts +251 -25
- package/src/use-board-gesture.ts +219 -8
- package/src/use-premove.ts +59 -0
package/src/board-piece.tsx
CHANGED
|
@@ -3,17 +3,24 @@ import Animated, {
|
|
|
3
3
|
useAnimatedStyle,
|
|
4
4
|
useSharedValue,
|
|
5
5
|
withTiming,
|
|
6
|
+
withSpring,
|
|
7
|
+
FadeOut,
|
|
6
8
|
type SharedValue,
|
|
7
9
|
} from 'react-native-reanimated';
|
|
8
10
|
|
|
11
|
+
import type { AnimationConfig } from './types';
|
|
12
|
+
import { DEFAULT_MOVE_DURATION, CAPTURE_FADE_DURATION } from './constants';
|
|
13
|
+
|
|
9
14
|
type BoardPieceProps = {
|
|
10
15
|
/** Target pixel position (top-left of destination square) */
|
|
11
16
|
targetX: number;
|
|
12
17
|
targetY: number;
|
|
13
18
|
/** Square size in pixels */
|
|
14
19
|
squareSize: number;
|
|
15
|
-
/**
|
|
16
|
-
|
|
20
|
+
/** Animation config for piece movement (timing or spring) */
|
|
21
|
+
animationConfig?: AnimationConfig;
|
|
22
|
+
/** Fallback move duration if animationConfig not provided */
|
|
23
|
+
moveDuration?: number;
|
|
17
24
|
/** The piece visual (rendered by parent via renderPiece) */
|
|
18
25
|
children: React.ReactElement;
|
|
19
26
|
/** Gesture state: is this piece currently being dragged? */
|
|
@@ -23,26 +30,62 @@ type BoardPieceProps = {
|
|
|
23
30
|
square: string;
|
|
24
31
|
};
|
|
25
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Animate a shared value using the provided AnimationConfig.
|
|
35
|
+
* Falls back to withTiming with moveDuration for backwards compatibility.
|
|
36
|
+
*/
|
|
37
|
+
function animateValue(
|
|
38
|
+
target: number,
|
|
39
|
+
config?: AnimationConfig,
|
|
40
|
+
moveDuration?: number,
|
|
41
|
+
): number {
|
|
42
|
+
if (config) {
|
|
43
|
+
if (config.type === 'spring') {
|
|
44
|
+
return withSpring(target, {
|
|
45
|
+
damping: config.damping ?? 15,
|
|
46
|
+
stiffness: config.stiffness ?? 200,
|
|
47
|
+
mass: config.mass ?? 1,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// timing
|
|
51
|
+
return withTiming(target, {
|
|
52
|
+
duration: config.duration ?? DEFAULT_MOVE_DURATION,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const duration = moveDuration ?? DEFAULT_MOVE_DURATION;
|
|
57
|
+
if (duration <= 0) return target;
|
|
58
|
+
return withTiming(target, { duration });
|
|
59
|
+
}
|
|
60
|
+
|
|
26
61
|
/**
|
|
27
62
|
* A single animated chess piece.
|
|
28
63
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
64
|
+
* Uses two nested Animated.Views to avoid the Reanimated warning
|
|
65
|
+
* "Property opacity may be overwritten by a layout animation":
|
|
66
|
+
*
|
|
67
|
+
* Outer view: position (transform) + exiting layout animation (FadeOut)
|
|
68
|
+
* Inner view: drag-hide opacity
|
|
69
|
+
*
|
|
70
|
+
* Only `transform` and `opacity` are animated — Reanimated's fast path
|
|
71
|
+
* on Android. No layout properties (top/left/width/height), avoiding
|
|
72
|
+
* costly layout recalculations on low-end devices.
|
|
32
73
|
*
|
|
33
74
|
* During drag:
|
|
34
|
-
* -
|
|
35
|
-
* - No position changes on the original piece during drag
|
|
75
|
+
* - Inner view hides (opacity: 0) — the drag ghost shows instead
|
|
36
76
|
*
|
|
37
77
|
* After a move:
|
|
38
|
-
* -
|
|
39
|
-
*
|
|
78
|
+
* - Outer view snaps to new position via withTiming/withSpring
|
|
79
|
+
*
|
|
80
|
+
* On capture (unmount):
|
|
81
|
+
* - Outer view fades out via exiting FadeOut (no conflict with inner opacity)
|
|
40
82
|
*/
|
|
41
83
|
export const BoardPieceView = React.memo(
|
|
42
84
|
function BoardPieceView({
|
|
43
85
|
targetX,
|
|
44
86
|
targetY,
|
|
45
87
|
squareSize,
|
|
88
|
+
animationConfig,
|
|
46
89
|
moveDuration,
|
|
47
90
|
children,
|
|
48
91
|
activeSquare,
|
|
@@ -57,25 +100,23 @@ export const BoardPieceView = React.memo(
|
|
|
57
100
|
// useEffect is the correct pattern for reacting to JS prop changes —
|
|
58
101
|
// useDerivedValue is meant for shared-value-to-shared-value derivation.
|
|
59
102
|
useEffect(() => {
|
|
60
|
-
currentX.value =
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
currentY.value = moveDuration > 0
|
|
64
|
-
? withTiming(targetY, { duration: moveDuration })
|
|
65
|
-
: targetY;
|
|
66
|
-
}, [targetX, targetY, moveDuration, currentX, currentY]);
|
|
103
|
+
currentX.value = animateValue(targetX, animationConfig, moveDuration);
|
|
104
|
+
currentY.value = animateValue(targetY, animationConfig, moveDuration);
|
|
105
|
+
}, [targetX, targetY, animationConfig, moveDuration, currentX, currentY]);
|
|
67
106
|
|
|
68
|
-
|
|
69
|
-
|
|
107
|
+
// Position style on outer view — no opacity here to avoid conflict
|
|
108
|
+
// with the FadeOut exiting layout animation
|
|
109
|
+
const positionStyle = useAnimatedStyle(() => ({
|
|
110
|
+
transform: [
|
|
111
|
+
{ translateX: currentX.value },
|
|
112
|
+
{ translateY: currentY.value },
|
|
113
|
+
],
|
|
114
|
+
}));
|
|
70
115
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
],
|
|
76
|
-
// Hide original piece during drag — drag ghost renders on top
|
|
77
|
-
opacity: isBeingDragged ? 0 : 1,
|
|
78
|
-
};
|
|
116
|
+
// Drag-hide opacity on inner view — separate from the exiting animation
|
|
117
|
+
const opacityStyle = useAnimatedStyle(() => {
|
|
118
|
+
const isBeingDragged = isDragging.value && activeSquare.value === square;
|
|
119
|
+
return { opacity: isBeingDragged ? 0 : 1 };
|
|
79
120
|
});
|
|
80
121
|
|
|
81
122
|
return (
|
|
@@ -86,19 +127,26 @@ export const BoardPieceView = React.memo(
|
|
|
86
127
|
width: squareSize,
|
|
87
128
|
height: squareSize,
|
|
88
129
|
},
|
|
89
|
-
|
|
130
|
+
positionStyle,
|
|
90
131
|
]}
|
|
132
|
+
// Fade out when this piece is captured (removed from the piece list).
|
|
133
|
+
// Lives on the outer view so it doesn't conflict with the
|
|
134
|
+
// drag-hide opacity on the inner view.
|
|
135
|
+
exiting={FadeOut.duration(CAPTURE_FADE_DURATION)}
|
|
91
136
|
>
|
|
92
|
-
{
|
|
137
|
+
<Animated.View style={[{ flex: 1 }, opacityStyle]}>
|
|
138
|
+
{children}
|
|
139
|
+
</Animated.View>
|
|
93
140
|
</Animated.View>
|
|
94
141
|
);
|
|
95
142
|
},
|
|
96
|
-
// Custom comparator: only re-render when position or
|
|
143
|
+
// Custom comparator: only re-render when position, square, or animation config changes
|
|
97
144
|
(prev, next) =>
|
|
98
145
|
prev.targetX === next.targetX &&
|
|
99
146
|
prev.targetY === next.targetY &&
|
|
100
147
|
prev.square === next.square &&
|
|
101
148
|
prev.squareSize === next.squareSize &&
|
|
102
149
|
prev.moveDuration === next.moveDuration &&
|
|
150
|
+
prev.animationConfig === next.animationConfig &&
|
|
103
151
|
prev.children === next.children,
|
|
104
152
|
);
|
package/src/board-pieces.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { SharedValue } from 'react-native-reanimated';
|
|
3
3
|
|
|
4
|
-
import type { ChessColor, BoardPiece } from './types';
|
|
4
|
+
import type { ChessColor, BoardPiece, AnimationConfig } from './types';
|
|
5
5
|
import { BoardPieceView } from './board-piece';
|
|
6
6
|
import { squareToXY } from './use-board-pieces';
|
|
7
7
|
|
|
@@ -10,6 +10,7 @@ type BoardPiecesProps = {
|
|
|
10
10
|
squareSize: number;
|
|
11
11
|
orientation: ChessColor;
|
|
12
12
|
moveDuration: number;
|
|
13
|
+
animationConfig?: AnimationConfig;
|
|
13
14
|
renderPiece: (code: string, size: number) => React.ReactElement;
|
|
14
15
|
activeSquare: SharedValue<string | null>;
|
|
15
16
|
isDragging: SharedValue<boolean>;
|
|
@@ -27,6 +28,7 @@ export const BoardPiecesLayer = React.memo(function BoardPiecesLayer({
|
|
|
27
28
|
squareSize,
|
|
28
29
|
orientation,
|
|
29
30
|
moveDuration,
|
|
31
|
+
animationConfig,
|
|
30
32
|
renderPiece,
|
|
31
33
|
activeSquare,
|
|
32
34
|
isDragging,
|
|
@@ -43,6 +45,7 @@ export const BoardPiecesLayer = React.memo(function BoardPiecesLayer({
|
|
|
43
45
|
targetY={y}
|
|
44
46
|
squareSize={squareSize}
|
|
45
47
|
moveDuration={moveDuration}
|
|
48
|
+
animationConfig={animationConfig}
|
|
46
49
|
activeSquare={activeSquare}
|
|
47
50
|
isDragging={isDragging}
|
|
48
51
|
square={piece.square}
|