kokopu-react 3.3.5 → 3.4.0
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/CHANGELOG.md +4 -0
- package/CREDITS.md +5 -1
- package/dist/lib/chessboard/BoardProperties.d.ts +4 -0
- package/dist/lib/chessboard/BoardProperties.js +1 -0
- package/dist/lib/chessboard/BoardProperties.js.map +1 -1
- package/dist/lib/chessboard/Chessboard.js +2 -1
- package/dist/lib/chessboard/Chessboard.js.map +1 -1
- package/dist/lib/chessboard/ChessboardImpl.d.ts +1 -0
- package/dist/lib/chessboard/ChessboardImpl.js +3 -1
- package/dist/lib/chessboard/ChessboardImpl.js.map +1 -1
- package/dist/lib/chessboard/Sound.d.ts +29 -0
- package/dist/lib/chessboard/Sound.js +53 -0
- package/dist/lib/chessboard/Sound.js.map +1 -0
- package/dist/lib/chessboard/sounds/move.ogg +0 -0
- package/dist/lib/navigationboard/NavigationBoard.d.ts +1 -0
- package/dist/lib/navigationboard/NavigationBoard.js +1 -1
- package/dist/lib/navigationboard/NavigationBoard.js.map +1 -1
- package/doc_src/demo/NavigationBoardWithMoveText.txt +1 -1
- package/doc_src/demo/PageChessboardMove.tsx +8 -0
- package/doc_src/demo/PageMovetextInteraction.tsx +1 -1
- package/doc_src/demo/PageNavigationBoardBase.tsx +11 -1
- package/doc_src/demo/PageNavigationBoardUncontrolledVsControlled.tsx +4 -2
- package/doc_src/demo/PageSynchroNavigationBoardMovetext.tsx +1 -1
- package/doc_src/webpack_configuration.md +2 -1
- package/package.json +7 -7
- package/scripts/doc.styleguide.config.js +1 -1
- package/scripts/doc.tsconfig.json +1 -1
- package/scripts/test-graphic.webpack.config.js +1 -1
- package/scripts/test-headless.webpack.config.js +1 -1
- package/src/chessboard/BoardProperties.ts +6 -0
- package/src/chessboard/Chessboard.tsx +2 -1
- package/src/chessboard/ChessboardImpl.tsx +3 -0
- package/src/chessboard/Sound.tsx +71 -0
- package/src/chessboard/sounds/move.ogg +0 -0
- package/src/decs.d.ts +5 -0
- package/src/navigationboard/NavigationBoard.tsx +1 -1
- package/test/06_chessboard_animation.js +21 -3
- package/test/common/graphic.js +9 -0
- package/test/graphic_references/06_chessboard_animation/sound/with_move.png +0 -0
- package/test/graphic_references/06_chessboard_animation/sound/without_move.png +0 -0
- package/test/graphic_test_app/05_chessboard_graphic/annotations.tsx +4 -4
- package/test/graphic_test_app/05_chessboard_graphic/base.tsx +1 -1
- package/test/graphic_test_app/05_chessboard_graphic/flipped.tsx +5 -5
- package/test/graphic_test_app/05_chessboard_graphic/move.tsx +2 -2
- package/test/graphic_test_app/05_chessboard_graphic/theme.tsx +3 -3
- package/test/graphic_test_app/06_chessboard_animation/base_1.tsx +6 -6
- package/test/graphic_test_app/06_chessboard_animation/base_2.tsx +6 -6
- package/test/graphic_test_app/06_chessboard_animation/base_3.tsx +6 -6
- package/test/graphic_test_app/06_chessboard_animation/on_redraw.tsx +3 -2
- package/test/graphic_test_app/06_chessboard_animation/sound.tsx +52 -0
- package/test/graphic_test_app/14_navigation_board_autoplay/controlled.tsx +1 -1
- package/test/graphic_test_app/common/test_app.tsx +5 -4
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Kokopu-React is not a "pure" JavaScript/TypeScript library, in that it is shipped with other type of files:
|
|
2
2
|
- `*.css` files (stylesheets),
|
|
3
|
+
- `*.ogg` files (sounds),
|
|
3
4
|
- `*.png` files (images),
|
|
4
5
|
- `*.woff` and `*.woff2` files (fonts).
|
|
5
6
|
|
|
@@ -17,7 +18,7 @@ module.exports = {
|
|
|
17
18
|
// ... or any other configuration that loads the matching files as global CSS.
|
|
18
19
|
},
|
|
19
20
|
{
|
|
20
|
-
test: /\.(png|woff|woff2)$/i,
|
|
21
|
+
test: /\.(ogg|png|woff|woff2)$/i,
|
|
21
22
|
type: 'asset/resource',
|
|
22
23
|
// ... or any other configuration that loads the matching files as resources.
|
|
23
24
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kokopu-react",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "A React-based library to create and display chessboard and chess-related components.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chess",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
"@emotion/react": "^11.14.0",
|
|
49
49
|
"@emotion/styled": "^11.14.1",
|
|
50
50
|
"@eslint/js": "^9.39.2",
|
|
51
|
-
"@mui/material": "^7.3.
|
|
52
|
-
"@stylistic/eslint-plugin": "^5.
|
|
53
|
-
"@types/react": "^19.2.
|
|
51
|
+
"@mui/material": "^7.3.7",
|
|
52
|
+
"@stylistic/eslint-plugin": "^5.7.0",
|
|
53
|
+
"@types/react": "^19.2.8",
|
|
54
54
|
"@types/react-dom": "^19.2.3",
|
|
55
55
|
"babel-loader": "^10.0.0",
|
|
56
56
|
"copy-webpack-plugin": "^13.0.1",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"eslint": "^9.39.2",
|
|
61
61
|
"eslint-plugin-react": "^7.37.5",
|
|
62
62
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
63
|
-
"globals": "^
|
|
63
|
+
"globals": "^17.0.0",
|
|
64
64
|
"html-webpack-plugin": "^5.6.5",
|
|
65
65
|
"img-diff-js": "^0.5.4",
|
|
66
66
|
"kokopu": "^4.13.1",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"style-loader": "^4.0.0",
|
|
78
78
|
"ts-loader": "^9.5.4",
|
|
79
79
|
"typescript": "^5.9.3",
|
|
80
|
-
"typescript-eslint": "^8.
|
|
80
|
+
"typescript-eslint": "^8.52.0",
|
|
81
81
|
"unit.js": "^2.1.1",
|
|
82
82
|
"webpack": "^5.104.1",
|
|
83
83
|
"webpack-cli": "^6.0.1"
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"test_env:stop": "docker compose -p kokopu-react-test-env -f scripts/docker-compose.yml down",
|
|
95
95
|
"build": "npm run build:lib && npm run build:doc",
|
|
96
96
|
"build:doc": "rimraf dist/docs && styleguidist build --config scripts/doc.styleguide.config.js && copyfiles -u 2 'doc_src/theming/*.png' dist/docs",
|
|
97
|
-
"build:lib": "rimraf dist/lib && tsc --outDir dist/lib && copyfiles -u 1 'src/**/*.{css,png,woff,woff2}' dist/lib",
|
|
97
|
+
"build:lib": "rimraf dist/lib && tsc --outDir dist/lib && copyfiles -u 1 'src/**/*.{css,ogg,png,woff,woff2}' dist/lib",
|
|
98
98
|
"start": "styleguidist server --open --config scripts/doc.styleguide.config.js",
|
|
99
99
|
"clean": "rimraf build dist"
|
|
100
100
|
}
|
|
@@ -104,6 +104,11 @@ export interface DynamicBoardGraphicProps extends StaticBoardGraphicProps {
|
|
|
104
104
|
* Whether moves are animated or not.
|
|
105
105
|
*/
|
|
106
106
|
animated: boolean,
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Whether sound effects are enabled or not.
|
|
110
|
+
*/
|
|
111
|
+
sound: boolean,
|
|
107
112
|
}
|
|
108
113
|
|
|
109
114
|
|
|
@@ -127,5 +132,6 @@ export function defaultDynamicBoardProps(): DynamicBoardGraphicProps {
|
|
|
127
132
|
moveArrowVisible: true,
|
|
128
133
|
moveArrowColor: 'b',
|
|
129
134
|
animated: false,
|
|
135
|
+
sound: false,
|
|
130
136
|
};
|
|
131
137
|
}
|
|
@@ -228,6 +228,7 @@ export class Chessboard extends React.Component<ChessboardProps, ChessboardState
|
|
|
228
228
|
throw new IllegalArgument('Chessboard', 'moveArrowColor');
|
|
229
229
|
}
|
|
230
230
|
const animated = sanitizeBoolean(this.props.animated);
|
|
231
|
+
const sound = sanitizeBoolean(this.props.sound);
|
|
231
232
|
const colorset = colorsets[this.props.colorset];
|
|
232
233
|
if (!colorset) {
|
|
233
234
|
throw new IllegalArgument('Chessboard', 'colorset');
|
|
@@ -263,7 +264,7 @@ export class Chessboard extends React.Component<ChessboardProps, ChessboardState
|
|
|
263
264
|
key={key}
|
|
264
265
|
position={position} move={move} squareMarkers={sqm} textMarkers={txtm} arrowMarkers={arm} flipped={flipped}
|
|
265
266
|
squareSize={actualSquareSize} coordinateVisible={actualCoordinateVisible} turnVisible={actualTurnVisible}
|
|
266
|
-
moveArrowVisible={moveArrowVisible} moveArrowColor={this.props.moveArrowColor} animated={animated}
|
|
267
|
+
moveArrowVisible={moveArrowVisible} moveArrowColor={this.props.moveArrowColor} animated={animated} sound={sound}
|
|
267
268
|
colorset={colorset} pieceset={pieceset}
|
|
268
269
|
interactionMode={interactionMode} editedArrowColor={this.props.editedArrowColor}
|
|
269
270
|
onPieceMoved={onPieceMoved} onSquareClicked={onSquareClicked} onArrowEdited={onArrowEdited} onMovePlayed={onMovePlayed}
|
|
@@ -33,6 +33,7 @@ import { AnnotationSymbolShape } from '../icons/AnnotationSymbolShape';
|
|
|
33
33
|
import { ArrowTip } from '../icons/ArrowTip';
|
|
34
34
|
import { Draggable } from './Draggable';
|
|
35
35
|
import { Motion } from './Motion';
|
|
36
|
+
import { Sound } from './Sound';
|
|
36
37
|
|
|
37
38
|
import '../icons/arrow.css';
|
|
38
39
|
import './Chessboard.css';
|
|
@@ -66,6 +67,7 @@ interface ChessboardImplProps {
|
|
|
66
67
|
moveArrowVisible: boolean,
|
|
67
68
|
moveArrowColor: AnnotationColor,
|
|
68
69
|
animated: boolean,
|
|
70
|
+
sound: boolean,
|
|
69
71
|
colorset: Colorset,
|
|
70
72
|
pieceset: Pieceset,
|
|
71
73
|
|
|
@@ -145,6 +147,7 @@ export class ChessboardImpl extends React.Component<ChessboardImplProps, Chessbo
|
|
|
145
147
|
{rankCoordinates}
|
|
146
148
|
{fileCoordinates}
|
|
147
149
|
{this.renderBoardContent()}
|
|
150
|
+
{this.props.move && this.props.sound ? <Sound /> : undefined}
|
|
148
151
|
</svg>
|
|
149
152
|
);
|
|
150
153
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* -------------------------------------------------------------------------- *
|
|
3
|
+
* *
|
|
4
|
+
* Kokopu-React - A React-based library of chess-related components. *
|
|
5
|
+
* <https://www.npmjs.com/package/kokopu-react> *
|
|
6
|
+
* Copyright (C) 2021-2026 Yoann Le Montagner <yo35 -at- melix.net> *
|
|
7
|
+
* *
|
|
8
|
+
* Kokopu-React is free software: you can redistribute it and/or *
|
|
9
|
+
* modify it under the terms of the GNU Lesser General Public License *
|
|
10
|
+
* as published by the Free Software Foundation, either version 3 of *
|
|
11
|
+
* the License, or (at your option) any later version. *
|
|
12
|
+
* *
|
|
13
|
+
* Kokopu-React is distributed in the hope that it will be useful, *
|
|
14
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
15
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
16
|
+
* GNU Lesser General Public License for more details. *
|
|
17
|
+
* *
|
|
18
|
+
* You should have received a copy of the GNU Lesser General *
|
|
19
|
+
* Public License along with this program. If not, see *
|
|
20
|
+
* <http://www.gnu.org/licenses/>. *
|
|
21
|
+
* *
|
|
22
|
+
* -------------------------------------------------------------------------- */
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
import * as React from 'react';
|
|
26
|
+
|
|
27
|
+
import moveSound from './sounds/move.ogg';
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Play a sound.
|
|
32
|
+
*/
|
|
33
|
+
export function Sound() {
|
|
34
|
+
|
|
35
|
+
React.useEffect(() => {
|
|
36
|
+
const audio = new Audio(moveSound);
|
|
37
|
+
safePlay(audio);
|
|
38
|
+
return () => audio.pause();
|
|
39
|
+
}, []);
|
|
40
|
+
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
declare global {
|
|
46
|
+
|
|
47
|
+
// WARNING: this global variable exists only for testing purposes. DO NOT USE IT IN PRODUCTION.
|
|
48
|
+
var __kokopu_debug_sound: string; // eslint-disable-line camelcase
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
async function safePlay(audio: HTMLAudioElement) {
|
|
53
|
+
try {
|
|
54
|
+
|
|
55
|
+
const debugSound = window.__kokopu_debug_sound === '';
|
|
56
|
+
// istanbul ignore else
|
|
57
|
+
if (debugSound) {
|
|
58
|
+
window['__kokopu_debug_sound'] = 'sound-in-progress';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
await audio.play();
|
|
62
|
+
|
|
63
|
+
// istanbul ignore else
|
|
64
|
+
if (debugSound) {
|
|
65
|
+
window['__kokopu_debug_sound'] = 'sound-done';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (e) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
69
|
+
// Ignore the errors (can typically happen if the audio is interrupted while fetching the sound file).
|
|
70
|
+
}
|
|
71
|
+
}
|
|
Binary file
|
package/src/decs.d.ts
CHANGED
|
@@ -242,7 +242,7 @@ export class NavigationBoard extends React.Component<NavigationBoardProps, Navig
|
|
|
242
242
|
smallScreenLimits={this.props.smallScreenLimits}
|
|
243
243
|
moveArrowVisible={this.props.moveArrowVisible}
|
|
244
244
|
moveArrowColor={this.props.moveArrowColor}
|
|
245
|
-
animated={this.props.animated}
|
|
245
|
+
animated={this.props.animated} sound={this.props.sound}
|
|
246
246
|
bottomComponent={({ squareSize }) => this.renderToolbar(game, node, squareSize, isPlaying)}
|
|
247
247
|
/>
|
|
248
248
|
);
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
* -------------------------------------------------------------------------- */
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
const { describeWithBrowser, itChecksScreenshots, itCustom, takeScreenshot, compareScreenshot, waitForAnimation
|
|
25
|
+
const { describeWithBrowser, itChecksScreenshots, itCustom, takeScreenshot, compareScreenshot, waitForAnimation,
|
|
26
|
+
compareGlobalVar } = require('./common/graphic');
|
|
26
27
|
const { By } = require('selenium-webdriver');
|
|
27
28
|
|
|
28
29
|
|
|
@@ -55,17 +56,34 @@ describeWithBrowser('Chessboard animation', browserContext => {
|
|
|
55
56
|
'promotion',
|
|
56
57
|
]);
|
|
57
58
|
|
|
59
|
+
async function runSoundTestScenario(element, withMove) {
|
|
60
|
+
|
|
61
|
+
// Run the scenario.
|
|
62
|
+
const actions = browserContext.driver.actions({ async: true });
|
|
63
|
+
const button = await element.findElement(By.id(`chessboard-actionButton-${withMove ? 'withMove' : 'noMove'}`));
|
|
64
|
+
await actions.move({ origin: button }).click().perform();
|
|
65
|
+
await waitForAnimation();
|
|
66
|
+
await takeScreenshot(browserContext, withMove ? 'with move' : 'without move', element);
|
|
67
|
+
|
|
68
|
+
// Validate the scenario.
|
|
69
|
+
await compareGlobalVar(browserContext, '__kokopu_debug_sound', withMove ? 'sound-done' : '');
|
|
70
|
+
await compareScreenshot(browserContext, withMove ? 'with move' : 'without move');
|
|
71
|
+
}
|
|
72
|
+
itCustom(browserContext, '06_chessboard_animation/sound', 0, 'without move', async element => await runSoundTestScenario(element, false));
|
|
73
|
+
itCustom(browserContext, '06_chessboard_animation/sound', 1, 'with move', async element => await runSoundTestScenario(element, true));
|
|
74
|
+
|
|
58
75
|
itCustom(browserContext, '06_chessboard_animation/on_redraw', 0, 'default', async element => {
|
|
59
76
|
|
|
60
77
|
// Run the scenario.
|
|
61
78
|
await takeScreenshot(browserContext, 'initial state', element);
|
|
62
79
|
const actions = browserContext.driver.actions({ async: true });
|
|
63
|
-
const button = await element.findElement(By.id('chessboard-
|
|
80
|
+
const button = await element.findElement(By.id('chessboard-actionButton'));
|
|
64
81
|
await actions.move({ origin: button }).click().perform();
|
|
65
82
|
await waitForAnimation();
|
|
66
83
|
await takeScreenshot(browserContext, 'final state', element);
|
|
67
84
|
|
|
68
|
-
//
|
|
85
|
+
// Validate the scenario.
|
|
86
|
+
await compareGlobalVar(browserContext, '__kokopu_debug_sound', 'sound-done');
|
|
69
87
|
await compareScreenshot(browserContext, 'initial state');
|
|
70
88
|
await compareScreenshot(browserContext, 'final state');
|
|
71
89
|
});
|
package/test/common/graphic.js
CHANGED
|
@@ -224,6 +224,15 @@ exports.setSandbox = async function (browserContext, value) {
|
|
|
224
224
|
};
|
|
225
225
|
|
|
226
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Compare the value of the given global variable to the expected value.
|
|
229
|
+
*/
|
|
230
|
+
exports.compareGlobalVar = async function (browserContext, variableName, expectedValue) {
|
|
231
|
+
const actualValue = await browserContext.driver.executeScript(`return window["${variableName}"];`);
|
|
232
|
+
test.value(actualValue).is(expectedValue);
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
|
|
227
236
|
/**
|
|
228
237
|
* Set the width of the browser.
|
|
229
238
|
*/
|
|
@@ -48,15 +48,15 @@ const arrowMarkers3 = { d1h5: G, a5f4: R, c7c3: Y, g7g7: G };
|
|
|
48
48
|
const textMarkers3 = 'G5c6,R(plus)a1,G(times)b1,B(dot)a2,Y(circle)b2';
|
|
49
49
|
|
|
50
50
|
testApp([ /* eslint-disable react/jsx-key */
|
|
51
|
-
<Chessboard squareMarkers={squareMarkers1} arrowMarkers={arrowMarkers1} textMarkers={textMarkers1} flipped={false} coordinateVisible
|
|
52
|
-
<Chessboard squareMarkers={squareMarkers1} arrowMarkers={arrowMarkers1} textMarkers={textMarkers1} flipped
|
|
51
|
+
<Chessboard squareMarkers={squareMarkers1} arrowMarkers={arrowMarkers1} textMarkers={textMarkers1} flipped={false} coordinateVisible />,
|
|
52
|
+
<Chessboard squareMarkers={squareMarkers1} arrowMarkers={arrowMarkers1} textMarkers={textMarkers1} flipped coordinateVisible />,
|
|
53
53
|
<Chessboard squareMarkers={squareMarkers2} arrowMarkers={arrowMarkers2} textMarkers={textMarkers2} flipped={false} coordinateVisible={false} />,
|
|
54
|
-
<Chessboard squareMarkers={squareMarkers2} arrowMarkers={arrowMarkers2} textMarkers={textMarkers2} flipped
|
|
54
|
+
<Chessboard squareMarkers={squareMarkers2} arrowMarkers={arrowMarkers2} textMarkers={textMarkers2} flipped coordinateVisible={false} />,
|
|
55
55
|
<Chessboard
|
|
56
56
|
squareMarkers={squareMarkers3} arrowMarkers={arrowMarkers3} textMarkers={textMarkers3} flipped={false} coordinateVisible={false} position="empty"
|
|
57
57
|
/>,
|
|
58
58
|
<Chessboard
|
|
59
|
-
squareMarkers={squareMarkers3} arrowMarkers={arrowMarkers3} textMarkers={textMarkers3} flipped
|
|
59
|
+
squareMarkers={squareMarkers3} arrowMarkers={arrowMarkers3} textMarkers={textMarkers3} flipped coordinateVisible
|
|
60
60
|
position="8/8/1r6/8/5k1K/8/8/8 b - - 0 1"
|
|
61
61
|
/>,
|
|
62
62
|
]); /* eslint-enable react/jsx-key */
|
|
@@ -29,7 +29,7 @@ import { Chessboard } from '../../../dist/lib/index';
|
|
|
29
29
|
|
|
30
30
|
testApp([ /* eslint-disable react/jsx-key */
|
|
31
31
|
<Chessboard />,
|
|
32
|
-
<Chessboard position="empty" turnVisible
|
|
32
|
+
<Chessboard position="empty" turnVisible />,
|
|
33
33
|
<Chessboard position="something invalid" />,
|
|
34
34
|
<Chessboard position="r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 3 3" turnVisible={false} />,
|
|
35
35
|
<Chessboard position={new Position('8/8/1r6/8/5k1K/8/8/8 b - - 0 1')} />,
|
|
@@ -28,9 +28,9 @@ import { testApp } from '../common/test_app';
|
|
|
28
28
|
import { Chessboard } from '../../../dist/lib/index';
|
|
29
29
|
|
|
30
30
|
testApp([ /* eslint-disable react/jsx-key */
|
|
31
|
-
<Chessboard flipped
|
|
32
|
-
<Chessboard flipped
|
|
33
|
-
<Chessboard flipped
|
|
34
|
-
<Chessboard flipped
|
|
35
|
-
<Chessboard flipped
|
|
31
|
+
<Chessboard flipped turnVisible={false} />,
|
|
32
|
+
<Chessboard flipped position="empty" />,
|
|
33
|
+
<Chessboard flipped position="something invalid" />,
|
|
34
|
+
<Chessboard flipped position="r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 3 3" />,
|
|
35
|
+
<Chessboard flipped position={new Position('8/8/1r6/8/5k1K/8/8/8 b - - 0 1')} turnVisible />,
|
|
36
36
|
]); /* eslint-enable react/jsx-key */
|
|
@@ -34,8 +34,8 @@ testApp([ /* eslint-disable react/jsx-key */
|
|
|
34
34
|
<Chessboard move="e4" animated={false} />,
|
|
35
35
|
<Chessboard move="Nf3" moveArrowVisible={false} animated={false} />,
|
|
36
36
|
<Chessboard move="Nf4" animated={false} />,
|
|
37
|
-
<Chessboard position="rnbqkbnr/pppp1ppp/4p3/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq - 0 2" move="Bb4+" moveArrowVisible
|
|
38
|
-
<Chessboard position={pos} move={move} animated
|
|
37
|
+
<Chessboard position="rnbqkbnr/pppp1ppp/4p3/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq - 0 2" move="Bb4+" moveArrowVisible flipped animated />,
|
|
38
|
+
<Chessboard position={pos} move={move} animated moveArrowColor="g" />,
|
|
39
39
|
<Chessboard position="r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R3K2R b KQkq - 0 1" move="O-O-O" animated={false} moveArrowColor="r" />,
|
|
40
40
|
<Chessboard position="rnbqkbnr/ppp1p1pp/8/3pPp2/8/8/PPPP1PPP/RNBQKBNR w KQkq f6 0 3" move="exf6" animated={false} moveArrowColor="y" />,
|
|
41
41
|
<Chessboard position="8/8/8/1K6/8/4k3/1p6/8 b - - 0 1" move="b1=R+" animated={false} moveArrowColor="b" />,
|
|
@@ -38,12 +38,12 @@ const am = 'Ba1a3,Gb1b3,Rc1c3,Yd1d3';
|
|
|
38
38
|
testApp([ /* eslint-disable react/jsx-key */
|
|
39
39
|
<Chessboard position={pos1} move={mv1} squareMarkers={sm} arrowMarkers={am} animated={false} />,
|
|
40
40
|
<Chessboard position={pos2} move={mv2} squareMarkers={sm} arrowMarkers={am} squareSize={60} animated={false} />,
|
|
41
|
-
<Chessboard position={pos1} move={mv1} squareMarkers={sm} arrowMarkers={am} squareSize={29} coordinateVisible={false} flipped
|
|
42
|
-
<Chessboard position={pos1} move={mv1} squareMarkers={sm} arrowMarkers={am} squareSize={47} coordinateVisible
|
|
41
|
+
<Chessboard position={pos1} move={mv1} squareMarkers={sm} arrowMarkers={am} squareSize={29} coordinateVisible={false} flipped animated={false} />,
|
|
42
|
+
<Chessboard position={pos1} move={mv1} squareMarkers={sm} arrowMarkers={am} squareSize={47} coordinateVisible flipped colorset="scid" animated={false} />,
|
|
43
43
|
<Chessboard position={pos2} move={mv2} squareMarkers={sm} arrowMarkers={am} coordinateVisible={false} colorset="marine" pieceset="eyes" animated={false} />,
|
|
44
44
|
<Chessboard position={pos1} move={mv1} squareMarkers={sm} arrowMarkers={am} coordinateVisible={false} pieceset="fantasy" animated={false} />,
|
|
45
45
|
<Chessboard position={pos1} move={mv1} squareMarkers={sm} arrowMarkers={am} colorset="emerald" pieceset="skulls" animated={false} />,
|
|
46
|
-
<Chessboard position={pos2} move={mv2} squareMarkers={sm} arrowMarkers={am} squareSize={91} flipped
|
|
46
|
+
<Chessboard position={pos2} move={mv2} squareMarkers={sm} arrowMarkers={am} squareSize={91} flipped colorset="gray" pieceset="spatial" animated={false} />,
|
|
47
47
|
<Chessboard position={pos1} move={mv1} squareMarkers={sm} arrowMarkers={am} squareSize={17} colorset="dusk" animated={false} />,
|
|
48
48
|
<Chessboard squareSize={/* eslint-disable @typescript-eslint/no-explicit-any */ '24' as any /* eslint-enable @typescript-eslint/no-explicit-any */} />,
|
|
49
49
|
<Chessboard colorset="not-a-colorset" />,
|
|
@@ -29,10 +29,10 @@ import { Chessboard } from '../../../dist/lib/index';
|
|
|
29
29
|
window['__kokopu_debug_freeze_motion'] = 0.09;
|
|
30
30
|
|
|
31
31
|
testApp([ /* eslint-disable react/jsx-key */
|
|
32
|
-
<Chessboard move="e4" animated
|
|
33
|
-
<Chessboard move="Nf3" animated
|
|
34
|
-
<Chessboard position="r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2" move="Bxa6" animated
|
|
35
|
-
<Chessboard position="r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R3K2R b KQkq - 0 1" move="O-O-O" animated
|
|
36
|
-
<Chessboard position="rnbqkbnr/ppp1p1pp/8/3pPp2/8/8/PPPP1PPP/RNBQKBNR w KQkq f6 0 3" move="exf6" animated
|
|
37
|
-
<Chessboard position="8/8/8/1K6/8/4k3/1p6/8 b - - 0 1" move="b1=R+" animated
|
|
32
|
+
<Chessboard move="e4" animated />,
|
|
33
|
+
<Chessboard move="Nf3" animated moveArrowVisible={false} />,
|
|
34
|
+
<Chessboard position="r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2" move="Bxa6" animated flipped turnVisible={false} />,
|
|
35
|
+
<Chessboard position="r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R3K2R b KQkq - 0 1" move="O-O-O" animated />,
|
|
36
|
+
<Chessboard position="rnbqkbnr/ppp1p1pp/8/3pPp2/8/8/PPPP1PPP/RNBQKBNR w KQkq f6 0 3" move="exf6" animated />,
|
|
37
|
+
<Chessboard position="8/8/8/1K6/8/4k3/1p6/8 b - - 0 1" move="b1=R+" animated turnVisible={false} />,
|
|
38
38
|
]); /* eslint-enable react/jsx-key */
|
|
@@ -29,10 +29,10 @@ import { Chessboard } from '../../../dist/lib/index';
|
|
|
29
29
|
window['__kokopu_debug_freeze_motion'] = 0.7;
|
|
30
30
|
|
|
31
31
|
testApp([ /* eslint-disable react/jsx-key */
|
|
32
|
-
<Chessboard move="e4" animated
|
|
33
|
-
<Chessboard move="Nf3" animated
|
|
34
|
-
<Chessboard position="r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2" move="Bxa6" animated
|
|
35
|
-
<Chessboard position="r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R3K2R b KQkq - 0 1" move="O-O-O" animated
|
|
36
|
-
<Chessboard position="rnbqkbnr/ppp1p1pp/8/3pPp2/8/8/PPPP1PPP/RNBQKBNR w KQkq f6 0 3" move="exf6" animated
|
|
37
|
-
<Chessboard position="8/8/8/1K6/8/4k3/1p6/8 b - - 0 1" move="b1=R+" animated
|
|
32
|
+
<Chessboard move="e4" animated />,
|
|
33
|
+
<Chessboard move="Nf3" animated moveArrowVisible={false} />,
|
|
34
|
+
<Chessboard position="r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2" move="Bxa6" animated flipped turnVisible={false} />,
|
|
35
|
+
<Chessboard position="r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R3K2R b KQkq - 0 1" move="O-O-O" animated />,
|
|
36
|
+
<Chessboard position="rnbqkbnr/ppp1p1pp/8/3pPp2/8/8/PPPP1PPP/RNBQKBNR w KQkq f6 0 3" move="exf6" animated />,
|
|
37
|
+
<Chessboard position="8/8/8/1K6/8/4k3/1p6/8 b - - 0 1" move="b1=R+" animated turnVisible={false} />,
|
|
38
38
|
]); /* eslint-enable react/jsx-key */
|
|
@@ -29,10 +29,10 @@ import { Chessboard } from '../../../dist/lib/index';
|
|
|
29
29
|
window['__kokopu_debug_freeze_motion'] = 0.91;
|
|
30
30
|
|
|
31
31
|
testApp([ /* eslint-disable react/jsx-key */
|
|
32
|
-
<Chessboard move="e4" animated
|
|
33
|
-
<Chessboard move="Nf3" animated
|
|
34
|
-
<Chessboard position="r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2" move="Bxa6" animated
|
|
35
|
-
<Chessboard position="r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R3K2R b KQkq - 0 1" move="O-O-O" animated
|
|
36
|
-
<Chessboard position="rnbqkbnr/ppp1p1pp/8/3pPp2/8/8/PPPP1PPP/RNBQKBNR w KQkq f6 0 3" move="exf6" animated
|
|
37
|
-
<Chessboard position="8/8/8/1K6/8/4k3/1p6/8 b - - 0 1" move="b1=R+" animated
|
|
32
|
+
<Chessboard move="e4" animated />,
|
|
33
|
+
<Chessboard move="Nf3" animated moveArrowVisible={false} />,
|
|
34
|
+
<Chessboard position="r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2" move="Bxa6" animated flipped turnVisible={false} />,
|
|
35
|
+
<Chessboard position="r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R3K2R b KQkq - 0 1" move="O-O-O" animated />,
|
|
36
|
+
<Chessboard position="rnbqkbnr/ppp1p1pp/8/3pPp2/8/8/PPPP1PPP/RNBQKBNR w KQkq f6 0 3" move="exf6" animated />,
|
|
37
|
+
<Chessboard position="8/8/8/1K6/8/4k3/1p6/8 b - - 0 1" move="b1=R+" animated turnVisible={false} />,
|
|
38
38
|
]); /* eslint-enable react/jsx-key */
|
|
@@ -34,15 +34,16 @@ function TestComponent() {
|
|
|
34
34
|
|
|
35
35
|
function onClick() {
|
|
36
36
|
window['__kokopu_debug_freeze_motion'] = 0.6;
|
|
37
|
+
window['__kokopu_debug_sound'] = '';
|
|
37
38
|
setClicked(true);
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
return (
|
|
41
42
|
<>
|
|
42
43
|
<div>
|
|
43
|
-
<Chessboard position={position} move={move} animated
|
|
44
|
+
<Chessboard position={position} move={move} animated sound />
|
|
44
45
|
</div>
|
|
45
|
-
{clicked ? undefined : <button id="chessboard-
|
|
46
|
+
{clicked ? undefined : <button id="chessboard-actionButton" onClick={onClick}>Click here</button>}
|
|
46
47
|
</>
|
|
47
48
|
);
|
|
48
49
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* -------------------------------------------------------------------------- *
|
|
3
|
+
* *
|
|
4
|
+
* Kokopu-React - A React-based library of chess-related components. *
|
|
5
|
+
* <https://www.npmjs.com/package/kokopu-react> *
|
|
6
|
+
* Copyright (C) 2021-2026 Yoann Le Montagner <yo35 -at- melix.net> *
|
|
7
|
+
* *
|
|
8
|
+
* Kokopu-React is free software: you can redistribute it and/or *
|
|
9
|
+
* modify it under the terms of the GNU Lesser General Public License *
|
|
10
|
+
* as published by the Free Software Foundation, either version 3 of *
|
|
11
|
+
* the License, or (at your option) any later version. *
|
|
12
|
+
* *
|
|
13
|
+
* Kokopu-React is distributed in the hope that it will be useful, *
|
|
14
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
15
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
16
|
+
* GNU Lesser General Public License for more details. *
|
|
17
|
+
* *
|
|
18
|
+
* You should have received a copy of the GNU Lesser General *
|
|
19
|
+
* Public License along with this program. If not, see *
|
|
20
|
+
* <http://www.gnu.org/licenses/>. *
|
|
21
|
+
* *
|
|
22
|
+
* -------------------------------------------------------------------------- */
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
import * as React from 'react';
|
|
26
|
+
import { testApp } from '../common/test_app';
|
|
27
|
+
import { Chessboard } from '../../../dist/lib/index';
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* REMARK: do NOT display the chessboards by default, because:
|
|
32
|
+
* - we want to know which one plays the sound,
|
|
33
|
+
* - there could be some issues with the auto-play policies of browsers.
|
|
34
|
+
*/
|
|
35
|
+
function TestComponent({ move }: { move?: string }) {
|
|
36
|
+
|
|
37
|
+
const [ clicked, setClicked ] = React.useState(false);
|
|
38
|
+
|
|
39
|
+
function onClick() {
|
|
40
|
+
window['__kokopu_debug_sound'] = '';
|
|
41
|
+
setClicked(true);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const id = `chessboard-actionButton-${move === undefined ? 'noMove' : 'withMove'}`;
|
|
45
|
+
return clicked ? <Chessboard move={move} sound /> : <button id={id} onClick={onClick}>Click here</button>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
testApp([ /* eslint-disable react/jsx-key */
|
|
50
|
+
<TestComponent />,
|
|
51
|
+
<TestComponent move="e4" />,
|
|
52
|
+
]); /* eslint-enable react/jsx-key */
|
|
@@ -85,5 +85,5 @@ testApp([ /* eslint-disable react/jsx-key */
|
|
|
85
85
|
}}
|
|
86
86
|
/>,
|
|
87
87
|
<NavigationBoardWithIsPlayingController />,
|
|
88
|
-
<NavigationBoard game={pgn} playButtonVisible initialNodeId="20b" isPlaying
|
|
88
|
+
<NavigationBoard game={pgn} playButtonVisible initialNodeId="20b" isPlaying />,
|
|
89
89
|
]); /* eslint-enable react/jsx-key */
|
|
@@ -28,12 +28,13 @@ import { createRoot } from 'react-dom/client';
|
|
|
28
28
|
import './test_app.css';
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
//
|
|
31
|
+
// These global variables are used for testing purposes.
|
|
32
|
+
/* eslint-disable camelcase */
|
|
32
33
|
declare global {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
34
|
+
var __kokopu_debug_freeze_motion: number;
|
|
35
|
+
var __kokopu_debug_sound: string;
|
|
36
36
|
}
|
|
37
|
+
/* eslint-enable */
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
interface TestItemContainerProps {
|