kokopu-react 1.2.0 → 1.3.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 CHANGED
@@ -1,6 +1,11 @@
1
1
  ChangeLog
2
2
  =========
3
3
 
4
+ 1.3.0 (September 26, 2021)
5
+ --------------------------
6
+ * Expose component `ErrorBox`.
7
+ * Minor fixes in documentation.
8
+
4
9
  1.2.0 (September 13, 2021)
5
10
  --------------------------
6
11
  * Fix ambiguous castling move issue at Chess960.
@@ -21,7 +21,9 @@ var _piecesets2 = _interopRequireDefault(require("./impl/piecesets"));
21
21
 
22
22
  var _ArrowTip = _interopRequireDefault(require("./impl/ArrowTip"));
23
23
 
24
- var _ErrorBox = _interopRequireDefault(require("./impl/ErrorBox"));
24
+ var _ErrorBox = _interopRequireDefault(require("./ErrorBox"));
25
+
26
+ var _i18n = _interopRequireDefault(require("./i18n"));
25
27
 
26
28
  var _markers = require("./markers");
27
29
 
@@ -133,12 +135,12 @@ var Chessboard = /*#__PURE__*/function (_React$Component) {
133
135
 
134
136
  if (info.positionError) {
135
137
  return /*#__PURE__*/_react["default"].createElement(_ErrorBox["default"], {
136
- title: "Error while analysing a FEN string.",
138
+ title: _i18n["default"].INVALID_FEN_ERROR_TITLE,
137
139
  message: info.message
138
140
  });
139
141
  } else if (info.moveError) {
140
142
  return /*#__PURE__*/_react["default"].createElement(_ErrorBox["default"], {
141
- title: "Invalid move notation.",
143
+ title: _i18n["default"].INVALID_NOTATION_ERROR_TITLE,
142
144
  message: info.message
143
145
  });
144
146
  }
@@ -1317,7 +1319,7 @@ function parsePosition(position) {
1317
1319
  } else {
1318
1320
  return {
1319
1321
  error: true,
1320
- message: 'Invalid "position" attribute.'
1322
+ message: _i18n["default"].INVALID_POSITION_ATTRIBUTE_ERROR_MESSAGE
1321
1323
  };
1322
1324
  }
1323
1325
  }
@@ -1352,7 +1354,7 @@ function parseMove(position, move) {
1352
1354
  } else {
1353
1355
  return {
1354
1356
  error: true,
1355
- message: 'Invalid "move" attribute.'
1357
+ message: _i18n["default"].INVALID_MOVE_ATTRIBUTE_ERROR_MESSAGE
1356
1358
  };
1357
1359
  }
1358
1360
  }
@@ -9,7 +9,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
 
10
10
  var _react = _interopRequireDefault(require("react"));
11
11
 
12
- require("../css/error_box.css");
12
+ require("./css/error_box.css");
13
13
 
14
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
15
15
 
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+
8
+ /******************************************************************************
9
+ * *
10
+ * This file is part of Kokopu-React, a JavaScript chess library. *
11
+ * Copyright (C) 2021 Yoann Le Montagner <yo35 -at- melix.net> *
12
+ * *
13
+ * This program is free software: you can redistribute it and/or *
14
+ * modify it under the terms of the GNU Lesser General Public License *
15
+ * as published by the Free Software Foundation, either version 3 of *
16
+ * the License, or (at your option) any later version. *
17
+ * *
18
+ * This program is distributed in the hope that it will be useful, *
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21
+ * GNU Lesser General Public License for more details. *
22
+ * *
23
+ * You should have received a copy of the GNU Lesser General *
24
+ * Public License along with this program. If not, see *
25
+ * <http://www.gnu.org/licenses/>. *
26
+ * *
27
+ ******************************************************************************/
28
+ var i18n = {
29
+ INVALID_FEN_ERROR_TITLE: 'Invalid FEN string.',
30
+ INVALID_NOTATION_ERROR_TITLE: 'Invalid move notation.',
31
+ INVALID_POSITION_ATTRIBUTE_ERROR_MESSAGE: 'Invalid "position" attribute.',
32
+ INVALID_MOVE_ATTRIBUTE_ERROR_MESSAGE: 'Invalid "move" attribute.'
33
+ };
34
+ var _default = i18n;
35
+ exports["default"] = _default;
package/dist/lib/index.js CHANGED
@@ -39,6 +39,12 @@ Object.defineProperty(exports, "parseArrowMarkers", {
39
39
  return _markers.parseArrowMarkers;
40
40
  }
41
41
  });
42
+ Object.defineProperty(exports, "i18n", {
43
+ enumerable: true,
44
+ get: function get() {
45
+ return _i18n["default"];
46
+ }
47
+ });
42
48
  Object.defineProperty(exports, "Chessboard", {
43
49
  enumerable: true,
44
50
  get: function get() {
@@ -66,6 +72,8 @@ Object.defineProperty(exports, "ArrowMarkerIcon", {
66
72
 
67
73
  var _markers = require("./markers");
68
74
 
75
+ var _i18n = _interopRequireDefault(require("./i18n"));
76
+
69
77
  var _Chessboard = _interopRequireDefault(require("./Chessboard"));
70
78
 
71
79
  var _SquareMarkerIcon = _interopRequireDefault(require("./SquareMarkerIcon"));
File without changes
@@ -25,15 +25,18 @@ import React from 'react';
25
25
  import { Chessboard } from '../../src/index';
26
26
  import { buildComponentDemoCode } from './util';
27
27
 
28
- import Box from '@material-ui/core/Box';
29
- import Button from '@material-ui/core/Button';
30
- import ButtonGroup from '@material-ui/core/ButtonGroup';
31
- import FormControlLabel from '@material-ui/core/FormControlLabel';
32
- import MenuItem from '@material-ui/core/MenuItem';
33
- import Select from '@material-ui/core/Select';
34
- import Slider from '@material-ui/core/Slider';
35
- import Switch from '@material-ui/core/Switch';
36
- import Typography from '@material-ui/core/Typography';
28
+ import Box from '@mui/material/Box';
29
+ import Button from '@mui/material/Button';
30
+ import ButtonGroup from '@mui/material/ButtonGroup';
31
+ import FormControl from '@mui/material/FormControl';
32
+ import FormControlLabel from '@mui/material/FormControlLabel';
33
+ import InputLabel from '@mui/material/InputLabel';
34
+ import MenuItem from '@mui/material/MenuItem';
35
+ import Select from '@mui/material/Select';
36
+ import Slider from '@mui/material/Slider';
37
+ import Stack from '@mui/material/Stack';
38
+ import Switch from '@mui/material/Switch';
39
+ import Typography from '@mui/material/Typography';
37
40
 
38
41
  import './demo.css';
39
42
 
@@ -59,17 +62,17 @@ export default class Page extends React.Component {
59
62
 
60
63
  render() {
61
64
  return (
62
- <div>
65
+ <Stack spacing={2} mt={2}>
63
66
  {this.renderControls()}
64
67
  {this.renderChessboard()}
65
68
  {this.renderCode()}
66
- </div>
69
+ </Stack>
67
70
  );
68
71
  }
69
72
 
70
73
  renderControls() {
71
74
  return (<>
72
- <Box my={2}>
75
+ <Stack direction="row" spacing={2} alignItems="center">
73
76
  <FormControlLabel label="Flip"
74
77
  control={<Switch checked={this.state.flipped} onChange={() => this.set('flipped', !this.state.flipped)} color="primary" />}
75
78
  />
@@ -79,42 +82,40 @@ export default class Page extends React.Component {
79
82
  <FormControlLabel label="Show annotations"
80
83
  control={<Switch checked={this.state.annotationVisible} onChange={() => this.set('annotationVisible', !this.state.annotationVisible)} color="primary" />}
81
84
  />
82
- </Box>
83
- <Box my={2}>
85
+ </Stack>
86
+ <Box>
84
87
  <Typography gutterBottom>Square size</Typography>
85
88
  <Slider
86
89
  value={this.state.squareSize} onChange={(_, newValue) => this.set('squareSize', newValue)}
87
90
  min={Chessboard.minSquareSize()} max={Chessboard.maxSquareSize()} step={1} valueLabelDisplay="on" color="primary"
88
91
  />
89
92
  </Box>
90
- <Box my={2} display="flex" flexDirection="row" alignItems="center">
91
- <Box mr={2}>
92
- <Typography>Colorset</Typography>
93
- <Select value={this.state.colorset} onChange={evt => this.set('colorset', evt.target.value)}>
93
+ <Stack direction="row" spacing={2} alignItems="center">
94
+ <FormControl variant="standard">
95
+ <InputLabel id="colorset-label">Colorset</InputLabel>
96
+ <Select labelId="colorset-label" sx={{ width: '8em' }} value={this.state.colorset} onChange={evt => this.set('colorset', evt.target.value)}>
94
97
  {Object.keys(Chessboard.colorsets()).sort().map(colorset => <MenuItem key={colorset} value={colorset}>{colorset}</MenuItem>)}
95
98
  </Select>
96
- </Box>
97
- <Box mx={2}>
98
- <Typography>Pieceset</Typography>
99
- <Select value={this.state.pieceset} onChange={evt => this.set('pieceset', evt.target.value)}>
99
+ </FormControl>
100
+ <FormControl variant="standard">
101
+ <InputLabel id="pieceset-label">Pieceset</InputLabel>
102
+ <Select labelId="pieceset-label" sx={{ width: '8em' }} value={this.state.pieceset} onChange={evt => this.set('pieceset', evt.target.value)}>
100
103
  {Object.keys(Chessboard.piecesets()).sort().map(pieceset => <MenuItem key={pieceset} value={pieceset}>{pieceset}</MenuItem>)}
101
104
  </Select>
102
- </Box>
103
- <Box ml={2}>
104
- <ButtonGroup color="primary" size="small">
105
- <Button onClick={() => this.set('position', 'empty')}>Clear</Button>
106
- <Button onClick={() => this.set('position', 'start')}>Reset</Button>
107
- <Button onClick={() => this.set('position', '8/8/8/8/8/4k3/q7/4K3 b - - 0 1')}>Set FEN</Button>
108
- <Button onClick={() => this.set('position', 'I\'m an invalid FEN string')}>Set ill-formed FEN</Button>
109
- </ButtonGroup>
110
- </Box>
111
- </Box>
105
+ </FormControl>
106
+ <ButtonGroup color="primary" size="small">
107
+ <Button onClick={() => this.set('position', 'empty')}>Clear</Button>
108
+ <Button onClick={() => this.set('position', 'start')}>Reset</Button>
109
+ <Button onClick={() => this.set('position', '8/8/8/8/8/4k3/q7/4K3 b - - 0 1')}>Set FEN</Button>
110
+ <Button onClick={() => this.set('position', 'I\'m an invalid FEN string')}>Set ill-formed FEN</Button>
111
+ </ButtonGroup>
112
+ </Stack>
112
113
  </>);
113
114
  }
114
115
 
115
116
  renderChessboard() {
116
117
  return (
117
- <Box my={2}>
118
+ <Box>
118
119
  <Chessboard
119
120
  position={this.state.position}
120
121
  flipped={this.state.flipped}
@@ -145,13 +146,7 @@ export default class Page extends React.Component {
145
146
  attributes.push(`coordinateVisible={${this.state.coordinateVisible}}`);
146
147
  attributes.push(`colorset="${this.state.colorset}"`);
147
148
  attributes.push(`pieceset="${this.state.pieceset}"`);
148
- return (
149
- <Box my={2}>
150
- <pre className="kokopu-demoCode">
151
- {buildComponentDemoCode('Chessboard', attributes)}
152
- </pre>
153
- </Box>
154
- );
149
+ return <pre className="kokopu-demoCode">{buildComponentDemoCode('Chessboard', attributes)}</pre>;
155
150
  }
156
151
 
157
152
  set(attributeName, newValue) {
@@ -26,18 +26,19 @@ import kokopu from 'kokopu';
26
26
  import { Chessboard, SquareMarkerIcon, TextMarkerIcon, ArrowMarkerIcon, flattenSquareMarkers, flattenTextMarkers, flattenArrowMarkers } from '../../src/index';
27
27
  import { buildComponentDemoCode } from './util';
28
28
 
29
- import Box from '@material-ui/core/Box';
30
- import Button from '@material-ui/core/Button';
31
- import ButtonGroup from '@material-ui/core/ButtonGroup';
32
- import FormControlLabel from '@material-ui/core/FormControlLabel';
33
- import MenuItem from '@material-ui/core/MenuItem';
34
- import Radio from '@material-ui/core/Radio';
35
- import RadioGroup from '@material-ui/core/RadioGroup';
36
- import Select from '@material-ui/core/Select';
37
- import Switch from '@material-ui/core/Switch';
38
- import ToggleButton from '@material-ui/lab/ToggleButton';
39
- import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup';
40
- import Typography from '@material-ui/core/Typography';
29
+ import Box from '@mui/material/Box';
30
+ import Button from '@mui/material/Button';
31
+ import ButtonGroup from '@mui/material/ButtonGroup';
32
+ import FormControlLabel from '@mui/material/FormControlLabel';
33
+ import MenuItem from '@mui/material/MenuItem';
34
+ import Radio from '@mui/material/Radio';
35
+ import RadioGroup from '@mui/material/RadioGroup';
36
+ import Select from '@mui/material/Select';
37
+ import Stack from '@mui/material/Stack';
38
+ import Switch from '@mui/material/Switch';
39
+ import ToggleButton from '@mui/material/ToggleButton';
40
+ import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
41
+ import Typography from '@mui/material/Typography';
41
42
 
42
43
  import './demo.css';
43
44
 
@@ -68,55 +69,53 @@ export default class Page extends React.Component {
68
69
 
69
70
  render() {
70
71
  return (
71
- <div>
72
+ <Stack spacing={2} mt={2}>
72
73
  {this.renderControls()}
73
74
  {this.renderChessboard()}
74
75
  {this.renderCode()}
75
- </div>
76
+ </Stack>
76
77
  );
77
78
  }
78
79
 
79
80
  renderControls() {
80
81
  return (<>
81
- <Box my={2} display="flex" flexDirection="row" alignItems="center">
82
+ <Stack direction="row" spacing={2} alignItems="center">
82
83
  <FormControlLabel label="Flip"
83
84
  control={<Switch checked={this.state.flipped} onChange={() => this.set('flipped', !this.state.flipped)} color="primary" />}
84
85
  />
85
86
  <Button color="primary" size="small" variant="contained" onClick={() => this.handleTurnClicked(kokopu.oppositeColor(this.state.position.turn()))}>
86
87
  Change turn
87
88
  </Button>
88
- <Box mx={2}>
89
- <ButtonGroup color="primary" size="small">
90
- <Button onClick={() => this.set('position', new kokopu.Position('empty'))}>Clear</Button>
91
- <Button onClick={() => this.set('position', new kokopu.Position())}>Reset</Button>
92
- </ButtonGroup>
93
- </Box>
94
- </Box>
95
- <Box my={2}>
89
+ <ButtonGroup color="primary" size="small">
90
+ <Button onClick={() => this.set('position', new kokopu.Position('empty'))}>Clear</Button>
91
+ <Button onClick={() => this.set('position', new kokopu.Position())}>Reset</Button>
92
+ </ButtonGroup>
93
+ </Stack>
94
+ <Box>
96
95
  <Typography gutterBottom>
97
96
  Edition mode
98
97
  </Typography>
99
98
  <RadioGroup value={this.state.interactionMode} onChange={evt => this.set('interactionMode', evt.target.value)}>
100
99
  <FormControlLabel value="" control={<Radio color="primary" />} label="None" />
101
- <Box display="flex" flexDirection="row">
100
+ <Stack direction="row" spacing={2} alignItems="center">
102
101
  <FormControlLabel value="addRemovePieces" control={<Radio color="primary" />} label="Add/remove pieces" />
103
102
  {this.renderPieceSelector()}
104
- </Box>
103
+ </Stack>
105
104
  <FormControlLabel value="movePieces" control={<Radio color="primary" />} label="Move pieces" />
106
105
  <FormControlLabel value="playMoves" control={<Radio color="primary" />} label="Move pieces (obeying chess rules)" />
107
- <Box display="flex" flexDirection="row">
106
+ <Stack direction="row" spacing={2} alignItems="center">
108
107
  <FormControlLabel value="editSquareMarkers" control={<Radio color="primary" />} label="Edit square annotations" />
109
108
  {this.renderMarkerColorSelector('squareMarkerColor', 'editSquareMarkers')}
110
- </Box>
111
- <Box display="flex" flexDirection="row">
109
+ </Stack>
110
+ <Stack direction="row" spacing={2} alignItems="center">
112
111
  <FormControlLabel value="editTextMarkers" control={<Radio color="primary" />} label="Edit text annotations" />
113
112
  {this.renderMarkerColorSelector('textMarkerColor', 'editTextMarkers')}
114
113
  {this.renderTextMarkerSymbolSelector()}
115
- </Box>
116
- <Box display="flex" flexDirection="row">
114
+ </Stack>
115
+ <Stack direction="row" spacing={2} alignItems="center">
117
116
  <FormControlLabel value="editArrowMarkers" control={<Radio color="primary" />} label="Edit arrow annotations" />
118
117
  {this.renderMarkerColorSelector('arrowMarkerColor', 'editArrowMarkers')}
119
- </Box>
118
+ </Stack>
120
119
  </RadioGroup>
121
120
  </Box>
122
121
  </>);
@@ -128,28 +127,24 @@ export default class Page extends React.Component {
128
127
  }
129
128
  let pieceset = Chessboard.piecesets()['cburnett'];
130
129
  return (
131
- <Box mx={2}>
132
- <Box my={0.5}>
133
- <ToggleButtonGroup value={this.state.pieceEditMode} exclusive size="small" onChange={(_, newMode) => this.setIfNonNull('pieceEditMode', newMode)}>
134
- <ToggleButton value="wk"><img src={pieceset.wk} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
135
- <ToggleButton value="wq"><img src={pieceset.wq} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
136
- <ToggleButton value="wr"><img src={pieceset.wr} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
137
- <ToggleButton value="wb"><img src={pieceset.wb} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
138
- <ToggleButton value="wn"><img src={pieceset.wn} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
139
- <ToggleButton value="wp"><img src={pieceset.wp} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
140
- </ToggleButtonGroup>
141
- </Box>
142
- <Box my={0.5}>
143
- <ToggleButtonGroup value={this.state.pieceEditMode} exclusive size="small" onChange={(_, newMode) => this.setIfNonNull('pieceEditMode', newMode)}>
144
- <ToggleButton value="bk"><img src={pieceset.bk} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
145
- <ToggleButton value="bq"><img src={pieceset.bq} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
146
- <ToggleButton value="br"><img src={pieceset.br} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
147
- <ToggleButton value="bb"><img src={pieceset.bb} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
148
- <ToggleButton value="bn"><img src={pieceset.bn} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
149
- <ToggleButton value="bp"><img src={pieceset.bp} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
150
- </ToggleButtonGroup>
151
- </Box>
152
- </Box>
130
+ <Stack spacing={0.5}>
131
+ <ToggleButtonGroup value={this.state.pieceEditMode} exclusive size="small" onChange={(_, newMode) => this.setIfNonNull('pieceEditMode', newMode)}>
132
+ <ToggleButton value="wk"><img src={pieceset.wk} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
133
+ <ToggleButton value="wq"><img src={pieceset.wq} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
134
+ <ToggleButton value="wr"><img src={pieceset.wr} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
135
+ <ToggleButton value="wb"><img src={pieceset.wb} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
136
+ <ToggleButton value="wn"><img src={pieceset.wn} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
137
+ <ToggleButton value="wp"><img src={pieceset.wp} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
138
+ </ToggleButtonGroup>
139
+ <ToggleButtonGroup value={this.state.pieceEditMode} exclusive size="small" onChange={(_, newMode) => this.setIfNonNull('pieceEditMode', newMode)}>
140
+ <ToggleButton value="bk"><img src={pieceset.bk} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
141
+ <ToggleButton value="bq"><img src={pieceset.bq} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
142
+ <ToggleButton value="br"><img src={pieceset.br} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
143
+ <ToggleButton value="bb"><img src={pieceset.bb} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
144
+ <ToggleButton value="bn"><img src={pieceset.bn} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
145
+ <ToggleButton value="bp"><img src={pieceset.bp} width={PIECE_ICON_SIZE} height={PIECE_ICON_SIZE} /></ToggleButton>
146
+ </ToggleButtonGroup>
147
+ </Stack>
153
148
  );
154
149
  }
155
150
 
@@ -158,7 +153,7 @@ export default class Page extends React.Component {
158
153
  return undefined;
159
154
  }
160
155
  return (
161
- <Select value={this.state.textMarkerSymbol} onChange={evt => this.set('textMarkerSymbol', evt.target.value)}>
156
+ <Select variant="standard" value={this.state.textMarkerSymbol} onChange={evt => this.set('textMarkerSymbol', evt.target.value)}>
162
157
  {[...'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'].map(mode => <MenuItem key={mode} value={mode}>{mode}</MenuItem>)}
163
158
  </Select>
164
159
  );
@@ -170,13 +165,11 @@ export default class Page extends React.Component {
170
165
  }
171
166
  let colorset = Chessboard.colorsets()['original'];
172
167
  return (
173
- <Box mx={2} my={0.5}>
174
- <ToggleButtonGroup value={this.state[attributeName]} exclusive size="small" onChange={(_, newColor) => this.setIfNonNull(attributeName, newColor)}>
175
- <ToggleButton className="kokopu-fixTextTransform" value="g">{this.renderColorButtonLabel(colorset.g)}</ToggleButton>
176
- <ToggleButton className="kokopu-fixTextTransform" value="r">{this.renderColorButtonLabel(colorset.r)}</ToggleButton>
177
- <ToggleButton className="kokopu-fixTextTransform" value="y">{this.renderColorButtonLabel(colorset.y)}</ToggleButton>
178
- </ToggleButtonGroup>
179
- </Box>
168
+ <ToggleButtonGroup value={this.state[attributeName]} exclusive size="small" onChange={(_, newColor) => this.setIfNonNull(attributeName, newColor)}>
169
+ <ToggleButton className="kokopu-fixTextTransform" value="g">{this.renderColorButtonLabel(colorset.g)}</ToggleButton>
170
+ <ToggleButton className="kokopu-fixTextTransform" value="r">{this.renderColorButtonLabel(colorset.r)}</ToggleButton>
171
+ <ToggleButton className="kokopu-fixTextTransform" value="y">{this.renderColorButtonLabel(colorset.y)}</ToggleButton>
172
+ </ToggleButtonGroup>
180
173
  );
181
174
  }
182
175
 
@@ -195,7 +188,7 @@ export default class Page extends React.Component {
195
188
 
196
189
  renderChessboard() {
197
190
  return (
198
- <Box my={2}>
191
+ <Box>
199
192
  <Chessboard
200
193
  position={this.state.position}
201
194
  flipped={this.state.flipped}
@@ -257,13 +250,7 @@ export default class Page extends React.Component {
257
250
  default:
258
251
  break;
259
252
  }
260
- return (
261
- <Box my={2}>
262
- <pre className="kokopu-demoCode">
263
- {buildComponentDemoCode('Chessboard', attributes)}
264
- </pre>
265
- </Box>
266
- );
253
+ return <pre className="kokopu-demoCode">{buildComponentDemoCode('Chessboard', attributes)}</pre>;
267
254
  }
268
255
 
269
256
  set(attributeName, newValue) {
@@ -26,12 +26,13 @@ import kokopu from 'kokopu';
26
26
  import { Chessboard } from '../../src/index';
27
27
  import { buildComponentDemoCode } from './util';
28
28
 
29
- import Box from '@material-ui/core/Box';
30
- import Button from '@material-ui/core/Button';
31
- import ButtonGroup from '@material-ui/core/ButtonGroup';
32
- import FormControlLabel from '@material-ui/core/FormControlLabel';
33
- import Switch from '@material-ui/core/Switch';
34
- import TextField from '@material-ui/core/TextField';
29
+ import Box from '@mui/material/Box';
30
+ import Button from '@mui/material/Button';
31
+ import ButtonGroup from '@mui/material/ButtonGroup';
32
+ import FormControlLabel from '@mui/material/FormControlLabel';
33
+ import Stack from '@mui/material/Stack';
34
+ import Switch from '@mui/material/Switch';
35
+ import TextField from '@mui/material/TextField';
35
36
 
36
37
  import './demo.css';
37
38
 
@@ -56,17 +57,17 @@ export default class Page extends React.Component {
56
57
 
57
58
  render() {
58
59
  return (
59
- <div>
60
+ <Stack spacing={2} mt={2}>
60
61
  {this.renderControls()}
61
62
  {this.renderChessboard()}
62
63
  {this.renderCode()}
63
- </div>
64
+ </Stack>
64
65
  );
65
66
  }
66
67
 
67
68
  renderControls() {
68
69
  return (<>
69
- <Box my={2}>
70
+ <Stack direction="row" spacing={2} alignItems="center">
70
71
  <FormControlLabel label="Flip"
71
72
  control={<Switch checked={this.state.flipped} onChange={() => this.set('flipped', !this.state.flipped)} color="primary" />}
72
73
  />
@@ -76,23 +77,21 @@ export default class Page extends React.Component {
76
77
  <FormControlLabel label="Animation" disabled={!this.state.positionAfter}
77
78
  control={<Switch checked={this.state.animated} onChange={() => this.set('animated', !this.state.animated)} color="primary" />}
78
79
  />
79
- </Box>
80
- <Box my={2} display="flex" flexDirection="row" alignItems="center">
81
- <TextField label="Move" value={this.state.editedMove} onChange={evt => this.set('editedMove', evt.target.value)} />
80
+ </Stack>
81
+ <Stack direction="row" spacing={2} alignItems="center">
82
+ <TextField label="Move" variant="standard" value={this.state.editedMove} onChange={evt => this.set('editedMove', evt.target.value)} />
82
83
  <Button color="primary" size="small" variant="contained" onClick={() => this.handlePlayClicked()}>Play</Button>
83
- <Box mx={2}>
84
- <ButtonGroup color="primary" size="small">
85
- <Button onClick={() => this.setPosition(new kokopu.Position('empty'))}>Clear</Button>
86
- <Button onClick={() => this.setPosition(new kokopu.Position())}>Reset</Button>
87
- </ButtonGroup>
88
- </Box>
89
- </Box>
84
+ <ButtonGroup color="primary" size="small">
85
+ <Button onClick={() => this.setPosition(new kokopu.Position('empty'))}>Clear</Button>
86
+ <Button onClick={() => this.setPosition(new kokopu.Position())}>Reset</Button>
87
+ </ButtonGroup>
88
+ </Stack>
90
89
  </>);
91
90
  }
92
91
 
93
92
  renderChessboard() {
94
93
  return (
95
- <Box my={2}>
94
+ <Box>
96
95
  <Chessboard
97
96
  position={this.state.position}
98
97
  move={this.state.playedMove}
@@ -115,13 +114,7 @@ export default class Page extends React.Component {
115
114
  }
116
115
  attributes.push(`moveArrowVisible={${this.state.moveArrowVisible}}`);
117
116
  attributes.push(`animated={${this.state.animated}}`);
118
- return (
119
- <Box my={2}>
120
- <pre className="kokopu-demoCode">
121
- {buildComponentDemoCode('Chessboard', attributes)}
122
- </pre>
123
- </Box>
124
- );
117
+ return <pre className="kokopu-demoCode">{buildComponentDemoCode('Chessboard', attributes)}</pre>;
125
118
  }
126
119
 
127
120
  set(attributeName, newValue) {
@@ -25,8 +25,9 @@ import React from 'react';
25
25
  import { Chessboard } from '../../src/index';
26
26
  import { buildComponentDemoCode } from './util';
27
27
 
28
- import Box from '@material-ui/core/Box';
29
- import Typography from '@material-ui/core/Typography';
28
+ import Box from '@mui/material/Box';
29
+ import Stack from '@mui/material/Stack';
30
+ import Typography from '@mui/material/Typography';
30
31
 
31
32
  import './demo.css';
32
33
 
@@ -63,17 +64,17 @@ export default class Page extends React.Component {
63
64
 
64
65
  render() {
65
66
  return (
66
- <div>
67
+ <Stack spacing={2} mt={2}>
67
68
  {this.renderControls()}
68
69
  {this.renderChessboard()}
69
70
  {this.renderCode()}
70
- </div>
71
+ </Stack>
71
72
  );
72
73
  }
73
74
 
74
75
  renderControls() {
75
76
  return (
76
- <Box my={2}>
77
+ <Box>
77
78
  <Typography>Resize the browser to see the chessboard adapt its size...</Typography>
78
79
  <Typography>{`Current browser width: ${this.state.windowWidth} px`}</Typography>
79
80
  </Box>
@@ -82,7 +83,7 @@ export default class Page extends React.Component {
82
83
 
83
84
  renderChessboard() {
84
85
  return (
85
- <Box my={2}>
86
+ <Box>
86
87
  <Chessboard squareSize={this.state.squareSize} smallScreenLimits={this.state.limits} />
87
88
  </Box>
88
89
  );
@@ -102,16 +103,14 @@ export default class Page extends React.Component {
102
103
  attributes.push(`squareSize={${this.state.squareSize}}`);
103
104
  attributes.push('smallScreenLimits={limits}');
104
105
  return (
105
- <Box my={2}>
106
- <pre className="kokopu-demoCode">
107
- {
108
- 'let limits = [\n' +
109
- limits.join('') +
110
- '];\n' +
111
- buildComponentDemoCode('Chessboard', attributes)
112
- }
113
- </pre>
114
- </Box>
106
+ <pre className="kokopu-demoCode">
107
+ {
108
+ 'let limits = [\n' +
109
+ limits.join('') +
110
+ '];\n' +
111
+ buildComponentDemoCode('Chessboard', attributes)
112
+ }
113
+ </pre>
115
114
  );
116
115
  }
117
116
 
@@ -0,0 +1,3 @@
1
+ ```js
2
+ <ErrorBox title="Something went wrong" message="This message describes what went wrong." />
3
+ ```
@@ -0,0 +1,50 @@
1
+ /******************************************************************************
2
+ * *
3
+ * This file is part of Kokopu-React, a JavaScript chess library. *
4
+ * Copyright (C) 2021 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 React from 'react';
24
+ import Styled from 'react-styleguidist/lib/client/rsg-components/Styled';
25
+
26
+ import logo from './kokopu-react-logo.png';
27
+
28
+ import './theming.css';
29
+
30
+
31
+ const styles = ({ color, fontFamily, fontSize }) => ({
32
+ logo: {
33
+ color: color.base,
34
+ margin: 0,
35
+ fontFamily: fontFamily.base,
36
+ fontSize: fontSize.h4,
37
+ fontWeight: 'normal',
38
+ },
39
+ });
40
+
41
+ function LogoRenderer({ classes, children }) {
42
+ return (<>
43
+ <div className="kokopu-logo">
44
+ <img src={logo} />
45
+ </div>
46
+ <h1 className={classes.logo}>{children}</h1>
47
+ </>);
48
+ }
49
+
50
+ export default Styled(styles)(LogoRenderer);
@@ -0,0 +1,29 @@
1
+ /******************************************************************************
2
+ * *
3
+ * This file is part of Kokopu-React, a JavaScript chess library. *
4
+ * Copyright (C) 2021 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
+ .kokopu-logo {
24
+ text-align: center;
25
+ }
26
+
27
+ footer {
28
+ display: none !important;
29
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kokopu-react",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "A React-based library to create and display chessboard components.",
5
5
  "keywords": [
6
6
  "chess",
@@ -29,26 +29,27 @@
29
29
  ".nycrc.yml"
30
30
  ],
31
31
  "dependencies": {
32
- "kokopu": "^2.0.0",
32
+ "kokopu": "^2.1.0",
33
33
  "prop-types": "^15.7.2",
34
34
  "react": "^17.0.2",
35
35
  "react-draggable": "^4.4.4",
36
36
  "react-motion": "^0.5.2"
37
37
  },
38
38
  "devDependencies": {
39
- "@babel/cli": "^7.15.4",
39
+ "@babel/cli": "^7.15.7",
40
40
  "@babel/core": "^7.15.5",
41
41
  "@babel/preset-env": "^7.15.6",
42
42
  "@babel/preset-react": "^7.14.5",
43
- "@material-ui/core": "^4.12.3",
44
- "@material-ui/lab": "^4.0.0-alpha.60",
43
+ "@emotion/react": "^11.4.1",
44
+ "@emotion/styled": "^11.3.0",
45
+ "@mui/material": "^5.0.1",
45
46
  "babel-loader": "^8.2.2",
46
47
  "babel-plugin-istanbul": "^6.0.0",
47
48
  "copy-webpack-plugin": "^9.0.1",
48
49
  "coveralls": "^3.1.1",
49
- "css-loader": "^6.2.0",
50
+ "css-loader": "^6.3.0",
50
51
  "eslint": "^7.32.0",
51
- "eslint-plugin-react": "^7.25.1",
52
+ "eslint-plugin-react": "^7.26.0",
52
53
  "html-webpack-plugin": "^5.3.2",
53
54
  "img-diff-js": "^0.5.2",
54
55
  "mocha": "^9.1.1",
@@ -59,9 +60,9 @@
59
60
  "react-styleguidist": "^11.1.7",
60
61
  "selenium-webdriver": "^4.0.0-rc-1",
61
62
  "ssh2-sftp-client": "^7.0.4",
62
- "style-loader": "^3.2.1",
63
+ "style-loader": "^3.3.0",
63
64
  "unit.js": "^2.1.1",
64
- "webpack": "^5.52.1",
65
+ "webpack": "^5.53.0",
65
66
  "webpack-cli": "^4.8.0"
66
67
  },
67
68
  "scripts": {
package/src/Chessboard.js CHANGED
@@ -29,7 +29,8 @@ import kokopu from 'kokopu';
29
29
  import colorsets from './impl/colorsets';
30
30
  import piecesets from './impl/piecesets';
31
31
  import ArrowTip from './impl/ArrowTip';
32
- import ErrorBox from './impl/ErrorBox';
32
+ import ErrorBox from './ErrorBox';
33
+ import i18n from './i18n';
33
34
  import { parseSquareMarkers, parseTextMarkers, parseArrowMarkers } from './markers';
34
35
  import { MIN_SQUARE_SIZE, MAX_SQUARE_SIZE, sanitizeInteger, generateRandomId, isValidSquare, isValidVector, isValidColor, isValidSymbol } from './impl/util';
35
36
 
@@ -82,10 +83,10 @@ export default class Chessboard extends React.Component {
82
83
  // Compute the current position.
83
84
  let info = this.getPositionAndMoveInfo();
84
85
  if (info.positionError) {
85
- return <ErrorBox title="Error while analysing a FEN string." message={info.message}></ErrorBox>;
86
+ return <ErrorBox title={i18n.INVALID_FEN_ERROR_TITLE} message={info.message}></ErrorBox>;
86
87
  }
87
88
  else if (info.moveError) {
88
- return <ErrorBox title="Invalid move notation." message={info.message}></ErrorBox>;
89
+ return <ErrorBox title={i18n.INVALID_NOTATION_ERROR_TITLE} message={info.message}></ErrorBox>;
89
90
  }
90
91
  let { position, move, positionBefore } = info;
91
92
 
@@ -938,7 +939,7 @@ function parsePosition(position) {
938
939
  }
939
940
  }
940
941
  else {
941
- return { error: true, message: 'Invalid "position" attribute.' };
942
+ return { error: true, message: i18n.INVALID_POSITION_ATTRIBUTE_ERROR_MESSAGE };
942
943
  }
943
944
  }
944
945
 
@@ -965,7 +966,7 @@ function parseMove(position, move) {
965
966
  }
966
967
  }
967
968
  else {
968
- return { error: true, message: 'Invalid "move" attribute.' };
969
+ return { error: true, message: i18n.INVALID_MOVE_ATTRIBUTE_ERROR_MESSAGE };
969
970
  }
970
971
  }
971
972
 
@@ -23,7 +23,7 @@
23
23
  import PropTypes from 'prop-types';
24
24
  import React from 'react';
25
25
 
26
- import '../css/error_box.css';
26
+ import './css/error_box.css';
27
27
 
28
28
 
29
29
  /**
package/src/i18n.js ADDED
@@ -0,0 +1,30 @@
1
+ /******************************************************************************
2
+ * *
3
+ * This file is part of Kokopu-React, a JavaScript chess library. *
4
+ * Copyright (C) 2021 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
+ const i18n = {
24
+ INVALID_FEN_ERROR_TITLE: 'Invalid FEN string.',
25
+ INVALID_NOTATION_ERROR_TITLE: 'Invalid move notation.',
26
+ INVALID_POSITION_ATTRIBUTE_ERROR_MESSAGE: 'Invalid "position" attribute.',
27
+ INVALID_MOVE_ATTRIBUTE_ERROR_MESSAGE: 'Invalid "move" attribute.',
28
+ };
29
+
30
+ export default i18n;
package/src/index.js CHANGED
@@ -21,6 +21,7 @@
21
21
 
22
22
 
23
23
  export { flattenSquareMarkers, parseSquareMarkers, flattenTextMarkers, parseTextMarkers, flattenArrowMarkers, parseArrowMarkers } from './markers';
24
+ export { default as i18n } from './i18n';
24
25
  export { default as Chessboard } from './Chessboard';
25
26
  export { default as SquareMarkerIcon } from './SquareMarkerIcon';
26
27
  export { default as TextMarkerIcon } from './TextMarkerIcon';