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