@dxos/react-ui-gameboard 0.7.5-main.ff8607b → 0.7.5-staging.b81e783

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.
Files changed (85) hide show
  1. package/dist/lib/browser/index.mjs +147 -44
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +147 -43
  5. package/dist/lib/node/index.cjs.map +3 -3
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +147 -44
  8. package/dist/lib/node-esm/index.mjs.map +3 -3
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/Board/Board.d.ts +2 -2
  11. package/dist/types/src/Board/Board.d.ts.map +1 -1
  12. package/dist/types/src/Board/Piece.d.ts +1 -1
  13. package/dist/types/src/Board/Piece.d.ts.map +1 -1
  14. package/dist/types/src/Board/Square.d.ts +1 -1
  15. package/dist/types/src/Board/Square.d.ts.map +1 -1
  16. package/dist/types/src/Board/context.d.ts +7 -7
  17. package/dist/types/src/Board/context.d.ts.map +1 -1
  18. package/dist/types/src/Board/index.d.ts +1 -0
  19. package/dist/types/src/Board/index.d.ts.map +1 -1
  20. package/dist/types/src/Board/types.d.ts +6 -2
  21. package/dist/types/src/Board/types.d.ts.map +1 -1
  22. package/dist/types/src/Chessboard/Chessboard.d.ts +1 -1
  23. package/dist/types/src/Chessboard/Chessboard.d.ts.map +1 -1
  24. package/dist/types/src/Chessboard/Chessboard.stories.d.ts +3 -2
  25. package/dist/types/src/Chessboard/Chessboard.stories.d.ts.map +1 -1
  26. package/dist/types/src/Chessboard/chess.d.ts +5 -9
  27. package/dist/types/src/Chessboard/chess.d.ts.map +1 -1
  28. package/dist/types/src/gen/pieces/chess/alpha/bB.d.ts +1 -2
  29. package/dist/types/src/gen/pieces/chess/alpha/bB.d.ts.map +1 -1
  30. package/dist/types/src/gen/pieces/chess/alpha/bK.d.ts +1 -2
  31. package/dist/types/src/gen/pieces/chess/alpha/bK.d.ts.map +1 -1
  32. package/dist/types/src/gen/pieces/chess/alpha/bN.d.ts +1 -2
  33. package/dist/types/src/gen/pieces/chess/alpha/bN.d.ts.map +1 -1
  34. package/dist/types/src/gen/pieces/chess/alpha/bP.d.ts +1 -2
  35. package/dist/types/src/gen/pieces/chess/alpha/bP.d.ts.map +1 -1
  36. package/dist/types/src/gen/pieces/chess/alpha/bQ.d.ts +1 -2
  37. package/dist/types/src/gen/pieces/chess/alpha/bQ.d.ts.map +1 -1
  38. package/dist/types/src/gen/pieces/chess/alpha/bR.d.ts +1 -2
  39. package/dist/types/src/gen/pieces/chess/alpha/bR.d.ts.map +1 -1
  40. package/dist/types/src/gen/pieces/chess/alpha/wB.d.ts +1 -2
  41. package/dist/types/src/gen/pieces/chess/alpha/wB.d.ts.map +1 -1
  42. package/dist/types/src/gen/pieces/chess/alpha/wK.d.ts +1 -2
  43. package/dist/types/src/gen/pieces/chess/alpha/wK.d.ts.map +1 -1
  44. package/dist/types/src/gen/pieces/chess/alpha/wN.d.ts +1 -2
  45. package/dist/types/src/gen/pieces/chess/alpha/wN.d.ts.map +1 -1
  46. package/dist/types/src/gen/pieces/chess/alpha/wP.d.ts +1 -2
  47. package/dist/types/src/gen/pieces/chess/alpha/wP.d.ts.map +1 -1
  48. package/dist/types/src/gen/pieces/chess/alpha/wQ.d.ts +1 -2
  49. package/dist/types/src/gen/pieces/chess/alpha/wQ.d.ts.map +1 -1
  50. package/dist/types/src/gen/pieces/chess/alpha/wR.d.ts +1 -2
  51. package/dist/types/src/gen/pieces/chess/alpha/wR.d.ts.map +1 -1
  52. package/dist/types/src/gen/pieces/chess/cburnett/bB.d.ts +1 -2
  53. package/dist/types/src/gen/pieces/chess/cburnett/bB.d.ts.map +1 -1
  54. package/dist/types/src/gen/pieces/chess/cburnett/bK.d.ts +1 -2
  55. package/dist/types/src/gen/pieces/chess/cburnett/bK.d.ts.map +1 -1
  56. package/dist/types/src/gen/pieces/chess/cburnett/bN.d.ts +1 -2
  57. package/dist/types/src/gen/pieces/chess/cburnett/bN.d.ts.map +1 -1
  58. package/dist/types/src/gen/pieces/chess/cburnett/bP.d.ts +1 -2
  59. package/dist/types/src/gen/pieces/chess/cburnett/bP.d.ts.map +1 -1
  60. package/dist/types/src/gen/pieces/chess/cburnett/bQ.d.ts +1 -2
  61. package/dist/types/src/gen/pieces/chess/cburnett/bQ.d.ts.map +1 -1
  62. package/dist/types/src/gen/pieces/chess/cburnett/bR.d.ts +1 -2
  63. package/dist/types/src/gen/pieces/chess/cburnett/bR.d.ts.map +1 -1
  64. package/dist/types/src/gen/pieces/chess/cburnett/wB.d.ts +1 -2
  65. package/dist/types/src/gen/pieces/chess/cburnett/wB.d.ts.map +1 -1
  66. package/dist/types/src/gen/pieces/chess/cburnett/wK.d.ts +1 -2
  67. package/dist/types/src/gen/pieces/chess/cburnett/wK.d.ts.map +1 -1
  68. package/dist/types/src/gen/pieces/chess/cburnett/wN.d.ts +1 -2
  69. package/dist/types/src/gen/pieces/chess/cburnett/wN.d.ts.map +1 -1
  70. package/dist/types/src/gen/pieces/chess/cburnett/wP.d.ts +1 -2
  71. package/dist/types/src/gen/pieces/chess/cburnett/wP.d.ts.map +1 -1
  72. package/dist/types/src/gen/pieces/chess/cburnett/wQ.d.ts +1 -2
  73. package/dist/types/src/gen/pieces/chess/cburnett/wQ.d.ts.map +1 -1
  74. package/dist/types/src/gen/pieces/chess/cburnett/wR.d.ts +1 -2
  75. package/dist/types/src/gen/pieces/chess/cburnett/wR.d.ts.map +1 -1
  76. package/package.json +12 -11
  77. package/src/Board/Board.tsx +24 -6
  78. package/src/Board/Piece.tsx +10 -9
  79. package/src/Board/Square.tsx +1 -1
  80. package/src/Board/context.ts +9 -2
  81. package/src/Board/index.ts +1 -0
  82. package/src/Board/types.ts +6 -2
  83. package/src/Chessboard/Chessboard.stories.tsx +45 -3
  84. package/src/Chessboard/Chessboard.tsx +76 -9
  85. package/src/Chessboard/chess.ts +31 -10
@@ -33,8 +33,10 @@ __export(node_exports, {
33
33
  ChessModel: () => ChessModel,
34
34
  ChessPieces: () => ChessPieces,
35
35
  Chessboard: () => Chessboard,
36
+ Container: () => Container,
36
37
  Piece: () => Piece,
37
38
  Square: () => Square,
39
+ boardStyles: () => boardStyles,
38
40
  getRelativeBounds: () => getRelativeBounds,
39
41
  getSquareColor: () => getSquareColor,
40
42
  isEqualLocation: () => isEqualLocation,
@@ -45,7 +47,6 @@ __export(node_exports, {
45
47
  mapPieces: () => mapPieces,
46
48
  posToLocation: () => posToLocation,
47
49
  stringToLocation: () => stringToLocation,
48
- styles: () => styles,
49
50
  useBoardContext: () => useBoardContext
50
51
  });
51
52
  module.exports = __toCommonJS(node_exports);
@@ -89,6 +90,8 @@ var React16 = __toESM(require("react"));
89
90
  var import_react6 = __toESM(require("react"));
90
91
  var import_react_resize_detector = require("react-resize-detector");
91
92
  var import_react_ui2 = require("@dxos/react-ui");
93
+ var import_react_ui_theme5 = require("@dxos/react-ui-theme");
94
+ var import_util = require("@dxos/util");
92
95
  var __defProp2 = Object.defineProperty;
93
96
  var __export2 = (target, all) => {
94
97
  for (var name in all)
@@ -125,14 +128,30 @@ var Container = /* @__PURE__ */ (0, import_react3.forwardRef)(({ children, class
125
128
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-gameboard/src/Board/Board.tsx";
126
129
  var Root = ({ children, classNames, model, onDrop }) => {
127
130
  const [dragging, setDragging] = (0, import_react2.useState)(false);
131
+ const [promoting, setPromoting] = (0, import_react2.useState)();
132
+ const onPromotion = (0, import_react2.useCallback)((move) => {
133
+ (0, import_log.log)("onPromotion", {
134
+ move
135
+ }, {
136
+ F: __dxlog_file,
137
+ L: 32,
138
+ S: void 0,
139
+ C: (f, a) => f(...a)
140
+ });
141
+ setPromoting(void 0);
142
+ onDrop?.(move);
143
+ }, []);
128
144
  (0, import_react2.useEffect)(() => {
145
+ if (!model) {
146
+ return;
147
+ }
129
148
  return (0, import_adapter.monitorForElements)({
130
149
  onDragStart: ({ source }) => {
131
150
  (0, import_log.log)("onDragStart", {
132
151
  source
133
152
  }, {
134
153
  F: __dxlog_file,
135
- L: 33,
154
+ L: 45,
136
155
  S: void 0,
137
156
  C: (f, a) => f(...a)
138
157
  });
@@ -144,7 +163,7 @@ var Root = ({ children, classNames, model, onDrop }) => {
144
163
  location
145
164
  }, {
146
165
  F: __dxlog_file,
147
- L: 37,
166
+ L: 49,
148
167
  S: void 0,
149
168
  C: (f, a) => f(...a)
150
169
  });
@@ -157,19 +176,31 @@ var Root = ({ children, classNames, model, onDrop }) => {
157
176
  if (!isLocation(targetLocation) || !isPiece(piece)) {
158
177
  return;
159
178
  }
160
- onDrop?.({
161
- source: piece.location,
162
- target: targetLocation,
179
+ const move = {
180
+ from: piece.location,
181
+ to: targetLocation,
163
182
  piece: piece.type
164
- });
183
+ };
184
+ if (model.canPromote?.(move)) {
185
+ setPromoting({
186
+ ...piece,
187
+ location: targetLocation
188
+ });
189
+ } else {
190
+ onDrop?.(move);
191
+ }
165
192
  setDragging(false);
166
193
  }
167
194
  });
168
- }, []);
195
+ }, [
196
+ model
197
+ ]);
169
198
  return /* @__PURE__ */ import_react2.default.createElement(BoardContext.Provider, {
170
199
  value: {
171
200
  model,
172
- dragging
201
+ dragging,
202
+ promoting,
203
+ onPromotion
173
204
  }
174
205
  }, /* @__PURE__ */ import_react2.default.createElement(Container, {
175
206
  classNames: (0, import_react_ui_theme.mx)("aspect-square", classNames)
@@ -225,8 +256,8 @@ var Square = /* @__PURE__ */ (0, import_react4.memo)(({ location, bounds, label,
225
256
  return;
226
257
  }
227
258
  if (model?.isValidMove({
228
- source: piece.location,
229
- target: location,
259
+ from: piece.location,
260
+ to: location,
230
261
  piece: piece.type
231
262
  })) {
232
263
  setState("validMove");
@@ -261,7 +292,8 @@ var Piece = /* @__PURE__ */ (0, import_react5.memo)(({ classNames, piece, orient
261
292
  Component
262
293
  }, Piece.displayName, false);
263
294
  const { model } = useBoardContext();
264
- const { dragging: isDragging } = useBoardContext();
295
+ const { dragging: isDragging, promoting } = useBoardContext();
296
+ const promotingRef = (0, import_react_ui.useDynamicRef)(promoting);
265
297
  const [dragging, setDragging] = (0, import_react5.useState)(false);
266
298
  const [preview, setPreview] = (0, import_react5.useState)();
267
299
  const [current, setCurrent] = (0, import_react5.useState)({});
@@ -270,7 +302,7 @@ var Piece = /* @__PURE__ */ (0, import_react5.memo)(({ classNames, piece, orient
270
302
  const el = ref.current;
271
303
  (0, import_invariant2.invariant)(el, void 0, {
272
304
  F: __dxlog_file3,
273
- L: 43,
305
+ L: 44,
274
306
  S: void 0,
275
307
  A: [
276
308
  "el",
@@ -287,7 +319,7 @@ var Piece = /* @__PURE__ */ (0, import_react5.memo)(({ classNames, piece, orient
287
319
  source: source.data
288
320
  }, {
289
321
  F: __dxlog_file3,
290
- L: 49,
322
+ L: 50,
291
323
  S: void 0,
292
324
  C: (f, a) => f(...a)
293
325
  });
@@ -309,15 +341,14 @@ var Piece = /* @__PURE__ */ (0, import_react5.memo)(({ classNames, piece, orient
309
341
  nativeSetDragImage
310
342
  });
311
343
  },
312
- canDrag: () => model?.turn === piece.side,
344
+ canDrag: () => !promotingRef.current && model?.turn === piece.side,
313
345
  onDragStart: () => setDragging(true),
314
- onDrop: ({ location }) => {
315
- const drop = location.current.dropTargets[0].data;
316
- const loc = drop.location;
317
- if (isLocation(loc)) {
318
- setCurrent((current2) => ({
319
- ...current2,
320
- location: loc
346
+ onDrop: ({ location: { current: current2 } }) => {
347
+ const location = current2.dropTargets[0].data.location;
348
+ if (isLocation(location)) {
349
+ setCurrent((current3) => ({
350
+ ...current3,
351
+ location
321
352
  }));
322
353
  }
323
354
  setDragging(false);
@@ -550,33 +581,47 @@ var locationToPos = ([row, col]) => {
550
581
  };
551
582
  var styles = {
552
583
  neutral: {
584
+ black: "bg-neutral-50",
553
585
  white: "bg-neutral-200",
554
- black: "bg-neutral-50"
586
+ promotion: "bg-neutral-200 hover:bg-neutral-300 opacity-70 hover:opacity-100"
587
+ },
588
+ original: {
589
+ black: "bg-[#6C95B9]",
590
+ white: "bg-[#CCD3DB]",
591
+ promotion: "duration-500 bg-[#CCD3DB] opacity-70 hover:opacity-100"
555
592
  },
556
593
  blue: {
557
- white: "bg-[#ccd3db]",
558
- black: "bg-[#6c95b9]"
594
+ black: "bg-[#608BC1]",
595
+ white: "bg-[#CBDCEB]",
596
+ promotion: "duration-500 bg-[#CBDCEB] opacity-70 hover:opacity-100"
597
+ },
598
+ green: {
599
+ black: "bg-[#8EB486]",
600
+ white: "bg-[#FDF7F4]",
601
+ promotion: "duration-500 bg-[#FDF7F4] opacity-70 hover:opacity-100"
559
602
  }
560
603
  };
604
+ var boardStyles = styles.original;
561
605
  var getSquareColor = ([row, col]) => {
562
- return (col + row) % 2 === 0 ? styles.blue.white : styles.blue.black;
606
+ return (col + row) % 2 === 0 ? boardStyles.white : boardStyles.black;
563
607
  };
564
- var makeMove = (game, { source, target }) => {
565
- const s = locationToPos(source);
566
- const t = locationToPos(target);
608
+ var makeMove = (game, move) => {
609
+ const from = locationToPos(move.from);
610
+ const to = locationToPos(move.to);
567
611
  try {
568
612
  (0, import_log4.log)("makeMove", {
569
- s,
570
- t
613
+ move
571
614
  }, {
572
615
  F: __dxlog_file4,
573
- L: 58,
616
+ L: 72,
574
617
  S: void 0,
575
618
  C: (f, a) => f(...a)
576
619
  });
620
+ const promotion = move.promotion ? move.promotion[1].toLowerCase() : "q";
577
621
  game.move({
578
- from: s,
579
- to: t
622
+ from,
623
+ to,
624
+ promotion
580
625
  }, {
581
626
  strict: false
582
627
  });
@@ -610,6 +655,11 @@ var ChessModel = class {
610
655
  isValidMove(move) {
611
656
  return makeMove(new import_chess.Chess(this._game.fen()), move) !== null;
612
657
  }
658
+ canPromote(move) {
659
+ const isPawnMove = move.piece === "BP" || move.piece === "WP";
660
+ const isToLastRank = move.to[0] === 0 || move.to[0] === 7;
661
+ return isPawnMove && isToLastRank;
662
+ }
613
663
  makeMove(move) {
614
664
  const game = makeMove(this._game, move);
615
665
  if (!game) {
@@ -681,7 +731,7 @@ var mapPieces = (before, after) => {
681
731
  added: Object.keys(difference.added).length
682
732
  }, {
683
733
  F: __dxlog_file4,
684
- L: 184,
734
+ L: 205,
685
735
  S: void 0,
686
736
  C: (f, a) => f(...a)
687
737
  });
@@ -696,7 +746,7 @@ var Chessboard = /* @__PURE__ */ (0, import_react6.memo)(({ orientation, showLab
696
746
  const { ref: containerRef, width, height } = (0, import_react_resize_detector.useResizeDetector)({
697
747
  refreshRate: 200
698
748
  });
699
- const { model } = useBoardContext();
749
+ const { model, promoting, onPromotion } = useBoardContext();
700
750
  const locations = (0, import_react6.useMemo)(() => {
701
751
  return Array.from({
702
752
  length: rows
@@ -742,15 +792,19 @@ var Chessboard = /* @__PURE__ */ (0, import_react6.memo)(({ orientation, showLab
742
792
  return [];
743
793
  }
744
794
  return Object.values(model?.pieces.value ?? {}).map((piece) => {
795
+ if (piece.id === promoting?.id) {
796
+ return null;
797
+ }
745
798
  const bounds = grid[locationToString(piece.location)];
746
799
  return {
747
- bounds,
748
- piece
800
+ piece,
801
+ bounds
749
802
  };
750
- });
803
+ }).filter(import_util.isNotFalsy);
751
804
  }, [
752
805
  grid,
753
- model?.pieces.value
806
+ model?.pieces.value,
807
+ promoting
754
808
  ]);
755
809
  return /* @__PURE__ */ import_react6.default.createElement("div", {
756
810
  ref: containerRef,
@@ -765,7 +819,7 @@ var Chessboard = /* @__PURE__ */ (0, import_react6.memo)(({ orientation, showLab
765
819
  bounds: grid[locationToString(location)],
766
820
  classNames: getSquareColor(location)
767
821
  }))), /* @__PURE__ */ import_react6.default.createElement("div", {
768
- className: "grow"
822
+ className: (0, import_react_ui_theme5.mx)(promoting && "opacity-50")
769
823
  }, positions.map(({ bounds, piece }) => /* @__PURE__ */ import_react6.default.createElement(Piece, {
770
824
  key: piece.id,
771
825
  piece,
@@ -773,12 +827,61 @@ var Chessboard = /* @__PURE__ */ (0, import_react6.memo)(({ orientation, showLab
773
827
  label: debug ? piece.id : void 0,
774
828
  orientation,
775
829
  Component: ChessPieces[piece.type]
776
- }))));
830
+ }))), /* @__PURE__ */ import_react6.default.createElement("div", null, promoting && /* @__PURE__ */ import_react6.default.createElement(PromotionSelector, {
831
+ grid,
832
+ piece: promoting,
833
+ onSelect: (piece) => {
834
+ onPromotion({
835
+ from: Object.values(model.pieces.value).find((p) => p.id === promoting.id).location,
836
+ to: piece.location,
837
+ piece: promoting.type,
838
+ promotion: piece.type
839
+ });
840
+ }
841
+ })));
777
842
  });
778
843
  Chessboard.displayName = "Chessboard";
779
844
  var getSquareLocation = (container, location) => {
780
845
  return container.querySelector(`[data-location="${locationToString(location)}"]`);
781
846
  };
847
+ var PromotionSelector = ({ grid, piece, onSelect }) => {
848
+ const positions = [
849
+ "Q",
850
+ "N",
851
+ "R",
852
+ "B"
853
+ ].map((pieceType, i) => {
854
+ const location = [
855
+ piece.location[0] + (piece.location[0] === 0 ? i : -i),
856
+ piece.location[1]
857
+ ];
858
+ return {
859
+ piece: {
860
+ id: `promotion-${pieceType}`,
861
+ type: (piece.side === "black" ? "B" : "W") + pieceType,
862
+ side: piece.side,
863
+ location
864
+ },
865
+ bounds: grid[locationToString(location)]
866
+ };
867
+ });
868
+ const handleSelect = (selected) => {
869
+ onSelect({
870
+ ...piece,
871
+ type: selected.type
872
+ });
873
+ };
874
+ return /* @__PURE__ */ import_react6.default.createElement("div", null, positions.map(({ piece: piece2, bounds }) => /* @__PURE__ */ import_react6.default.createElement("div", {
875
+ key: piece2.id,
876
+ style: bounds,
877
+ onClick: () => handleSelect(piece2)
878
+ }, /* @__PURE__ */ import_react6.default.createElement(Piece, {
879
+ piece: piece2,
880
+ bounds,
881
+ Component: ChessPieces[piece2.type],
882
+ classNames: (0, import_react_ui_theme5.mx)("border-2 border-neutral-700 rounded-full", boardStyles.promotion)
883
+ }))));
884
+ };
782
885
  // Annotate the CommonJS export names for ESM import in node:
783
886
  0 && (module.exports = {
784
887
  Board,
@@ -786,8 +889,10 @@ var getSquareLocation = (container, location) => {
786
889
  ChessModel,
787
890
  ChessPieces,
788
891
  Chessboard,
892
+ Container,
789
893
  Piece,
790
894
  Square,
895
+ boardStyles,
791
896
  getRelativeBounds,
792
897
  getSquareColor,
793
898
  isEqualLocation,
@@ -798,7 +903,6 @@ var getSquareLocation = (container, location) => {
798
903
  mapPieces,
799
904
  posToLocation,
800
905
  stringToLocation,
801
- styles,
802
906
  useBoardContext
803
907
  });
804
908
  //# sourceMappingURL=index.cjs.map