@dxos/react-ui-gameboard 0.8.4-main.b97322e → 0.8.4-main.dedc0f3
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/dist/lib/browser/index.mjs +426 -330
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +426 -330
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/Chessboard/Chessboard.d.ts +20 -0
- package/dist/types/src/components/Chessboard/Chessboard.d.ts.map +1 -0
- package/dist/types/src/components/Chessboard/Chessboard.stories.d.ts +31 -0
- package/dist/types/src/components/Chessboard/Chessboard.stories.d.ts.map +1 -0
- package/dist/types/src/components/Chessboard/chess.d.ts +59 -0
- package/dist/types/src/components/Chessboard/chess.d.ts.map +1 -0
- package/dist/types/src/components/Chessboard/chess.test.d.ts +2 -0
- package/dist/types/src/components/Chessboard/chess.test.d.ts.map +1 -0
- package/dist/types/src/components/Chessboard/index.d.ts.map +1 -0
- package/dist/types/src/components/Gameboard/Gameboard.d.ts +38 -0
- package/dist/types/src/components/Gameboard/Gameboard.d.ts.map +1 -0
- package/dist/types/src/{Gameboard → components/Gameboard}/Piece.d.ts +3 -2
- package/dist/types/src/components/Gameboard/Piece.d.ts.map +1 -0
- package/dist/types/src/components/Gameboard/Square.d.ts.map +1 -0
- package/dist/types/src/components/Gameboard/index.d.ts +4 -0
- package/dist/types/src/components/Gameboard/index.d.ts.map +1 -0
- package/dist/types/src/{Gameboard → components/Gameboard}/types.d.ts +2 -0
- package/dist/types/src/components/Gameboard/types.d.ts.map +1 -0
- package/dist/types/src/components/Gameboard/util.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +3 -0
- package/dist/types/src/components/index.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -13
- package/src/{Chessboard → components/Chessboard}/Chessboard.stories.tsx +24 -23
- package/src/{Chessboard → components/Chessboard}/Chessboard.tsx +55 -50
- package/src/components/Chessboard/chess.test.ts +19 -0
- package/src/components/Chessboard/chess.ts +322 -0
- package/src/components/Gameboard/Gameboard.tsx +140 -0
- package/src/{Gameboard → components/Gameboard}/Piece.tsx +25 -22
- package/src/{Gameboard → components/Gameboard}/Square.tsx +4 -4
- package/src/{Gameboard → components/Gameboard}/index.ts +0 -3
- package/src/{Gameboard → components/Gameboard}/types.ts +3 -0
- package/src/components/index.ts +6 -0
- package/src/index.ts +1 -2
- package/dist/types/src/Chessboard/Chessboard.d.ts +0 -15
- package/dist/types/src/Chessboard/Chessboard.d.ts.map +0 -1
- package/dist/types/src/Chessboard/Chessboard.stories.d.ts +0 -16
- package/dist/types/src/Chessboard/Chessboard.stories.d.ts.map +0 -1
- package/dist/types/src/Chessboard/chess.d.ts +0 -40
- package/dist/types/src/Chessboard/chess.d.ts.map +0 -1
- package/dist/types/src/Chessboard/index.d.ts.map +0 -1
- package/dist/types/src/Gameboard/Gameboard.d.ts +0 -23
- package/dist/types/src/Gameboard/Gameboard.d.ts.map +0 -1
- package/dist/types/src/Gameboard/Piece.d.ts.map +0 -1
- package/dist/types/src/Gameboard/Square.d.ts.map +0 -1
- package/dist/types/src/Gameboard/context.d.ts +0 -10
- package/dist/types/src/Gameboard/context.d.ts.map +0 -1
- package/dist/types/src/Gameboard/index.d.ts +0 -7
- package/dist/types/src/Gameboard/index.d.ts.map +0 -1
- package/dist/types/src/Gameboard/types.d.ts.map +0 -1
- package/dist/types/src/Gameboard/util.d.ts.map +0 -1
- package/src/Chessboard/chess.ts +0 -213
- package/src/Gameboard/Gameboard.tsx +0 -103
- package/src/Gameboard/context.ts +0 -22
- /package/dist/types/src/{Chessboard → components/Chessboard}/index.d.ts +0 -0
- /package/dist/types/src/{Gameboard → components/Gameboard}/Square.d.ts +0 -0
- /package/dist/types/src/{Gameboard → components/Gameboard}/util.d.ts +0 -0
- /package/src/{Chessboard → components/Chessboard}/index.ts +0 -0
- /package/src/{Gameboard → components/Gameboard}/util.ts +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-gameboard",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.dedc0f3",
|
|
4
4
|
"description": "Game board.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"type": "module",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
|
+
"source": "./src/index.ts",
|
|
12
13
|
"types": "./dist/types/src/index.d.ts",
|
|
13
14
|
"browser": "./dist/lib/browser/index.mjs",
|
|
14
15
|
"node": "./dist/lib/node-esm/index.mjs"
|
|
@@ -27,13 +28,14 @@
|
|
|
27
28
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
|
|
28
29
|
"@preact-signals/safe-react": "^0.9.0",
|
|
29
30
|
"@preact/signals-core": "^1.9.0",
|
|
30
|
-
"
|
|
31
|
+
"@radix-ui/react-context": "1.1.1",
|
|
32
|
+
"chess.js": "^1.4.0",
|
|
31
33
|
"react-resize-detector": "^11.0.1",
|
|
32
|
-
"@dxos/debug": "0.8.4-main.
|
|
33
|
-
"@dxos/invariant": "0.8.4-main.
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/util": "0.8.4-main.
|
|
34
|
+
"@dxos/debug": "0.8.4-main.dedc0f3",
|
|
35
|
+
"@dxos/invariant": "0.8.4-main.dedc0f3",
|
|
36
|
+
"@dxos/log": "0.8.4-main.dedc0f3",
|
|
37
|
+
"@dxos/node-std": "0.8.4-main.dedc0f3",
|
|
38
|
+
"@dxos/util": "0.8.4-main.dedc0f3"
|
|
37
39
|
},
|
|
38
40
|
"devDependencies": {
|
|
39
41
|
"@svgr/cli": "^8.1.0",
|
|
@@ -43,16 +45,16 @@
|
|
|
43
45
|
"lodash.defaultsdeep": "^4.6.1",
|
|
44
46
|
"react": "~18.2.0",
|
|
45
47
|
"react-dom": "~18.2.0",
|
|
46
|
-
"vite": "
|
|
47
|
-
"@dxos/react-ui
|
|
48
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
49
|
-
"@dxos/storybook-utils": "0.8.4-main.
|
|
48
|
+
"vite": "7.1.1",
|
|
49
|
+
"@dxos/react-ui": "0.8.4-main.dedc0f3",
|
|
50
|
+
"@dxos/react-ui-theme": "0.8.4-main.dedc0f3",
|
|
51
|
+
"@dxos/storybook-utils": "0.8.4-main.dedc0f3"
|
|
50
52
|
},
|
|
51
53
|
"peerDependencies": {
|
|
52
54
|
"react": "~18.2.0",
|
|
53
55
|
"react-dom": "~18.2.0",
|
|
54
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
55
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
56
|
+
"@dxos/react-ui": "0.8.4-main.dedc0f3",
|
|
57
|
+
"@dxos/react-ui-theme": "0.8.4-main.dedc0f3"
|
|
56
58
|
},
|
|
57
59
|
"publishConfig": {
|
|
58
60
|
"access": "public"
|
|
@@ -4,29 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
-
import type
|
|
7
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
8
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
9
9
|
|
|
10
|
-
import { log } from '@dxos/log';
|
|
11
10
|
import { Button, Toolbar } from '@dxos/react-ui';
|
|
12
11
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
13
12
|
|
|
14
|
-
import {
|
|
13
|
+
import { Gameboard, type GameboardRootProps, type Move, type Player } from '../Gameboard';
|
|
14
|
+
|
|
15
15
|
import { ChessModel } from './chess';
|
|
16
|
-
import {
|
|
16
|
+
import { Chessboard, type ChessboardProps } from './Chessboard';
|
|
17
17
|
|
|
18
|
-
type
|
|
19
|
-
|
|
18
|
+
type DefaultStoryProps = Pick<ChessboardProps, 'orientation' | 'showLabels' | 'debug'> & {
|
|
19
|
+
pgn?: string;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
const DefaultStory = ({
|
|
23
|
-
const model = useMemo(() => new ChessModel(
|
|
22
|
+
const DefaultStory = ({ orientation: _orientation, pgn, ...props }: DefaultStoryProps) => {
|
|
23
|
+
const model = useMemo(() => new ChessModel(pgn), [pgn]);
|
|
24
24
|
const [orientation, setOrientation] = useState<Player | undefined>(_orientation);
|
|
25
25
|
|
|
26
|
-
const handleDrop = useCallback<NonNullable<GameboardRootProps['onDrop']>>(
|
|
26
|
+
const handleDrop = useCallback<NonNullable<GameboardRootProps<ChessModel>['onDrop']>>(
|
|
27
27
|
(move: Move) => {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const result = model.makeMove(move);
|
|
29
|
+
console.log(model.pgn);
|
|
30
|
+
return result;
|
|
30
31
|
},
|
|
31
32
|
[model],
|
|
32
33
|
);
|
|
@@ -34,7 +35,7 @@ const DefaultStory = ({ fen, orientation: _orientation, ...props }: RenderProps)
|
|
|
34
35
|
return (
|
|
35
36
|
<div className='flex flex-col grow gap-2 overflow-hidden'>
|
|
36
37
|
<Toolbar.Root>
|
|
37
|
-
<Button onClick={() => model.
|
|
38
|
+
<Button onClick={() => model.update()}>Reset</Button>
|
|
38
39
|
<Button onClick={() => model.makeRandomMove()}>Move</Button>
|
|
39
40
|
<div className='grow'></div>
|
|
40
41
|
<Button
|
|
@@ -44,7 +45,7 @@ const DefaultStory = ({ fen, orientation: _orientation, ...props }: RenderProps)
|
|
|
44
45
|
</Button>
|
|
45
46
|
</Toolbar.Root>
|
|
46
47
|
<Gameboard.Root model={model} onDrop={handleDrop}>
|
|
47
|
-
<Gameboard.Content>
|
|
48
|
+
<Gameboard.Content grow contain>
|
|
48
49
|
<Chessboard orientation={orientation} {...props} />
|
|
49
50
|
</Gameboard.Content>
|
|
50
51
|
</Gameboard.Root>
|
|
@@ -52,7 +53,7 @@ const DefaultStory = ({ fen, orientation: _orientation, ...props }: RenderProps)
|
|
|
52
53
|
);
|
|
53
54
|
};
|
|
54
55
|
|
|
55
|
-
const
|
|
56
|
+
const GridStory = () => {
|
|
56
57
|
const models = useMemo(() => Array.from({ length: 9 }).map(() => new ChessModel()), []);
|
|
57
58
|
useEffect(() => {
|
|
58
59
|
const i = setInterval(() => {
|
|
@@ -77,34 +78,34 @@ const Grid = (props: RenderProps) => {
|
|
|
77
78
|
);
|
|
78
79
|
};
|
|
79
80
|
|
|
80
|
-
const meta
|
|
81
|
+
const meta = {
|
|
81
82
|
title: 'ui/react-ui-gameboard/Chessboard',
|
|
82
83
|
component: Chessboard,
|
|
83
84
|
render: DefaultStory,
|
|
84
85
|
decorators: [withTheme, withLayout({ fullscreen: true, classNames: '' })],
|
|
85
|
-
}
|
|
86
|
+
} satisfies Meta<typeof Chessboard>;
|
|
86
87
|
|
|
87
88
|
export default meta;
|
|
88
89
|
|
|
89
|
-
type Story = StoryObj<typeof
|
|
90
|
+
type Story = StoryObj<typeof meta>;
|
|
90
91
|
|
|
91
92
|
export const Default: Story = {};
|
|
92
93
|
|
|
93
94
|
export const Promotion: Story = {
|
|
94
95
|
args: {
|
|
95
|
-
|
|
96
|
+
pgn: '1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 d5 8. exd5 Nxd5 9. O-O Be6 10. Qb3 Na5 11. Qa4+ c6 12. Bxd5 Bxc3 13. Bxe6 fxe6 14. d5 Qg5 15. dxe6 Kf8 16. e7+ Kg8 *',
|
|
96
97
|
},
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
export const Debug: Story = {
|
|
100
101
|
args: {
|
|
101
|
-
|
|
102
|
-
showLabels: true,
|
|
102
|
+
pgn: '1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 d5 8. exd5 Nxd5 9. O-O Be6 10. Qb3 Na5 11. Qa4+ c6 12. Bxd5 Bxc3 13. Bxe6 fxe6 *',
|
|
103
103
|
orientation: 'black',
|
|
104
|
-
|
|
104
|
+
showLabels: true,
|
|
105
|
+
debug: true,
|
|
105
106
|
},
|
|
106
107
|
};
|
|
107
108
|
|
|
108
|
-
export const
|
|
109
|
-
render:
|
|
109
|
+
export const Grid = {
|
|
110
|
+
render: GridStory,
|
|
110
111
|
};
|
|
@@ -2,26 +2,26 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { type PropsWithChildren,
|
|
5
|
+
import React, { type PropsWithChildren, forwardRef, memo, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
import { useResizeDetector } from 'react-resize-detector';
|
|
7
7
|
|
|
8
|
-
import { type ThemedClassName, useTrackProps } from '@dxos/react-ui';
|
|
8
|
+
import { type ThemedClassName, useForwardedRef, useTrackProps } from '@dxos/react-ui';
|
|
9
9
|
import { mx } from '@dxos/react-ui-theme';
|
|
10
10
|
import { isNotFalsy } from '@dxos/util';
|
|
11
11
|
|
|
12
|
-
import { boardStyles, type ChessPiece, ChessPieces, getSquareColor, locationToPos } from './chess';
|
|
13
12
|
import {
|
|
14
13
|
type DOMRectBounds,
|
|
14
|
+
Gameboard,
|
|
15
15
|
type Location,
|
|
16
16
|
type PieceRecord,
|
|
17
17
|
type Player,
|
|
18
|
-
Piece,
|
|
19
|
-
Square,
|
|
20
18
|
getRelativeBounds,
|
|
21
19
|
locationToString,
|
|
22
|
-
|
|
20
|
+
useGameboardContext,
|
|
23
21
|
} from '../Gameboard';
|
|
24
22
|
|
|
23
|
+
import { type ChessModel, type ChessPiece, ChessPieces, boardStyles, getSquareColor, locationToPos } from './chess';
|
|
24
|
+
|
|
25
25
|
export type ChessboardProps = ThemedClassName<
|
|
26
26
|
PropsWithChildren<{
|
|
27
27
|
orientation?: Player;
|
|
@@ -35,13 +35,15 @@ export type ChessboardProps = ThemedClassName<
|
|
|
35
35
|
/**
|
|
36
36
|
* Chessboard layout.
|
|
37
37
|
*/
|
|
38
|
-
|
|
39
|
-
({ orientation, showLabels, debug, rows = 8, cols = 8
|
|
38
|
+
const ChessboardComponent = forwardRef<HTMLDivElement, ChessboardProps>(
|
|
39
|
+
({ classNames, orientation, showLabels, debug, rows = 8, cols = 8 }, forwardedRef) => {
|
|
40
40
|
useTrackProps({ orientation, showLabels, debug }, Chessboard.displayName, false);
|
|
41
|
-
const
|
|
42
|
-
const {
|
|
41
|
+
const targetRef = useForwardedRef(forwardedRef);
|
|
42
|
+
const { width, height } = useResizeDetector({ targetRef, refreshRate: 200 });
|
|
43
|
+
const { model, promoting, onPromotion } = useGameboardContext<ChessModel>(Chessboard.displayName!);
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
// Board squares.
|
|
46
|
+
const squares = useMemo<Location[]>(() => {
|
|
45
47
|
return Array.from({ length: rows }, (_, i) => (orientation === 'black' ? i : rows - 1 - i)).flatMap((row) =>
|
|
46
48
|
Array.from({ length: cols }).map((_, col) => [row, col] as Location),
|
|
47
49
|
);
|
|
@@ -49,7 +51,7 @@ export const Chessboard = memo(
|
|
|
49
51
|
|
|
50
52
|
// Use DOM grid layout to position squares.
|
|
51
53
|
const layout = useMemo(() => {
|
|
52
|
-
return
|
|
54
|
+
return squares.map((location) => {
|
|
53
55
|
return (
|
|
54
56
|
<div
|
|
55
57
|
key={locationToString(location)}
|
|
@@ -59,14 +61,14 @@ export const Chessboard = memo(
|
|
|
59
61
|
/>
|
|
60
62
|
);
|
|
61
63
|
});
|
|
62
|
-
}, [
|
|
64
|
+
}, [squares]);
|
|
63
65
|
|
|
64
66
|
// Build map of square locations to bounds.
|
|
65
67
|
const [grid, setGrid] = useState<Record<string, DOMRectBounds>>({});
|
|
66
68
|
const gridRef = useRef<HTMLDivElement>(null);
|
|
67
69
|
useEffect(() => {
|
|
68
70
|
setGrid(
|
|
69
|
-
|
|
71
|
+
squares.reduce(
|
|
70
72
|
(acc, location) => {
|
|
71
73
|
const square = getSquareLocation(gridRef.current!, location)!;
|
|
72
74
|
const bounds = getRelativeBounds(gridRef.current!, square);
|
|
@@ -75,7 +77,7 @@ export const Chessboard = memo(
|
|
|
75
77
|
{} as Record<string, DOMRectBounds>,
|
|
76
78
|
),
|
|
77
79
|
);
|
|
78
|
-
}, [
|
|
80
|
+
}, [squares, width, height]);
|
|
79
81
|
|
|
80
82
|
// Get the bounds of each square and piece.
|
|
81
83
|
const positions = useMemo<{ piece: PieceRecord; bounds: DOMRectBounds }[]>(() => {
|
|
@@ -96,13 +98,15 @@ export const Chessboard = memo(
|
|
|
96
98
|
}, [grid, model?.pieces.value, promoting]);
|
|
97
99
|
|
|
98
100
|
return (
|
|
99
|
-
<div ref={
|
|
101
|
+
<div ref={targetRef} tabIndex={0} className={mx('relative outline-none', classNames)}>
|
|
102
|
+
{/* DOM Layout. */}
|
|
100
103
|
<div ref={gridRef} className='grid grid-rows-8 grid-cols-8 aspect-square select-none'>
|
|
101
104
|
{layout}
|
|
102
105
|
</div>
|
|
106
|
+
{/* Squares. */}
|
|
103
107
|
<div>
|
|
104
|
-
{
|
|
105
|
-
<Square
|
|
108
|
+
{squares.map((location) => (
|
|
109
|
+
<Gameboard.Square
|
|
106
110
|
key={locationToString(location)}
|
|
107
111
|
location={location}
|
|
108
112
|
label={showLabels ? locationToPos(location) : undefined}
|
|
@@ -111,9 +115,10 @@ export const Chessboard = memo(
|
|
|
111
115
|
/>
|
|
112
116
|
))}
|
|
113
117
|
</div>
|
|
118
|
+
{/* Pieces. */}
|
|
114
119
|
<div className={mx(promoting && 'opacity-50')}>
|
|
115
120
|
{positions.map(({ bounds, piece }) => (
|
|
116
|
-
<Piece
|
|
121
|
+
<Gameboard.Piece
|
|
117
122
|
key={piece.id}
|
|
118
123
|
piece={piece}
|
|
119
124
|
bounds={bounds}
|
|
@@ -123,32 +128,29 @@ export const Chessboard = memo(
|
|
|
123
128
|
/>
|
|
124
129
|
))}
|
|
125
130
|
</div>
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
</div>
|
|
131
|
+
{/* Promotion selector. */}
|
|
132
|
+
{promoting && (
|
|
133
|
+
<PromotionSelector
|
|
134
|
+
grid={grid}
|
|
135
|
+
piece={promoting}
|
|
136
|
+
onSelect={(piece) => {
|
|
137
|
+
onPromotion({
|
|
138
|
+
from: Object.values(model.pieces.value).find((p) => p.id === promoting.id)!.location,
|
|
139
|
+
to: piece.location,
|
|
140
|
+
piece: promoting.type,
|
|
141
|
+
promotion: piece.type,
|
|
142
|
+
});
|
|
143
|
+
}}
|
|
144
|
+
/>
|
|
145
|
+
)}
|
|
142
146
|
</div>
|
|
143
147
|
);
|
|
144
148
|
},
|
|
145
149
|
);
|
|
146
150
|
|
|
147
|
-
|
|
151
|
+
ChessboardComponent.displayName = 'Chessboard';
|
|
148
152
|
|
|
149
|
-
const
|
|
150
|
-
return container.querySelector(`[data-location="${locationToString(location)}"]`);
|
|
151
|
-
};
|
|
153
|
+
export const Chessboard = memo(ChessboardComponent);
|
|
152
154
|
|
|
153
155
|
const PromotionSelector = ({
|
|
154
156
|
grid,
|
|
@@ -176,19 +178,22 @@ const PromotionSelector = ({
|
|
|
176
178
|
onSelect({ ...piece, type: selected.type });
|
|
177
179
|
};
|
|
178
180
|
|
|
179
|
-
// TODO(burdon): Circle.
|
|
180
181
|
return (
|
|
181
|
-
|
|
182
|
+
<>
|
|
182
183
|
{positions.map(({ piece, bounds }) => (
|
|
183
|
-
<
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
<Gameboard.Piece
|
|
185
|
+
key={piece.id}
|
|
186
|
+
classNames={mx('border-2 border-neutral-700 rounded-full', boardStyles.promotion)}
|
|
187
|
+
piece={piece}
|
|
188
|
+
bounds={bounds}
|
|
189
|
+
Component={ChessPieces[piece.type as ChessPiece]}
|
|
190
|
+
onClick={() => handleSelect(piece)}
|
|
191
|
+
/>
|
|
191
192
|
))}
|
|
192
|
-
|
|
193
|
+
</>
|
|
193
194
|
);
|
|
194
195
|
};
|
|
196
|
+
|
|
197
|
+
const getSquareLocation = (container: HTMLElement, location: Location): HTMLElement | null => {
|
|
198
|
+
return container.querySelector(`[data-location="${locationToString(location)}"]`);
|
|
199
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Chess as ChessJS } from 'chess.js';
|
|
6
|
+
import { describe, it } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import { createPieceMap } from './chess';
|
|
9
|
+
|
|
10
|
+
describe('ChessModel', () => {
|
|
11
|
+
it('should update pieces', ({ expect }) => {
|
|
12
|
+
const chess = new ChessJS();
|
|
13
|
+
chess.loadPgn(
|
|
14
|
+
'1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 d5 8. exd5 Nxd5 9. O-O Be6 10. Qb3 Na5 11. Qa4+ c6 12. Bxd5 Bxc3 13. Bxe6 fxe6 *',
|
|
15
|
+
);
|
|
16
|
+
const pieces = createPieceMap(chess);
|
|
17
|
+
expect(pieces).to.exist;
|
|
18
|
+
});
|
|
19
|
+
});
|