kokopu-react 2.0.1 → 3.0.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 +12 -0
- package/dist/lib/chessboard/Chessboard.d.ts +7 -2
- package/dist/lib/chessboard/Chessboard.js +43 -21
- package/dist/lib/chessboard/Chessboard.js.map +1 -1
- package/dist/lib/chessboard/ChessboardImpl.d.ts +2 -1
- package/dist/lib/chessboard/ChessboardImpl.js +9 -3
- package/dist/lib/chessboard/ChessboardImpl.js.map +1 -1
- package/dist/lib/chessboard/Draggable.d.ts +7 -1
- package/dist/lib/chessboard/Draggable.js +21 -29
- package/dist/lib/chessboard/Draggable.js.map +1 -1
- package/dist/lib/chessboard/colorsets.d.ts +4 -0
- package/dist/lib/chessboard/colorsets.js +4 -0
- package/dist/lib/chessboard/colorsets.js.map +1 -1
- package/dist/lib/chessboard/piecesets.d.ts +4 -0
- package/dist/lib/chessboard/piecesets.js +4 -0
- package/dist/lib/chessboard/piecesets.js.map +1 -1
- package/dist/lib/icons/ChessPieceIcon.d.ts +23 -0
- package/dist/lib/icons/ChessPieceIcon.js +65 -0
- package/dist/lib/icons/ChessPieceIcon.js.map +1 -0
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +2 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/movetext/Movetext.d.ts +3 -1
- package/dist/lib/movetext/Movetext.js.map +1 -1
- package/dist/lib/movetext/MovetextImpl.d.ts +3 -1
- package/dist/lib/movetext/MovetextImpl.js +15 -14
- package/dist/lib/movetext/MovetextImpl.js.map +1 -1
- package/dist/lib/sanitization.d.ts +1 -0
- package/dist/lib/sanitization.js +11 -0
- package/dist/lib/sanitization.js.map +1 -1
- package/dist/lib/types.d.ts +11 -1
- package/dist/lib/types.js +7 -1
- package/dist/lib/types.js.map +1 -1
- package/doc_src/demo/PageChessboardBase.tsx +7 -0
- package/doc_src/demo/PageChessboardSmallScreens.tsx +10 -3
- package/doc_src/demo/PageMovetextBase.tsx +8 -0
- package/doc_src/examples/ChessPieceIcon.md +3 -0
- package/doc_src/home.md +11 -0
- package/doc_src/migrate_to_3.md +51 -0
- package/package.json +16 -16
- package/scripts/doc.styleguide.config.js +6 -1
- package/scripts/docker-compose.yml +1 -1
- package/src/chessboard/Chessboard.tsx +56 -23
- package/src/chessboard/ChessboardImpl.tsx +10 -3
- package/src/chessboard/Draggable.tsx +22 -41
- package/src/chessboard/colorsets.ts +6 -0
- package/src/chessboard/piecesets.ts +6 -0
- package/src/icons/ChessPieceIcon.tsx +99 -0
- package/src/index.ts +4 -2
- package/src/movetext/Movetext.tsx +3 -1
- package/src/movetext/MovetextImpl.tsx +18 -14
- package/src/sanitization.ts +13 -0
- package/src/types.ts +17 -1
- package/test/02_chessboard_util.js +104 -36
- package/test/{04_marker_icons_graphic.js → 04_icons_graphic.js} +14 -2
- package/test/09_chessboard_small_screens.js +50 -0
- package/test/{09_movetext_graphic.js → 10_movetext_graphic.js} +5 -4
- package/test/{10_movetext_interaction.js → 11_movetext_interaction.js} +38 -14
- package/test/common/graphic.js +9 -0
- package/test/graphic_references/04_icons_graphic/chess_piece/customized_pieceset.png +0 -0
- package/test/graphic_references/04_icons_graphic/chess_piece/multiple_pieces.png +0 -0
- package/test/graphic_references/04_icons_graphic/chess_piece/single_piece.png +0 -0
- package/test/graphic_references/04_icons_graphic/marker/invalid_arrow_size.png +0 -0
- package/test/graphic_references/04_icons_graphic/marker/invalid_square_size.png +0 -0
- package/test/graphic_references/04_icons_graphic/marker/invalid_symbol.png +0 -0
- package/test/graphic_references/04_icons_graphic/marker/invalid_text_size.png +0 -0
- package/test/graphic_references/05_chessboard_graphic/base/from_fen.png +0 -0
- package/test/graphic_references/05_chessboard_graphic/flipped/default.png +0 -0
- package/test/graphic_references/06_chessboard_animation/base_1/capture.png +0 -0
- package/test/graphic_references/06_chessboard_animation/base_1/promotion.png +0 -0
- package/test/graphic_references/06_chessboard_animation/base_2/capture.png +0 -0
- package/test/graphic_references/06_chessboard_animation/base_2/promotion.png +0 -0
- package/test/graphic_references/06_chessboard_animation/base_3/capture.png +0 -0
- package/test/graphic_references/06_chessboard_animation/base_3/promotion.png +0 -0
- package/test/graphic_references/09_chessboard_small_screens/base/default.png +0 -0
- package/test/graphic_references/09_chessboard_small_screens/base/invalid_limits.png +0 -0
- package/test/graphic_references/09_chessboard_small_screens/base/width_690.png +0 -0
- package/test/graphic_references/09_chessboard_small_screens/base/width_700.png +0 -0
- package/test/graphic_references/09_chessboard_small_screens/base/width_710.png +0 -0
- package/test/graphic_references/09_chessboard_small_screens/base/width_720.png +0 -0
- package/test/graphic_references/09_chessboard_small_screens/base/width_730.png +0 -0
- package/test/graphic_references/09_chessboard_small_screens/base/width_740.png +0 -0
- package/test/graphic_references/09_chessboard_small_screens/base/width_750.png +0 -0
- package/test/graphic_references/10_movetext_graphic/options/other_diagram_options.png +0 -0
- package/test/graphic_test_app/04_icons_graphic/chess_piece.tsx +38 -0
- package/test/graphic_test_app/05_chessboard_graphic/base.tsx +2 -2
- package/test/graphic_test_app/05_chessboard_graphic/flipped.tsx +2 -2
- package/test/graphic_test_app/06_chessboard_animation/base_1.tsx +2 -2
- package/test/graphic_test_app/06_chessboard_animation/base_2.tsx +2 -2
- package/test/graphic_test_app/06_chessboard_animation/base_3.tsx +2 -2
- package/test/graphic_test_app/09_chessboard_small_screens/base.tsx +41 -0
- package/test/graphic_test_app/{09_movetext_graphic → 10_movetext_graphic}/options.tsx +1 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base/invalid_symbol.png → 04_icons_graphic/chess_piece/invalid_multiple_pieces.png} +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base/invalid_arrow_size.png → 04_icons_graphic/chess_piece/invalid_pieceset.png} +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base/invalid_text_size.png → 04_icons_graphic/chess_piece/invalid_single_piece.png} +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base/invalid_square_size.png → 04_icons_graphic/chess_piece/invalid_size.png} +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/colorized_arrow.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/colorized_square.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/colorized_symbol.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/colorized_text.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/default_arrow.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/default_square.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/default_text.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/wrapped_arrow.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/wrapped_square.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/wrapped_symbol.png +0 -0
- /package/test/graphic_references/{04_marker_icons_graphic/base → 04_icons_graphic/marker}/wrapped_text.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/base/game_1.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/base/game_2.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/base/game_3.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/base/game_4.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/error/pgn_parsing_error_1.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/error/pgn_parsing_error_2.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/error/wrong_game_index_1.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/error/wrong_game_index_2.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/error/wrong_game_index_type.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/error/wrong_game_type.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/html/filtered_tags_and_attributes.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/html/html_in_comments.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/html/html_in_headers.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/options/custom_piece_symbols.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/options/figurine_piece_symbols_and_diagram_options.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/options/hidden_diagrams.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/options/localized_piece_symbols.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/options/wrong_diagram_options_1.png +0 -0
- /package/test/graphic_references/{09_movetext_graphic → 10_movetext_graphic}/options/wrong_diagram_options_2.png +0 -0
- /package/test/graphic_references/{10_movetext_interaction → 11_movetext_interaction}/error/wrong_interaction_mode.png +0 -0
- /package/test/graphic_references/{10_movetext_interaction → 11_movetext_interaction}/select_moves/click_on_disabled.png +0 -0
- /package/test/graphic_references/{10_movetext_interaction → 11_movetext_interaction}/select_moves/click_on_unselected.png +0 -0
- /package/test/graphic_references/{10_movetext_interaction → 11_movetext_interaction}/select_moves/click_on_with_variations.png +0 -0
- /package/test/graphic_test_app/{04_marker_icons_graphic/base.tsx → 04_icons_graphic/marker.tsx} +0 -0
- /package/test/graphic_test_app/{09_movetext_graphic → 10_movetext_graphic}/base.tsx +0 -0
- /package/test/graphic_test_app/{09_movetext_graphic → 10_movetext_graphic}/error.tsx +0 -0
- /package/test/graphic_test_app/{09_movetext_graphic → 10_movetext_graphic}/html.tsx +0 -0
- /package/test/graphic_test_app/{10_movetext_interaction → 11_movetext_interaction}/error.tsx +0 -0
- /package/test/graphic_test_app/{10_movetext_interaction → 11_movetext_interaction}/select_moves.tsx +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Kokopu-React version 3.0.0 introduces some breaking changes with regard to the previous versions.
|
|
2
|
+
Those changes may require some fixes or adjustments in your codebase when upgrading Kokopu-React
|
|
3
|
+
from 2.x to 3.0.0 (or any subsequent version).
|
|
4
|
+
|
|
5
|
+
To upgrade from an older version, follow the [migration guide to 2.x](#/Migrate%20to%202.x) beforehand.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Methods `Chessboard.size(..)`
|
|
10
|
+
-----------------------------
|
|
11
|
+
|
|
12
|
+
As of 3.0.0, the method arguments `squareSize`, `coordinateVisible` and `smallScreenLimits`
|
|
13
|
+
must be passed as named arguments, as in the following example:
|
|
14
|
+
|
|
15
|
+
```plain
|
|
16
|
+
const squareSize = 42;
|
|
17
|
+
const coordinateVisible = true;
|
|
18
|
+
const smallScreenLimits = [ /* whatever */ ];
|
|
19
|
+
|
|
20
|
+
const { width, height } = Chessboard.size({
|
|
21
|
+
squareSize: squareSize,
|
|
22
|
+
coordinateVisible: coordinateVisible,
|
|
23
|
+
smallScreenLimits: smallScreenLimits,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Used to be, before 3.0.0:
|
|
27
|
+
// const { width, height } = Chessboard.size(squareSize, coordinateVisible, smallScreenLimits);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Methods `Chessboard.adaptSquareSize(..)`
|
|
33
|
+
----------------------------------------
|
|
34
|
+
|
|
35
|
+
As of 3.0.0, the method arguments `coordinateVisible` and `smallScreenLimits`
|
|
36
|
+
must be passed as named arguments, as in the following example:
|
|
37
|
+
|
|
38
|
+
```plain
|
|
39
|
+
const width = 600;
|
|
40
|
+
const height = 400;
|
|
41
|
+
const coordinateVisible = true;
|
|
42
|
+
const smallScreenLimits = [ /* whatever */ ];
|
|
43
|
+
|
|
44
|
+
const squareSize = Chessboard.adaptSquareSize(width, height, {
|
|
45
|
+
coordinateVisible: coordinateVisible,
|
|
46
|
+
smallScreenLimits: smallScreenLimits,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Used to be, before 3.0.0:
|
|
50
|
+
// const squareSize = Chessboard.adaptSquareSize(width, height, coordinateVisible, smallScreenLimits);
|
|
51
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kokopu-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A React-based library to create and display chessboard and chess-related components.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chess",
|
|
@@ -42,23 +42,23 @@
|
|
|
42
42
|
"htmlparser2": "^9.0.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@babel/preset-env": "^7.
|
|
46
|
-
"@babel/preset-react": "^7.
|
|
47
|
-
"@emotion/react": "^11.11.
|
|
45
|
+
"@babel/preset-env": "^7.22.5",
|
|
46
|
+
"@babel/preset-react": "^7.22.5",
|
|
47
|
+
"@emotion/react": "^11.11.1",
|
|
48
48
|
"@emotion/styled": "^11.11.0",
|
|
49
|
-
"@mui/material": "^5.13.
|
|
50
|
-
"@types/react": "^18.2.
|
|
51
|
-
"@types/react-dom": "^18.2.
|
|
52
|
-
"@typescript-eslint/eslint-plugin": "^5.59.
|
|
53
|
-
"@typescript-eslint/parser": "^5.59.
|
|
49
|
+
"@mui/material": "^5.13.5",
|
|
50
|
+
"@types/react": "^18.2.12",
|
|
51
|
+
"@types/react-dom": "^18.2.5",
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
|
53
|
+
"@typescript-eslint/parser": "^5.59.11",
|
|
54
54
|
"babel-loader": "^9.1.2",
|
|
55
55
|
"copy-webpack-plugin": "^11.0.0",
|
|
56
56
|
"copyfiles": "^2.4.1",
|
|
57
57
|
"coverage-istanbul-loader": "^3.0.5",
|
|
58
|
-
"css-loader": "^6.
|
|
59
|
-
"eslint": "^8.
|
|
58
|
+
"css-loader": "^6.8.1",
|
|
59
|
+
"eslint": "^8.43.0",
|
|
60
60
|
"eslint-plugin-react": "^7.32.2",
|
|
61
|
-
"html-webpack-plugin": "^5.5.
|
|
61
|
+
"html-webpack-plugin": "^5.5.3",
|
|
62
62
|
"img-diff-js": "^0.5.2",
|
|
63
63
|
"kokopu": "^4.7.0",
|
|
64
64
|
"mocha": "^10.2.0",
|
|
@@ -69,14 +69,14 @@
|
|
|
69
69
|
"react-dom": "^18.2.0",
|
|
70
70
|
"react-styleguidist": "^13.1.1",
|
|
71
71
|
"rimraf": "^5.0.1",
|
|
72
|
-
"selenium-webdriver": "^4.
|
|
72
|
+
"selenium-webdriver": "^4.10.0",
|
|
73
73
|
"ssh2-sftp-client": "^9.1.0",
|
|
74
74
|
"style-loader": "^3.3.3",
|
|
75
75
|
"ts-loader": "^9.4.3",
|
|
76
|
-
"typescript": "
|
|
76
|
+
"typescript": "~5.0.4",
|
|
77
77
|
"unit.js": "^2.1.1",
|
|
78
|
-
"webpack": "^5.
|
|
79
|
-
"webpack-cli": "^5.1.
|
|
78
|
+
"webpack": "^5.87.0",
|
|
79
|
+
"webpack-cli": "^5.1.4"
|
|
80
80
|
},
|
|
81
81
|
"scripts": {
|
|
82
82
|
"lint": "eslint doc_src src test",
|
|
@@ -37,7 +37,8 @@ fs.mkdirSync(path.resolve(__dirname, tmpDir), { recursive: true });
|
|
|
37
37
|
// -------------------------------
|
|
38
38
|
|
|
39
39
|
const componentSectionTitle = 'Components';
|
|
40
|
-
const components = [ 'errorbox/ErrorBox', 'icons/SquareMarkerIcon', 'icons/TextMarkerIcon', 'icons/ArrowMarkerIcon', '
|
|
40
|
+
const components = [ 'errorbox/ErrorBox', 'icons/SquareMarkerIcon', 'icons/TextMarkerIcon', 'icons/ArrowMarkerIcon', 'icons/ChessPieceIcon',
|
|
41
|
+
'chessboard/Chessboard', 'movetext/Movetext' ];
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
// Demo section configuration
|
|
@@ -177,6 +178,10 @@ module.exports = {
|
|
|
177
178
|
name: 'Migrate to 2.x',
|
|
178
179
|
content: `${docSrcDir}/migrate_to_2.md`,
|
|
179
180
|
},
|
|
181
|
+
{
|
|
182
|
+
name: 'Migrate to 3.x',
|
|
183
|
+
content: `${docSrcDir}/migrate_to_3.md`,
|
|
184
|
+
},
|
|
180
185
|
],
|
|
181
186
|
styleguideComponents: {
|
|
182
187
|
LogoRenderer: path.resolve(__dirname, `${docSrcDir}/theming/LogoRenderer`),
|
|
@@ -2,7 +2,7 @@ version: "3.7"
|
|
|
2
2
|
|
|
3
3
|
services:
|
|
4
4
|
web-client:
|
|
5
|
-
image: selenium/standalone-firefox:4.
|
|
5
|
+
image: selenium/standalone-firefox:4.10.0-20230607 # https://github.com/SeleniumHQ/docker-selenium to get the latest version
|
|
6
6
|
shm_size: '2gb'
|
|
7
7
|
ports:
|
|
8
8
|
- 4444:4444 # http://localhost:4444 (driver)
|
|
@@ -26,12 +26,12 @@ import { exception as kokopuException, MoveDescriptor, Position, Square, GameVar
|
|
|
26
26
|
|
|
27
27
|
import { IllegalArgument } from '../exception';
|
|
28
28
|
import { i18n } from '../i18n';
|
|
29
|
-
import { sanitizeString, sanitizeBoolean, sanitizeInteger, sanitizeBoundedInteger, sanitizeOptional } from '../sanitization';
|
|
29
|
+
import { sanitizeString, sanitizeBoolean, sanitizePartialObject, sanitizeInteger, sanitizeBoundedInteger, sanitizeOptional } from '../sanitization';
|
|
30
30
|
import { MIN_SQUARE_SIZE, MAX_SQUARE_SIZE, Colorset, Pieceset, AnnotationColor, AnnotationSymbol, SquareMarkerSet, TextMarkerSet, ArrowMarkerSet,
|
|
31
31
|
isAnnotationColor, isAnnotationSymbol, parseSquareMarkers, parseTextMarkers, parseArrowMarkers } from '../types';
|
|
32
32
|
|
|
33
|
-
import { colorsets } from './colorsets';
|
|
34
|
-
import { piecesets } from './piecesets';
|
|
33
|
+
import { colorsets, DEFAULT_COLORSET } from './colorsets';
|
|
34
|
+
import { piecesets, DEFAULT_PIECESET } from './piecesets';
|
|
35
35
|
import { ChessboardImpl, chessboardSize } from './ChessboardImpl';
|
|
36
36
|
import { ErrorBox } from '../errorbox/ErrorBox';
|
|
37
37
|
|
|
@@ -43,6 +43,7 @@ export interface SmallScreenLimit {
|
|
|
43
43
|
width: number;
|
|
44
44
|
squareSize?: number;
|
|
45
45
|
coordinateVisible?: boolean;
|
|
46
|
+
turnVisible?: boolean;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
|
|
@@ -98,6 +99,11 @@ export interface ChessboardProps {
|
|
|
98
99
|
*/
|
|
99
100
|
coordinateVisible: boolean;
|
|
100
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Whether the turn flag is visible or not.
|
|
104
|
+
*/
|
|
105
|
+
turnVisible: boolean;
|
|
106
|
+
|
|
101
107
|
/**
|
|
102
108
|
* Whether moves are highlighted with an arrow or not.
|
|
103
109
|
*/
|
|
@@ -180,6 +186,9 @@ interface ChessboardState {
|
|
|
180
186
|
}
|
|
181
187
|
|
|
182
188
|
|
|
189
|
+
const DEFAULT_SQUARE_SIZE = 40;
|
|
190
|
+
|
|
191
|
+
|
|
183
192
|
/**
|
|
184
193
|
* SVG image representing a chessboard diagram. Optionally, the user may interact with the board (move pieces, click on squares...).
|
|
185
194
|
* Annotations such as square markers or arrows can also be added to the board.
|
|
@@ -189,13 +198,14 @@ export class Chessboard extends React.Component<ChessboardProps, ChessboardState
|
|
|
189
198
|
static defaultProps: Partial<ChessboardProps> = {
|
|
190
199
|
position: 'start',
|
|
191
200
|
flipped: false,
|
|
192
|
-
squareSize:
|
|
201
|
+
squareSize: DEFAULT_SQUARE_SIZE,
|
|
193
202
|
coordinateVisible: true,
|
|
203
|
+
turnVisible: true,
|
|
194
204
|
moveArrowVisible: true,
|
|
195
205
|
moveArrowColor: 'b',
|
|
196
206
|
animated: false,
|
|
197
|
-
colorset:
|
|
198
|
-
pieceset:
|
|
207
|
+
colorset: DEFAULT_COLORSET,
|
|
208
|
+
pieceset: DEFAULT_PIECESET,
|
|
199
209
|
};
|
|
200
210
|
|
|
201
211
|
private windowResizeListener = () => this.handleWindowResize();
|
|
@@ -242,6 +252,7 @@ export class Chessboard extends React.Component<ChessboardProps, ChessboardState
|
|
|
242
252
|
const flipped = sanitizeBoolean(this.props.flipped);
|
|
243
253
|
const squareSize = sanitizeBoundedInteger(this.props.squareSize, MIN_SQUARE_SIZE, MAX_SQUARE_SIZE, () => new IllegalArgument('Chessboard', 'squareSize'));
|
|
244
254
|
const coordinateVisible = sanitizeBoolean(this.props.coordinateVisible);
|
|
255
|
+
const turnVisible = sanitizeBoolean(this.props.turnVisible);
|
|
245
256
|
const moveArrowVisible = sanitizeBoolean(this.props.moveArrowVisible);
|
|
246
257
|
if (!isAnnotationColor(this.props.moveArrowColor)) {
|
|
247
258
|
throw new IllegalArgument('Chessboard', 'moveArrowColor');
|
|
@@ -260,6 +271,7 @@ export class Chessboard extends React.Component<ChessboardProps, ChessboardState
|
|
|
260
271
|
const smallScreenLimits = sanitizeSmallScreenLimits(this.props.smallScreenLimits, () => new IllegalArgument('Chessboard', 'smallScreenLimits'));
|
|
261
272
|
const actualSquareSize = computeSquareSizeForSmallScreens(squareSize, smallScreenLimits, this.state.windowWidth);
|
|
262
273
|
const actualCoordinateVisible = computeCoordinateVisibleForSmallScreens(coordinateVisible, smallScreenLimits, this.state.windowWidth);
|
|
274
|
+
const actualTurnVisible = computeTurnVisibleForSmallScreens(turnVisible, smallScreenLimits, this.state.windowWidth);
|
|
263
275
|
|
|
264
276
|
// Validate the interaction attributes and the callbacks.
|
|
265
277
|
const interactionMode = this.getInteractionModeAndValidateEditedArrowColor();
|
|
@@ -271,9 +283,10 @@ export class Chessboard extends React.Component<ChessboardProps, ChessboardState
|
|
|
271
283
|
|
|
272
284
|
return (
|
|
273
285
|
<ChessboardImpl key={key}
|
|
274
|
-
position={position} move={move} squareMarkers={sqm} textMarkers={txtm} arrowMarkers={arm}
|
|
275
|
-
|
|
276
|
-
moveArrowColor={this.props.moveArrowColor} animated={animated}
|
|
286
|
+
position={position} move={move} squareMarkers={sqm} textMarkers={txtm} arrowMarkers={arm} flipped={flipped}
|
|
287
|
+
squareSize={actualSquareSize} coordinateVisible={actualCoordinateVisible} turnVisible={actualTurnVisible}
|
|
288
|
+
moveArrowVisible={moveArrowVisible} moveArrowColor={this.props.moveArrowColor} animated={animated}
|
|
289
|
+
colorset={colorset} pieceset={pieceset}
|
|
277
290
|
interactionMode={interactionMode} editedArrowColor={this.props.editedArrowColor}
|
|
278
291
|
onPieceMoved={onPieceMoved} onSquareClicked={onSquareClicked} onArrowEdited={onArrowEdited} onMovePlayed={onMovePlayed}
|
|
279
292
|
/>
|
|
@@ -299,43 +312,50 @@ export class Chessboard extends React.Component<ChessboardProps, ChessboardState
|
|
|
299
312
|
/**
|
|
300
313
|
* Return the size of the chessboard, assuming it is built with the given attributes.
|
|
301
314
|
*/
|
|
302
|
-
static size(
|
|
315
|
+
static size(attr?: Partial<Pick<ChessboardProps, 'squareSize' | 'coordinateVisible' | 'turnVisible' | 'smallScreenLimits'>>): { width: number, height: number } {
|
|
316
|
+
let { squareSize, coordinateVisible, turnVisible, smallScreenLimits } = sanitizePartialObject(attr, () => new IllegalArgument('Chessboard.size()', 'attr'));
|
|
303
317
|
|
|
304
318
|
// Sanitize the arguments.
|
|
305
|
-
squareSize =
|
|
306
|
-
|
|
307
|
-
|
|
319
|
+
squareSize = squareSize === undefined ? DEFAULT_SQUARE_SIZE :
|
|
320
|
+
sanitizeBoundedInteger(squareSize, MIN_SQUARE_SIZE, MAX_SQUARE_SIZE, () => new IllegalArgument('Chessboard.size()', 'squareSize'));
|
|
321
|
+
coordinateVisible = coordinateVisible === undefined ? true : sanitizeBoolean(coordinateVisible);
|
|
322
|
+
turnVisible = turnVisible === undefined ? true : sanitizeBoolean(turnVisible);
|
|
323
|
+
smallScreenLimits = sanitizeSmallScreenLimits(smallScreenLimits, () => new IllegalArgument('Chessboard.size()', 'smallScreenLimits'));
|
|
308
324
|
|
|
309
325
|
// Enforce small-screen limits, if any.
|
|
310
326
|
if (typeof window !== 'undefined') {
|
|
311
|
-
squareSize = computeSquareSizeForSmallScreens(squareSize,
|
|
312
|
-
coordinateVisible = computeCoordinateVisibleForSmallScreens(coordinateVisible,
|
|
327
|
+
squareSize = computeSquareSizeForSmallScreens(squareSize, smallScreenLimits, window.innerWidth);
|
|
328
|
+
coordinateVisible = computeCoordinateVisibleForSmallScreens(coordinateVisible, smallScreenLimits, window.innerWidth);
|
|
329
|
+
turnVisible = computeTurnVisibleForSmallScreens(turnVisible, smallScreenLimits, window.innerWidth);
|
|
313
330
|
}
|
|
314
331
|
|
|
315
332
|
// Compute the dimensions.
|
|
316
|
-
return chessboardSize(squareSize, coordinateVisible);
|
|
333
|
+
return chessboardSize(squareSize, coordinateVisible, turnVisible);
|
|
317
334
|
}
|
|
318
335
|
|
|
319
336
|
/**
|
|
320
337
|
* Return the maximum square size that would allow the chessboard to fit in a rectangle of size `width x height`.
|
|
321
338
|
*/
|
|
322
|
-
static adaptSquareSize(width: number, height: number,
|
|
339
|
+
static adaptSquareSize(width: number, height: number, attr?: Partial<Pick<ChessboardProps, 'coordinateVisible' | 'turnVisible' | 'smallScreenLimits'>>): number {
|
|
340
|
+
let { coordinateVisible, turnVisible, smallScreenLimits } = sanitizePartialObject(attr, () => new IllegalArgument('Chessboard.size()', 'attr'));
|
|
323
341
|
|
|
324
342
|
// Sanitize the arguments.
|
|
325
343
|
width = sanitizeInteger(width, () => new IllegalArgument('Chessboard.adaptSquareSize()', 'width'));
|
|
326
344
|
height = sanitizeInteger(height, () => new IllegalArgument('Chessboard.adaptSquareSize()', 'height'));
|
|
327
|
-
coordinateVisible = sanitizeBoolean(coordinateVisible);
|
|
328
|
-
|
|
345
|
+
coordinateVisible = coordinateVisible === undefined ? true : sanitizeBoolean(coordinateVisible);
|
|
346
|
+
turnVisible = turnVisible === undefined ? true : sanitizeBoolean(turnVisible);
|
|
347
|
+
smallScreenLimits = sanitizeSmallScreenLimits(smallScreenLimits, () => new IllegalArgument('Chessboard.adaptSquareSize()', 'smallScreenLimits'));
|
|
329
348
|
|
|
330
349
|
// Enforce small-screen limits, if any.
|
|
331
350
|
let maxSquareSize = MAX_SQUARE_SIZE;
|
|
332
351
|
if (typeof window !== 'undefined') {
|
|
333
|
-
maxSquareSize = computeSquareSizeForSmallScreens(maxSquareSize,
|
|
334
|
-
coordinateVisible = computeCoordinateVisibleForSmallScreens(coordinateVisible,
|
|
352
|
+
maxSquareSize = computeSquareSizeForSmallScreens(maxSquareSize, smallScreenLimits, window.innerWidth);
|
|
353
|
+
coordinateVisible = computeCoordinateVisibleForSmallScreens(coordinateVisible, smallScreenLimits, window.innerWidth);
|
|
354
|
+
turnVisible = computeTurnVisibleForSmallScreens(turnVisible, smallScreenLimits, window.innerWidth);
|
|
335
355
|
}
|
|
336
356
|
|
|
337
357
|
function isAdapted(squareSize: number) {
|
|
338
|
-
const { width: actualWidth, height: actualHeight } = chessboardSize(squareSize, coordinateVisible);
|
|
358
|
+
const { width: actualWidth, height: actualHeight } = chessboardSize(squareSize, coordinateVisible!, turnVisible!);
|
|
339
359
|
return actualWidth <= width && actualHeight <= height;
|
|
340
360
|
}
|
|
341
361
|
|
|
@@ -410,7 +430,7 @@ function computeSquareSizeForSmallScreens(squareSize: number, smallScreenLimits:
|
|
|
410
430
|
|
|
411
431
|
|
|
412
432
|
/**
|
|
413
|
-
* Compute the actual
|
|
433
|
+
* Compute the actual coordinate visibility attribute taking into account the given small-screen limits and window width.
|
|
414
434
|
*/
|
|
415
435
|
function computeCoordinateVisibleForSmallScreens(coordinateVisible: boolean, smallScreenLimits: SmallScreenLimit[], windowWidth: number) {
|
|
416
436
|
const maximumCoordinateVisible = computeSmallScreenLimits(smallScreenLimits, windowWidth, limit => limit.coordinateVisible);
|
|
@@ -418,6 +438,15 @@ function computeCoordinateVisibleForSmallScreens(coordinateVisible: boolean, sma
|
|
|
418
438
|
}
|
|
419
439
|
|
|
420
440
|
|
|
441
|
+
/**
|
|
442
|
+
* Compute the actual turn flag visibility attribute taking into account the given small-screen limits and window width.
|
|
443
|
+
*/
|
|
444
|
+
function computeTurnVisibleForSmallScreens(turnVisible: boolean, smallScreenLimits: SmallScreenLimit[], windowWidth: number) {
|
|
445
|
+
const maximumTurnVisible = computeSmallScreenLimits(smallScreenLimits, windowWidth, limit => limit.turnVisible);
|
|
446
|
+
return maximumTurnVisible === undefined ? turnVisible : turnVisible && maximumTurnVisible;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
|
|
421
450
|
/**
|
|
422
451
|
* Compute the limit applicable to the given window width.
|
|
423
452
|
*/
|
|
@@ -565,10 +594,14 @@ function sanitizeSmallScreenLimits(smallScreenLimits: SmallScreenLimit[] | undef
|
|
|
565
594
|
}
|
|
566
595
|
else {
|
|
567
596
|
return smallScreenLimits.map(smallScreenLimit => {
|
|
597
|
+
if (typeof smallScreenLimit !== 'object' || smallScreenLimit === null) {
|
|
598
|
+
throw exceptionBuilder();
|
|
599
|
+
}
|
|
568
600
|
return {
|
|
569
601
|
width: sanitizeInteger(smallScreenLimit.width, exceptionBuilder),
|
|
570
602
|
squareSize: sanitizeOptional(smallScreenLimit.squareSize, val => sanitizeBoundedInteger(val, MIN_SQUARE_SIZE, MAX_SQUARE_SIZE, exceptionBuilder)),
|
|
571
603
|
coordinateVisible: sanitizeOptional(smallScreenLimit.coordinateVisible, sanitizeBoolean),
|
|
604
|
+
turnVisible: sanitizeOptional(smallScreenLimit.turnVisible, sanitizeBoolean)
|
|
572
605
|
};
|
|
573
606
|
});
|
|
574
607
|
}
|
|
@@ -60,6 +60,7 @@ interface ChessboardImplProps {
|
|
|
60
60
|
flipped: boolean;
|
|
61
61
|
squareSize: number;
|
|
62
62
|
coordinateVisible: boolean;
|
|
63
|
+
turnVisible: boolean;
|
|
63
64
|
moveArrowVisible: boolean;
|
|
64
65
|
moveArrowColor: AnnotationColor;
|
|
65
66
|
animated: boolean;
|
|
@@ -127,7 +128,7 @@ export class ChessboardImpl extends React.Component<ChessboardImplProps, Chessbo
|
|
|
127
128
|
// Render the whole canvas.
|
|
128
129
|
const xmin = Math.round(-RANK_COORDINATE_WIDTH_FACTOR * fontSize);
|
|
129
130
|
const ymin = 0;
|
|
130
|
-
const xmax = 9 * this.props.squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * this.props.squareSize);
|
|
131
|
+
const xmax = this.props.turnVisible ? 9 * this.props.squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * this.props.squareSize) : 8 * this.props.squareSize;
|
|
131
132
|
const ymax = 8 * this.props.squareSize + Math.round(FILE_COORDINATE_HEIGHT_FACTOR * fontSize);
|
|
132
133
|
const viewBox = `${xmin} ${ymin} ${xmax - xmin} ${ymax - ymin}`;
|
|
133
134
|
return (
|
|
@@ -433,6 +434,9 @@ export class ChessboardImpl extends React.Component<ChessboardImplProps, Chessbo
|
|
|
433
434
|
}
|
|
434
435
|
|
|
435
436
|
private renderTurnFlag(turn: Color) {
|
|
437
|
+
if (!this.props.turnVisible) {
|
|
438
|
+
return undefined;
|
|
439
|
+
}
|
|
436
440
|
const x = 8 * this.props.squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * this.props.squareSize);
|
|
437
441
|
const y = turn === (this.props.flipped ? 'b' : 'w') ? 7 * this.props.squareSize : 0;
|
|
438
442
|
return <image key={'turn-' + turn} x={x} y={y} width={this.props.squareSize} height={this.props.squareSize} href={this.getURLForTurnFlag(turn)} />;
|
|
@@ -612,9 +616,12 @@ export class ChessboardImpl extends React.Component<ChessboardImplProps, Chessbo
|
|
|
612
616
|
/**
|
|
613
617
|
* Return the size of the chessboard, assuming it is built with the given attributes.
|
|
614
618
|
*/
|
|
615
|
-
export function chessboardSize(squareSize: number, coordinateVisible: boolean) {
|
|
616
|
-
let width =
|
|
619
|
+
export function chessboardSize(squareSize: number, coordinateVisible: boolean, turnVisible: boolean) {
|
|
620
|
+
let width = 8 * squareSize;
|
|
617
621
|
let height = 8 * squareSize;
|
|
622
|
+
if (turnVisible) {
|
|
623
|
+
width += squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * squareSize);
|
|
624
|
+
}
|
|
618
625
|
if (coordinateVisible) {
|
|
619
626
|
const fontSize = computeCoordinateFontSize(squareSize);
|
|
620
627
|
width += Math.round(RANK_COORDINATE_WIDTH_FACTOR * fontSize);
|
|
@@ -72,17 +72,6 @@ interface DraggableProps {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
interface InnerListeners {
|
|
76
|
-
mouseDown: (evt: MouseEvent) => void;
|
|
77
|
-
mouseMove: (evt: MouseEvent) => void;
|
|
78
|
-
mouseUp: (evt: MouseEvent) => void;
|
|
79
|
-
touchStart: (evt: TouchEvent) => void;
|
|
80
|
-
touchMove: (evt: TouchEvent) => void;
|
|
81
|
-
touchEnd: (evt: TouchEvent) => void;
|
|
82
|
-
touchCancel: (evt: TouchEvent) => void;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
75
|
interface DragData {
|
|
87
76
|
originX: number;
|
|
88
77
|
originY: number;
|
|
@@ -107,42 +96,34 @@ interface ClientCoordinates {
|
|
|
107
96
|
export class Draggable extends React.Component<DraggableProps> {
|
|
108
97
|
|
|
109
98
|
private innerRef: React.RefObject<SVGRectElement> = React.createRef();
|
|
110
|
-
private innerListeners?: InnerListeners;
|
|
111
99
|
private dragData?: DragData;
|
|
112
100
|
|
|
101
|
+
private mouseDownListener = (evt: MouseEvent) => this.handleMouseDown(evt);
|
|
102
|
+
private mouseMoveListener = (evt: MouseEvent) => this.handleMouseMove(evt);
|
|
103
|
+
private mouseUpListener = (evt: MouseEvent) => this.handleMouseUp(evt);
|
|
104
|
+
private touchStartListener = (evt: TouchEvent) => this.handleTouchStart(evt);
|
|
105
|
+
private touchMoveListener = (evt: TouchEvent) => this.handleTouchMove(evt);
|
|
106
|
+
private touchEndListener = (evt: TouchEvent) => this.handleTouchEnd(evt);
|
|
107
|
+
private touchCancelListener = (evt: TouchEvent) => this.handleTouchCancel(evt);
|
|
108
|
+
|
|
113
109
|
componentDidMount() {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
touchEnd: evt => this.handleTouchEnd(evt),
|
|
122
|
-
touchCancel: evt => this.handleTouchCancel(evt),
|
|
123
|
-
};
|
|
124
|
-
this.innerRef.current!.addEventListener('mousedown', this.innerListeners.mouseDown);
|
|
125
|
-
window.addEventListener('mousemove', this.innerListeners.mouseMove);
|
|
126
|
-
window.addEventListener('mouseup', this.innerListeners.mouseUp);
|
|
127
|
-
this.innerRef.current!.addEventListener('touchstart', this.innerListeners.touchStart, { passive: false });
|
|
128
|
-
window.addEventListener('touchmove', this.innerListeners.touchMove, { passive: false });
|
|
129
|
-
window.addEventListener('touchend', this.innerListeners.touchEnd);
|
|
130
|
-
window.addEventListener('touchcancel', this.innerListeners.touchCancel);
|
|
131
|
-
}
|
|
132
|
-
this.dragData = undefined;
|
|
110
|
+
this.innerRef.current!.addEventListener('mousedown', this.mouseDownListener);
|
|
111
|
+
window.addEventListener('mousemove', this.mouseMoveListener);
|
|
112
|
+
window.addEventListener('mouseup', this.mouseUpListener);
|
|
113
|
+
this.innerRef.current!.addEventListener('touchstart', this.touchStartListener, { passive: false });
|
|
114
|
+
window.addEventListener('touchmove', this.touchMoveListener, { passive: false });
|
|
115
|
+
window.addEventListener('touchend', this.touchEndListener);
|
|
116
|
+
window.addEventListener('touchcancel', this.touchCancelListener);
|
|
133
117
|
}
|
|
134
118
|
|
|
135
119
|
componentWillUnmount() {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
window.removeEventListener('touchcancel', this.innerListeners.touchCancel);
|
|
144
|
-
this.innerListeners = undefined;
|
|
145
|
-
}
|
|
120
|
+
this.innerRef.current!.removeEventListener('mousedown', this.mouseDownListener);
|
|
121
|
+
window.removeEventListener('mousemove', this.mouseMoveListener);
|
|
122
|
+
window.removeEventListener('mouseup', this.mouseUpListener);
|
|
123
|
+
this.innerRef.current!.removeEventListener('touchstart', this.touchStartListener);
|
|
124
|
+
window.removeEventListener('touchmove', this.touchMoveListener);
|
|
125
|
+
window.removeEventListener('touchend', this.touchEndListener);
|
|
126
|
+
window.removeEventListener('touchcancel', this.touchCancelListener);
|
|
146
127
|
}
|
|
147
128
|
|
|
148
129
|
render() {
|
|
@@ -121,6 +121,12 @@ import skulls_bx from './sprites/skulls-bx.png';
|
|
|
121
121
|
import skulls_wx from './sprites/skulls-wx.png';
|
|
122
122
|
|
|
123
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Default pieceset.
|
|
126
|
+
*/
|
|
127
|
+
export const DEFAULT_PIECESET = 'cburnett';
|
|
128
|
+
|
|
129
|
+
|
|
124
130
|
/**
|
|
125
131
|
* Available piecesets.
|
|
126
132
|
*/
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/* -------------------------------------------------------------------------- *
|
|
2
|
+
* *
|
|
3
|
+
* This file is part of Kokopu-React, a JavaScript chess library. *
|
|
4
|
+
* Copyright (C) 2021-2023 Yoann Le Montagner <yo35 -at- melix.net> *
|
|
5
|
+
* *
|
|
6
|
+
* This program is free software: you can redistribute it and/or *
|
|
7
|
+
* modify it under the terms of the GNU Lesser General Public License *
|
|
8
|
+
* as published by the Free Software Foundation, either version 3 of *
|
|
9
|
+
* the License, or (at your option) any later version. *
|
|
10
|
+
* *
|
|
11
|
+
* This program is distributed in the hope that it will be useful, *
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
14
|
+
* GNU Lesser General Public License for more details. *
|
|
15
|
+
* *
|
|
16
|
+
* You should have received a copy of the GNU Lesser General *
|
|
17
|
+
* Public License along with this program. If not, see *
|
|
18
|
+
* <http://www.gnu.org/licenses/>. *
|
|
19
|
+
* *
|
|
20
|
+
* -------------------------------------------------------------------------- */
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
import * as React from 'react';
|
|
24
|
+
|
|
25
|
+
import { IllegalArgument } from '../exception';
|
|
26
|
+
import { sanitizeBoundedInteger } from '../sanitization';
|
|
27
|
+
import { MIN_SQUARE_SIZE, MAX_SQUARE_SIZE, ChessPieceIconType, isChessPieceIconType } from '../types';
|
|
28
|
+
import { piecesets, DEFAULT_PIECESET } from '../chessboard/piecesets';
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
export interface ChessPieceIconProps {
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Width and height (in pixels) of each chess piece icon.
|
|
35
|
+
*/
|
|
36
|
+
size: number;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Chess piece(s) to display.
|
|
40
|
+
*/
|
|
41
|
+
type: ChessPieceIconType | ChessPieceIconType[];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Piece theme ID. Must be a property of `Chessboard.piecesets()`.
|
|
45
|
+
*/
|
|
46
|
+
pieceset: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
const defaultProps: Partial<ChessPieceIconProps> = {
|
|
51
|
+
pieceset: DEFAULT_PIECESET,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* SVG icon representing a colored chess piece, or a list of colored chess pieces.
|
|
57
|
+
*/
|
|
58
|
+
export function ChessPieceIcon({ size, type, pieceset }: ChessPieceIconProps) {
|
|
59
|
+
|
|
60
|
+
// Sanitize the inputs.
|
|
61
|
+
size = sanitizeBoundedInteger(size, MIN_SQUARE_SIZE, MAX_SQUARE_SIZE, () => new IllegalArgument('ChessPieceIcon', 'size'));
|
|
62
|
+
const types = sanitizeChessPieceIconType(type, () => new IllegalArgument('ChessPieceIcon', 'type'));
|
|
63
|
+
const piecesetData = piecesets[pieceset];
|
|
64
|
+
if (!piecesetData) {
|
|
65
|
+
throw new IllegalArgument('ChessPieceIcon', 'pieceset');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Render the component.
|
|
69
|
+
const width = size * types.length;
|
|
70
|
+
const viewBox = `0 0 ${width} ${size}`;
|
|
71
|
+
return (
|
|
72
|
+
<svg className="kokopu-chessPieceIcon" viewBox={viewBox} width={width} height={size}>
|
|
73
|
+
{types.map((t, i) => <image key={i} x={i * size} y={0} width={size} height={size} href={piecesetData[t]} />)}
|
|
74
|
+
</svg>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ChessPieceIcon.defaultProps = defaultProps;
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Sanitization method for the small-screen limits parameter.
|
|
83
|
+
*/
|
|
84
|
+
function sanitizeChessPieceIconType(type: ChessPieceIconType | ChessPieceIconType[], exceptionBuilder: () => IllegalArgument): ChessPieceIconType[] {
|
|
85
|
+
if (Array.isArray(type)) {
|
|
86
|
+
return type.map(t => {
|
|
87
|
+
if (!isChessPieceIconType(t)) {
|
|
88
|
+
throw exceptionBuilder();
|
|
89
|
+
}
|
|
90
|
+
return t;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else if (isChessPieceIconType(type)) {
|
|
94
|
+
return [ type ];
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
throw exceptionBuilder();
|
|
98
|
+
}
|
|
99
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -23,14 +23,16 @@
|
|
|
23
23
|
export { i18n } from './i18n';
|
|
24
24
|
export * as exception from './exception';
|
|
25
25
|
|
|
26
|
-
export { Colorset, Pieceset, PieceSymbolMapping, AnnotationColor, AnnotationSymbol, SquareMarkerSet, TextMarkerSet, ArrowMarkerSet,
|
|
27
|
-
isAnnotationColor, isAnnotationSymbol, flattenSquareMarkers, flattenTextMarkers, flattenArrowMarkers,
|
|
26
|
+
export { ChessPieceIconType, Colorset, Pieceset, PieceSymbolMapping, AnnotationColor, AnnotationSymbol, SquareMarkerSet, TextMarkerSet, ArrowMarkerSet,
|
|
27
|
+
isChessPieceIconType, isPieceSymbolMapping, isAnnotationColor, isAnnotationSymbol, flattenSquareMarkers, flattenTextMarkers, flattenArrowMarkers,
|
|
28
|
+
parseSquareMarkers, parseTextMarkers, parseArrowMarkers } from './types';
|
|
28
29
|
|
|
29
30
|
export { ErrorBox, ErrorBoxProps } from './errorbox/ErrorBox';
|
|
30
31
|
|
|
31
32
|
export { SquareMarkerIcon, SquareMarkerIconProps } from './icons/SquareMarkerIcon';
|
|
32
33
|
export { TextMarkerIcon, TextMarkerIconProps } from './icons/TextMarkerIcon';
|
|
33
34
|
export { ArrowMarkerIcon, ArrowMarkerIconProps } from './icons/ArrowMarkerIcon';
|
|
35
|
+
export { ChessPieceIcon, ChessPieceIconProps } from './icons/ChessPieceIcon';
|
|
34
36
|
|
|
35
37
|
export { Chessboard, ChessboardProps, SmallScreenLimit } from './chessboard/Chessboard';
|
|
36
38
|
|
|
@@ -40,7 +40,7 @@ import './Movetext.css';
|
|
|
40
40
|
/**
|
|
41
41
|
* Origin of a "move-selected" event in {@link Movetext}. See {@link MovetextProps.onMoveSelected} for more details.
|
|
42
42
|
*/
|
|
43
|
-
export type MoveSelectEventOrigin = 'key-first' | 'key-previous' | 'key-next' | 'key-last' | 'click';
|
|
43
|
+
export type MoveSelectEventOrigin = 'key-first' | 'key-previous' | 'key-next' | 'key-last' | 'key-exit' | 'click';
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
export interface MovetextProps {
|
|
@@ -66,6 +66,7 @@ export interface MovetextProps {
|
|
|
66
66
|
flipped?: ChessboardProps['flipped'],
|
|
67
67
|
squareSize?: ChessboardProps['squareSize'],
|
|
68
68
|
coordinateVisible?: ChessboardProps['coordinateVisible'],
|
|
69
|
+
turnVisible?: ChessboardProps['turnVisible'],
|
|
69
70
|
colorset?: ChessboardProps['colorset'],
|
|
70
71
|
pieceset?: ChessboardProps['pieceset'],
|
|
71
72
|
smallScreenLimits?: ChessboardProps['smallScreenLimits'],
|
|
@@ -109,6 +110,7 @@ export interface MovetextProps {
|
|
|
109
110
|
* - `'key-previous'`: the event has been triggered by the "go-to-previous-move" key (aka. the arrow left key),
|
|
110
111
|
* - `'key-next'`: the event has been triggered by the "go-to-next-move" key (aka. the arrow right key),
|
|
111
112
|
* - `'key-last'`: the event has been triggered by the "go-to-last-move" key (aka. the end key),
|
|
113
|
+
* - `'key-exit'`: the event has been triggered by the "unselect-move" key (aka. the escape key),
|
|
112
114
|
* - `'click'`: the event has been triggered by a mouse click on a move.
|
|
113
115
|
*/
|
|
114
116
|
onMoveSelected?: (nodeId: string | undefined, evtOrigin: MoveSelectEventOrigin) => void;
|