@dxos/react-ui-gameboard 0.7.5-main.e9bb01b → 0.7.5-staging.2ff1350

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,7 +33,7 @@ var getRelativeBounds = (container, element) => {
33
33
 
34
34
  // packages/ui/react-ui-gameboard/src/Board/Board.tsx
35
35
  import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
36
- import React2, { useEffect, useState } from "react";
36
+ import React2, { useCallback, useEffect, useState } from "react";
37
37
  import { log } from "@dxos/log";
38
38
  import { mx as mx2 } from "@dxos/react-ui-theme";
39
39
 
@@ -54,14 +54,30 @@ var Container = /* @__PURE__ */ forwardRef(({ children, classNames, style }, for
54
54
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-gameboard/src/Board/Board.tsx";
55
55
  var Root = ({ children, classNames, model, onDrop }) => {
56
56
  const [dragging, setDragging] = useState(false);
57
+ const [promoting, setPromoting] = useState();
58
+ const onPromotion = useCallback((move) => {
59
+ log("onPromotion", {
60
+ move
61
+ }, {
62
+ F: __dxlog_file,
63
+ L: 32,
64
+ S: void 0,
65
+ C: (f, a) => f(...a)
66
+ });
67
+ setPromoting(void 0);
68
+ onDrop?.(move);
69
+ }, []);
57
70
  useEffect(() => {
71
+ if (!model) {
72
+ return;
73
+ }
58
74
  return monitorForElements({
59
75
  onDragStart: ({ source }) => {
60
76
  log("onDragStart", {
61
77
  source
62
78
  }, {
63
79
  F: __dxlog_file,
64
- L: 33,
80
+ L: 45,
65
81
  S: void 0,
66
82
  C: (f, a) => f(...a)
67
83
  });
@@ -73,7 +89,7 @@ var Root = ({ children, classNames, model, onDrop }) => {
73
89
  location
74
90
  }, {
75
91
  F: __dxlog_file,
76
- L: 37,
92
+ L: 49,
77
93
  S: void 0,
78
94
  C: (f, a) => f(...a)
79
95
  });
@@ -86,19 +102,31 @@ var Root = ({ children, classNames, model, onDrop }) => {
86
102
  if (!isLocation(targetLocation) || !isPiece(piece)) {
87
103
  return;
88
104
  }
89
- onDrop?.({
90
- source: piece.location,
91
- target: targetLocation,
105
+ const move = {
106
+ from: piece.location,
107
+ to: targetLocation,
92
108
  piece: piece.type
93
- });
109
+ };
110
+ if (model.canPromote?.(move)) {
111
+ setPromoting({
112
+ ...piece,
113
+ location: targetLocation
114
+ });
115
+ } else {
116
+ onDrop?.(move);
117
+ }
94
118
  setDragging(false);
95
119
  }
96
120
  });
97
- }, []);
121
+ }, [
122
+ model
123
+ ]);
98
124
  return /* @__PURE__ */ React2.createElement(BoardContext.Provider, {
99
125
  value: {
100
126
  model,
101
- dragging
127
+ dragging,
128
+ promoting,
129
+ onPromotion
102
130
  }
103
131
  }, /* @__PURE__ */ React2.createElement(Container, {
104
132
  classNames: mx2("aspect-square", classNames)
@@ -161,8 +189,8 @@ var Square = /* @__PURE__ */ memo(({ location, bounds, label, classNames }) => {
161
189
  return;
162
190
  }
163
191
  if (model?.isValidMove({
164
- source: piece.location,
165
- target: location,
192
+ from: piece.location,
193
+ to: location,
166
194
  piece: piece.type
167
195
  })) {
168
196
  setState("validMove");
@@ -195,7 +223,7 @@ import React4, { useState as useState3, useRef as useRef2, useEffect as useEffec
195
223
  import { createPortal } from "react-dom";
196
224
  import { invariant as invariant2 } from "@dxos/invariant";
197
225
  import { log as log3 } from "@dxos/log";
198
- import { useTrackProps } from "@dxos/react-ui";
226
+ import { useDynamicRef, useTrackProps } from "@dxos/react-ui";
199
227
  import { mx as mx4 } from "@dxos/react-ui-theme";
200
228
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-gameboard/src/Board/Piece.tsx";
201
229
  var Piece = /* @__PURE__ */ memo2(({ classNames, piece, orientation, bounds, label, Component }) => {
@@ -208,7 +236,8 @@ var Piece = /* @__PURE__ */ memo2(({ classNames, piece, orientation, bounds, lab
208
236
  Component
209
237
  }, Piece.displayName, false);
210
238
  const { model } = useBoardContext();
211
- const { dragging: isDragging } = useBoardContext();
239
+ const { dragging: isDragging, promoting } = useBoardContext();
240
+ const promotingRef = useDynamicRef(promoting);
212
241
  const [dragging, setDragging] = useState3(false);
213
242
  const [preview, setPreview] = useState3();
214
243
  const [current, setCurrent] = useState3({});
@@ -217,7 +246,7 @@ var Piece = /* @__PURE__ */ memo2(({ classNames, piece, orientation, bounds, lab
217
246
  const el = ref.current;
218
247
  invariant2(el, void 0, {
219
248
  F: __dxlog_file3,
220
- L: 43,
249
+ L: 44,
221
250
  S: void 0,
222
251
  A: [
223
252
  "el",
@@ -234,7 +263,7 @@ var Piece = /* @__PURE__ */ memo2(({ classNames, piece, orientation, bounds, lab
234
263
  source: source.data
235
264
  }, {
236
265
  F: __dxlog_file3,
237
- L: 49,
266
+ L: 50,
238
267
  S: void 0,
239
268
  C: (f, a) => f(...a)
240
269
  });
@@ -256,15 +285,14 @@ var Piece = /* @__PURE__ */ memo2(({ classNames, piece, orientation, bounds, lab
256
285
  nativeSetDragImage
257
286
  });
258
287
  },
259
- canDrag: () => model?.turn === piece.side,
288
+ canDrag: () => !promotingRef.current && model?.turn === piece.side,
260
289
  onDragStart: () => setDragging(true),
261
- onDrop: ({ location }) => {
262
- const drop = location.current.dropTargets[0].data;
263
- const loc = drop.location;
264
- if (isLocation(loc)) {
265
- setCurrent((current2) => ({
266
- ...current2,
267
- location: loc
290
+ onDrop: ({ location: { current: current2 } }) => {
291
+ const location = current2.dropTargets[0].data.location;
292
+ if (isLocation(location)) {
293
+ setCurrent((current3) => ({
294
+ ...current3,
295
+ location
268
296
  }));
269
297
  }
270
298
  setDragging(false);
@@ -542,33 +570,47 @@ var locationToPos = ([row, col]) => {
542
570
  };
543
571
  var styles = {
544
572
  neutral: {
573
+ black: "bg-neutral-50",
545
574
  white: "bg-neutral-200",
546
- black: "bg-neutral-50"
575
+ promotion: "bg-neutral-200 hover:bg-neutral-300 opacity-70 hover:opacity-100"
576
+ },
577
+ original: {
578
+ black: "bg-[#6C95B9]",
579
+ white: "bg-[#CCD3DB]",
580
+ promotion: "duration-500 bg-[#CCD3DB] opacity-70 hover:opacity-100"
547
581
  },
548
582
  blue: {
549
- white: "bg-[#ccd3db]",
550
- black: "bg-[#6c95b9]"
583
+ black: "bg-[#608BC1]",
584
+ white: "bg-[#CBDCEB]",
585
+ promotion: "duration-500 bg-[#CBDCEB] opacity-70 hover:opacity-100"
586
+ },
587
+ green: {
588
+ black: "bg-[#8EB486]",
589
+ white: "bg-[#FDF7F4]",
590
+ promotion: "duration-500 bg-[#FDF7F4] opacity-70 hover:opacity-100"
551
591
  }
552
592
  };
593
+ var boardStyles = styles.original;
553
594
  var getSquareColor = ([row, col]) => {
554
- return (col + row) % 2 === 0 ? styles.blue.white : styles.blue.black;
595
+ return (col + row) % 2 === 0 ? boardStyles.white : boardStyles.black;
555
596
  };
556
- var makeMove = (game, { source, target }) => {
557
- const s = locationToPos(source);
558
- const t = locationToPos(target);
597
+ var makeMove = (game, move) => {
598
+ const from = locationToPos(move.from);
599
+ const to = locationToPos(move.to);
559
600
  try {
560
601
  log4("makeMove", {
561
- s,
562
- t
602
+ move
563
603
  }, {
564
604
  F: __dxlog_file4,
565
- L: 58,
605
+ L: 72,
566
606
  S: void 0,
567
607
  C: (f, a) => f(...a)
568
608
  });
609
+ const promotion = move.promotion ? move.promotion[1].toLowerCase() : "q";
569
610
  game.move({
570
- from: s,
571
- to: t
611
+ from,
612
+ to,
613
+ promotion
572
614
  }, {
573
615
  strict: false
574
616
  });
@@ -602,6 +644,11 @@ var ChessModel = class {
602
644
  isValidMove(move) {
603
645
  return makeMove(new Chess(this._game.fen()), move) !== null;
604
646
  }
647
+ canPromote(move) {
648
+ const isPawnMove = move.piece === "BP" || move.piece === "WP";
649
+ const isToLastRank = move.to[0] === 0 || move.to[0] === 7;
650
+ return isPawnMove && isToLastRank;
651
+ }
605
652
  makeMove(move) {
606
653
  const game = makeMove(this._game, move);
607
654
  if (!game) {
@@ -673,7 +720,7 @@ var mapPieces = (before, after) => {
673
720
  added: Object.keys(difference.added).length
674
721
  }, {
675
722
  F: __dxlog_file4,
676
- L: 184,
723
+ L: 205,
677
724
  S: void 0,
678
725
  C: (f, a) => f(...a)
679
726
  });
@@ -684,6 +731,8 @@ var mapPieces = (before, after) => {
684
731
  import React17, { useRef as useRef3, useMemo, useEffect as useEffect4, useState as useState4, memo as memo3 } from "react";
685
732
  import { useResizeDetector } from "react-resize-detector";
686
733
  import { useTrackProps as useTrackProps2 } from "@dxos/react-ui";
734
+ import { mx as mx5 } from "@dxos/react-ui-theme";
735
+ import { isNotFalsy } from "@dxos/util";
687
736
  var Chessboard = /* @__PURE__ */ memo3(({ orientation, showLabels, debug, rows = 8, cols = 8 }) => {
688
737
  useTrackProps2({
689
738
  orientation,
@@ -693,7 +742,7 @@ var Chessboard = /* @__PURE__ */ memo3(({ orientation, showLabels, debug, rows =
693
742
  const { ref: containerRef, width, height } = useResizeDetector({
694
743
  refreshRate: 200
695
744
  });
696
- const { model } = useBoardContext();
745
+ const { model, promoting, onPromotion } = useBoardContext();
697
746
  const locations = useMemo(() => {
698
747
  return Array.from({
699
748
  length: rows
@@ -739,15 +788,19 @@ var Chessboard = /* @__PURE__ */ memo3(({ orientation, showLabels, debug, rows =
739
788
  return [];
740
789
  }
741
790
  return Object.values(model?.pieces.value ?? {}).map((piece) => {
791
+ if (piece.id === promoting?.id) {
792
+ return null;
793
+ }
742
794
  const bounds = grid[locationToString(piece.location)];
743
795
  return {
744
- bounds,
745
- piece
796
+ piece,
797
+ bounds
746
798
  };
747
- });
799
+ }).filter(isNotFalsy);
748
800
  }, [
749
801
  grid,
750
- model?.pieces.value
802
+ model?.pieces.value,
803
+ promoting
751
804
  ]);
752
805
  return /* @__PURE__ */ React17.createElement("div", {
753
806
  ref: containerRef,
@@ -762,7 +815,7 @@ var Chessboard = /* @__PURE__ */ memo3(({ orientation, showLabels, debug, rows =
762
815
  bounds: grid[locationToString(location)],
763
816
  classNames: getSquareColor(location)
764
817
  }))), /* @__PURE__ */ React17.createElement("div", {
765
- className: "grow"
818
+ className: mx5(promoting && "opacity-50")
766
819
  }, positions.map(({ bounds, piece }) => /* @__PURE__ */ React17.createElement(Piece, {
767
820
  key: piece.id,
768
821
  piece,
@@ -770,20 +823,71 @@ var Chessboard = /* @__PURE__ */ memo3(({ orientation, showLabels, debug, rows =
770
823
  label: debug ? piece.id : void 0,
771
824
  orientation,
772
825
  Component: ChessPieces[piece.type]
773
- }))));
826
+ }))), /* @__PURE__ */ React17.createElement("div", null, promoting && /* @__PURE__ */ React17.createElement(PromotionSelector, {
827
+ grid,
828
+ piece: promoting,
829
+ onSelect: (piece) => {
830
+ onPromotion({
831
+ from: Object.values(model.pieces.value).find((p) => p.id === promoting.id).location,
832
+ to: piece.location,
833
+ piece: promoting.type,
834
+ promotion: piece.type
835
+ });
836
+ }
837
+ })));
774
838
  });
775
839
  Chessboard.displayName = "Chessboard";
776
840
  var getSquareLocation = (container, location) => {
777
841
  return container.querySelector(`[data-location="${locationToString(location)}"]`);
778
842
  };
843
+ var PromotionSelector = ({ grid, piece, onSelect }) => {
844
+ const positions = [
845
+ "Q",
846
+ "N",
847
+ "R",
848
+ "B"
849
+ ].map((pieceType, i) => {
850
+ const location = [
851
+ piece.location[0] + (piece.location[0] === 0 ? i : -i),
852
+ piece.location[1]
853
+ ];
854
+ return {
855
+ piece: {
856
+ id: `promotion-${pieceType}`,
857
+ type: (piece.side === "black" ? "B" : "W") + pieceType,
858
+ side: piece.side,
859
+ location
860
+ },
861
+ bounds: grid[locationToString(location)]
862
+ };
863
+ });
864
+ const handleSelect = (selected) => {
865
+ onSelect({
866
+ ...piece,
867
+ type: selected.type
868
+ });
869
+ };
870
+ return /* @__PURE__ */ React17.createElement("div", null, positions.map(({ piece: piece2, bounds }) => /* @__PURE__ */ React17.createElement("div", {
871
+ key: piece2.id,
872
+ style: bounds,
873
+ onClick: () => handleSelect(piece2)
874
+ }, /* @__PURE__ */ React17.createElement(Piece, {
875
+ piece: piece2,
876
+ bounds,
877
+ Component: ChessPieces[piece2.type],
878
+ classNames: mx5("border-2 border-neutral-700 rounded-full", boardStyles.promotion)
879
+ }))));
880
+ };
779
881
  export {
780
882
  Board,
781
883
  BoardContext,
782
884
  ChessModel,
783
885
  ChessPieces,
784
886
  Chessboard,
887
+ Container,
785
888
  Piece,
786
889
  Square,
890
+ boardStyles,
787
891
  getRelativeBounds,
788
892
  getSquareColor,
789
893
  isEqualLocation,
@@ -794,7 +898,6 @@ export {
794
898
  mapPieces,
795
899
  posToLocation,
796
900
  stringToLocation,
797
- styles,
798
901
  useBoardContext
799
902
  };
800
903
  //# sourceMappingURL=index.mjs.map