kokopu-react 1.5.3 → 1.5.4

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,10 @@
1
1
  ChangeLog
2
2
  =========
3
3
 
4
+ 1.5.4 (May 1, 2022)
5
+ -------------------
6
+ * Provide method `Chessboard#size(..)` to retrieve the width/height of a `Chessboard` component instance.
7
+
4
8
  1.5.3 (April 30, 2022)
5
9
  ----------------------
6
10
  * Add method `Movetext#focus()`.
package/README.md CHANGED
@@ -3,7 +3,7 @@ Kokopu-React
3
3
 
4
4
  <img align="right" width="96" height="96" src="graphics/logo.svg" />
5
5
 
6
- Kokopu-React is a [React](https://reactjs.org/)-based library to create and display chessboard components.
6
+ Kokopu-React is a [React](https://reactjs.org/)-based library to create and display chessboard and chess-related components.
7
7
  Kokopu-React is built on top of [Kokopu](https://www.npmjs.com/package/kokopu), a headless library that
8
8
  implements all the chess logic (game rules, parsing of [FEN](https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation)
9
9
  and [PGN](https://en.wikipedia.org/wiki/Portable_Game_Notation) formats...).
@@ -984,6 +984,46 @@ var Chessboard = /*#__PURE__*/function (_React$Component) {
984
984
  value: function getArrowTipId(color) {
985
985
  return 'kokopu-arrowTip-' + color + '-' + this.arrowTipIdSuffix;
986
986
  }
987
+ /**
988
+ * Return the size of the chessboard, assuming it is built with the given attributes.
989
+ *
990
+ * @param {number} squareSize
991
+ * @param {boolean} coordinateVisible
992
+ * @param {{width:number, squareSize:number, coordinateVisible:boolean}[]} smallScreenLimits
993
+ * @returns {{width:number, height:number}}
994
+ * @public
995
+ */
996
+
997
+ }], [{
998
+ key: "size",
999
+ value: function size(squareSize, coordinateVisible, smallScreenLimits) {
1000
+ // Enforce small-screen limits, if any.
1001
+ if (typeof window !== 'undefined') {
1002
+ var squareSizeLimit = computeSmallScreenLimits('squareSize', smallScreenLimits, window.innerWidth);
1003
+ var coordinateVisibleLimit = computeSmallScreenLimits('coordinateVisible', smallScreenLimits, window.innerWidth);
1004
+
1005
+ if (!isNaN(squareSizeLimit)) {
1006
+ squareSize = (0, _util.sanitizeInteger)(squareSizeLimit, _util.MIN_SQUARE_SIZE, squareSize);
1007
+ }
1008
+
1009
+ coordinateVisible = coordinateVisible && (coordinateVisibleLimit === undefined || coordinateVisibleLimit);
1010
+ } // Compute the dimensions.
1011
+
1012
+
1013
+ var width = 9 * squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * squareSize);
1014
+ var height = 8 * squareSize;
1015
+
1016
+ if (coordinateVisible) {
1017
+ var fontSize = computeCoordinateFontSize(squareSize);
1018
+ width += Math.round(RANK_COORDINATE_WIDTH_FACTOR * fontSize);
1019
+ height += Math.round(FILE_COORDINATE_HEIGHT_FACTOR * fontSize);
1020
+ }
1021
+
1022
+ return {
1023
+ width: width,
1024
+ height: height
1025
+ };
1026
+ }
987
1027
  /**
988
1028
  * Return the maximum square size that would allow the chessboard to fit in a rectangle of size `width x height`.
989
1029
  *
@@ -995,7 +1035,7 @@ var Chessboard = /*#__PURE__*/function (_React$Component) {
995
1035
  * @public
996
1036
  */
997
1037
 
998
- }], [{
1038
+ }, {
999
1039
  key: "adaptSquareSize",
1000
1040
  value: function adaptSquareSize(width, height, coordinateVisible, smallScreenLimits) {
1001
1041
  var maxSquareSize = _util.MAX_SQUARE_SIZE; // Enforce small-screen limits, if any.
@@ -96,7 +96,7 @@ var Movetext = /*#__PURE__*/function (_React$Component) {
96
96
 
97
97
  return /*#__PURE__*/_react["default"].createElement("div", {
98
98
  className: "kokopu-movetext"
99
- }, this.renderHeaders(info.game), this.renderBody(info.game), this.renderFocusField());
99
+ }, this.renderHeaders(info.game), this.renderBody(info.game), this.renderFocusField(info.game));
100
100
  }
101
101
  }, {
102
102
  key: "renderHeaders",
@@ -233,7 +233,7 @@ var Movetext = /*#__PURE__*/function (_React$Component) {
233
233
  }
234
234
  }, {
235
235
  key: "renderFocusField",
236
- value: function renderFocusField() {
236
+ value: function renderFocusField(game) {
237
237
  var _this2 = this;
238
238
 
239
239
  if (this.props.interactionMode !== 'selectMove') {
@@ -247,7 +247,7 @@ var Movetext = /*#__PURE__*/function (_React$Component) {
247
247
  href: "#",
248
248
  ref: this.focusFieldRef,
249
249
  onKeyDown: function onKeyDown(evt) {
250
- return _this2.handleKeyDownInFocusField(evt);
250
+ return _this2.handleKeyDownInFocusField(evt, game);
251
251
  }
252
252
  }));
253
253
  }
@@ -522,7 +522,7 @@ var Movetext = /*#__PURE__*/function (_React$Component) {
522
522
  }
523
523
  }, {
524
524
  key: "handleKeyDownInFocusField",
525
- value: function handleKeyDownInFocusField(evt) {
525
+ value: function handleKeyDownInFocusField(evt, game) {
526
526
  if (evt.key !== 'Home' && evt.key !== 'ArrowLeft' && evt.key !== 'ArrowRight' && evt.key !== 'End') {
527
527
  return;
528
528
  }
@@ -533,9 +533,6 @@ var Movetext = /*#__PURE__*/function (_React$Component) {
533
533
  return;
534
534
  }
535
535
 
536
- var _parseGame = parseGame(this.props.game, this.props.gameIndex),
537
- game = _parseGame.game;
538
-
539
536
  var nodeId = undefined;
540
537
  var evtOrigin = '';
541
538
 
package/doc_src/home.md CHANGED
@@ -1,4 +1,4 @@
1
- Kokopu-React is a [React](https://reactjs.org/)-based library to create and display chessboard components.
1
+ Kokopu-React is a [React](https://reactjs.org/)-based library to create and display chessboard and chess-related components.
2
2
  Kokopu-React is built on top of [Kokopu](https://www.npmjs.com/package/kokopu), a headless library that
3
3
  implements all the chess logic (game rules, parsing of [FEN](https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation)
4
4
  and [PGN](https://en.wikipedia.org/wiki/Portable_Game_Notation) formats...).
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kokopu-react",
3
- "version": "1.5.3",
4
- "description": "A React-based library to create and display chessboard components.",
3
+ "version": "1.5.4",
4
+ "description": "A React-based library to create and display chessboard and chess-related components.",
5
5
  "keywords": [
6
6
  "chess",
7
7
  "react",
package/src/Chessboard.js CHANGED
@@ -623,6 +623,38 @@ export default class Chessboard extends React.Component {
623
623
  return 'kokopu-arrowTip-' + color + '-' + this.arrowTipIdSuffix;
624
624
  }
625
625
 
626
+ /**
627
+ * Return the size of the chessboard, assuming it is built with the given attributes.
628
+ *
629
+ * @param {number} squareSize
630
+ * @param {boolean} coordinateVisible
631
+ * @param {{width:number, squareSize:number, coordinateVisible:boolean}[]} smallScreenLimits
632
+ * @returns {{width:number, height:number}}
633
+ * @public
634
+ */
635
+ static size(squareSize, coordinateVisible, smallScreenLimits) {
636
+
637
+ // Enforce small-screen limits, if any.
638
+ if (typeof window !== 'undefined') {
639
+ let squareSizeLimit = computeSmallScreenLimits('squareSize', smallScreenLimits, window.innerWidth);
640
+ let coordinateVisibleLimit = computeSmallScreenLimits('coordinateVisible', smallScreenLimits, window.innerWidth);
641
+ if (!isNaN(squareSizeLimit)) {
642
+ squareSize = sanitizeInteger(squareSizeLimit, MIN_SQUARE_SIZE, squareSize);
643
+ }
644
+ coordinateVisible = coordinateVisible && (coordinateVisibleLimit === undefined || coordinateVisibleLimit);
645
+ }
646
+
647
+ // Compute the dimensions.
648
+ let width = 9 * squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * squareSize);
649
+ let height = 8 * squareSize;
650
+ if (coordinateVisible) {
651
+ let fontSize = computeCoordinateFontSize(squareSize);
652
+ width += Math.round(RANK_COORDINATE_WIDTH_FACTOR * fontSize);
653
+ height += Math.round(FILE_COORDINATE_HEIGHT_FACTOR * fontSize);
654
+ }
655
+ return { width: width, height: height };
656
+ }
657
+
626
658
  /**
627
659
  * Return the maximum square size that would allow the chessboard to fit in a rectangle of size `width x height`.
628
660
  *
package/src/Movetext.js CHANGED
@@ -52,7 +52,7 @@ export default class Movetext extends React.Component {
52
52
  <div className="kokopu-movetext">
53
53
  {this.renderHeaders(info.game)}
54
54
  {this.renderBody(info.game)}
55
- {this.renderFocusField()}
55
+ {this.renderFocusField(info.game)}
56
56
  </div>
57
57
  );
58
58
  }
@@ -132,13 +132,13 @@ export default class Movetext extends React.Component {
132
132
  return <div className="kokopu-header-annotator" key="annotator">{sanitizeHtml(annotator)}</div>;
133
133
  }
134
134
 
135
- renderFocusField() {
135
+ renderFocusField(game) {
136
136
  if (this.props.interactionMode !== 'selectMove') {
137
137
  return undefined;
138
138
  }
139
139
  return (
140
140
  <div className="kokopu-focusFieldContainer">
141
- <a className="kokopu-focusField" href="#" ref={this.focusFieldRef} onKeyDown={evt => this.handleKeyDownInFocusField(evt)}></a>
141
+ <a className="kokopu-focusField" href="#" ref={this.focusFieldRef} onKeyDown={evt => this.handleKeyDownInFocusField(evt, game)}></a>
142
142
  </div>
143
143
  );
144
144
  }
@@ -330,7 +330,7 @@ export default class Movetext extends React.Component {
330
330
  return comment ? comment : undefined;
331
331
  }
332
332
 
333
- handleKeyDownInFocusField(evt) {
333
+ handleKeyDownInFocusField(evt, game) {
334
334
  if (evt.key !== 'Home' && evt.key !== 'ArrowLeft' && evt.key !== 'ArrowRight' && evt.key !== 'End') {
335
335
  return;
336
336
  }
@@ -338,7 +338,6 @@ export default class Movetext extends React.Component {
338
338
  if (!this.props.selection) {
339
339
  return;
340
340
  }
341
- let { game } = parseGame(this.props.game, this.props.gameIndex);
342
341
  let nodeId = undefined;
343
342
  let evtOrigin = '';
344
343
  if (evt.key === 'Home') {
@@ -24,19 +24,33 @@ let { Chessboard } = require('../build/test_headless/index');
24
24
  let test = require('unit.js');
25
25
 
26
26
 
27
+ function testAdaptSquareSize(expectedSquareSize, width, height, coordinateVisible, smallScreenLimits) {
28
+ test.value(Chessboard.adaptSquareSize(width, height, coordinateVisible, smallScreenLimits)).is(expectedSquareSize);
29
+
30
+ let actualSize = Chessboard.size(expectedSquareSize, coordinateVisible, smallScreenLimits);
31
+ test.value(actualSize.width <= width && actualSize.height <= height).isTrue();
32
+ }
33
+
34
+ function testAdaptSquareSizeWithIncrement(expectedSquareSize, width, height, coordinateVisible, smallScreenLimits) {
35
+ testAdaptSquareSize(expectedSquareSize, width, height, coordinateVisible, smallScreenLimits);
36
+
37
+ let actualSizeIncremented = Chessboard.size(expectedSquareSize + 1, coordinateVisible, smallScreenLimits);
38
+ test.value(actualSizeIncremented.width > width || actualSizeIncremented.height > height).isTrue();
39
+ }
40
+
27
41
  describe('Adapt square-size', () => {
28
42
 
29
43
  it('Very small', () => { test.value(Chessboard.adaptSquareSize(10, 10, false)).is(Chessboard.minSquareSize()); });
30
44
  it('Very large', () => { test.value(Chessboard.adaptSquareSize(9999, 9999, true)).is(Chessboard.maxSquareSize()); });
31
45
 
32
- it('Size 185x300 with coordinates', () => { test.value(Chessboard.adaptSquareSize(185, 300, true)).is(19); });
33
- it('Size 185x300 without coordinates', () => { test.value(Chessboard.adaptSquareSize(185, 300, false)).is(20); });
34
- it('Size 300x200 with coordinates', () => { test.value(Chessboard.adaptSquareSize(300, 200, true)).is(23); });
35
- it('Size 300x200 without coordinates', () => { test.value(Chessboard.adaptSquareSize(300, 200, false)).is(25); });
36
- it('Size 375x500 with coordinates', () => { test.value(Chessboard.adaptSquareSize(375, 500, true)).is(40); });
37
- it('Size 375x500 without coordinates', () => { test.value(Chessboard.adaptSquareSize(375, 500, false)).is(41); });
38
- it('Size 600x450 with coordinates', () => { test.value(Chessboard.adaptSquareSize(600, 450, true)).is(54); });
39
- it('Size 600x450 without coordinates', () => { test.value(Chessboard.adaptSquareSize(600, 450, false)).is(56); });
46
+ it('Size 185x300 with coordinates', () => testAdaptSquareSizeWithIncrement(19, 185, 300, true));
47
+ it('Size 185x300 without coordinates', () => testAdaptSquareSizeWithIncrement(20, 185, 300, false));
48
+ it('Size 300x200 with coordinates', () => testAdaptSquareSizeWithIncrement(23, 300, 200, true));
49
+ it('Size 300x200 without coordinates', () => testAdaptSquareSizeWithIncrement(25, 300, 200, false));
50
+ it('Size 375x500 with coordinates', () => testAdaptSquareSizeWithIncrement(40, 375, 500, true));
51
+ it('Size 375x500 without coordinates', () => testAdaptSquareSizeWithIncrement(41, 375, 500, false));
52
+ it('Size 600x450 with coordinates', () => testAdaptSquareSizeWithIncrement(54, 600, 450, true));
53
+ it('Size 600x450 without coordinates', () => testAdaptSquareSizeWithIncrement(56, 600, 450, false));
40
54
  });
41
55
 
42
56
  describe('Adapt square-size with small-screen limits', () => {
@@ -58,18 +72,18 @@ describe('Adapt square-size with small-screen limits', () => {
58
72
 
59
73
  it('Window-limited', () => {
60
74
  window.innerWidth = 640;
61
- test.value(Chessboard.adaptSquareSize(9999, 9999, true, limits)).is(32);
75
+ testAdaptSquareSize(32, 9999, 9999, true, limits);
62
76
  });
63
77
  it('Available-space-limited 1', () => {
64
78
  window.innerWidth = 800;
65
- test.value(Chessboard.adaptSquareSize(375, 500, true, limits)).is(40);
79
+ testAdaptSquareSize(40, 375, 500, true, limits);
66
80
  });
67
81
  it('Available-space-limited 2', () => {
68
82
  window.innerWidth = 800;
69
- test.value(Chessboard.adaptSquareSize(375, 500, false, limits)).is(41);
83
+ testAdaptSquareSize(41, 375, 500, false, limits);
70
84
  });
71
85
  it('Force hidden coordinates', () => {
72
86
  window.innerWidth = 600;
73
- test.value(Chessboard.adaptSquareSize(185, 300, true, limits)).is(20);
87
+ testAdaptSquareSize(20, 185, 300, true, limits);
74
88
  });
75
89
  });