Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ yarn add @react-chess/chessground

## Documentation

After installing, the component can be default imported and it has 4 optional props:
After installing, the component can be default imported and it has 5 optional props:

- `width: number` defaults to `900`, determines width of the chessboard in pxs

Expand All @@ -28,6 +28,8 @@ After installing, the component can be default imported and it has 4 optional pr

- `contained: boolean` defaults to `false`, when enabled renders the chessboard in a `100%` width & height div.

- `ref: Api` returns an instance of the Chessground API for interacting with the chessboard.

Renders a simple `900 x 900` board, with pieces in their default position:

```jsx
Expand All @@ -40,3 +42,51 @@ import "chessground/assets/chessground.cburnett.css";

ReactDOM.render(<Chessground />, document.getElementById("root"));
```

## Example: showing the moves of a game

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i really like this example!


```tsx
import { useEffect, useRef } from "react";
import Chessground, { Api, Config, Key } from "@react-chess/chessground";

// these styles must be imported somewhere
import "chessground/assets/chessground.base.css";
import "chessground/assets/chessground.brown.css";
import "chessground/assets/chessground.cburnett.css";

const CONFIG: Config = {
movable: { free: false },
};

// Demo game moves in long algebraic form
const MOVES = (
"e2e4 e7e5 g1f3 d7d6 d2d4 c8g4 d4e5 g4f3 d1f3 d6e5 " +
"f1c4 g8f6 f3b3 d8e7 b1c3 c7c6 c1g5 b7b5 c3b5 c6b5 " +
"c4b5 b8d7 e1c1 a8d8 d1d7 d8d7 h1d1 e7e6 b5d7 f6d7 " +
"b3b8 d7b8 d1d8"
).split(" ");

export const DemoGameMoves = () => {
const apiRef = useRef<Api | undefined>();

useEffect(() => {
// Make a move every 2 seconds
const interval = setInterval(() => {
const move = MOVES.shift();
if (move) {
apiRef.current!.move(move.substring(0,2) as Key, move.substring(2,4) as Key);
} else {
clearInterval(interval);
}
}, 2000);
return () => clearInterval(interval);
});

return (
<Chessground
width={640} height={640}
config={CONFIG} ref={apiRef}
/>
);
}
```
82 changes: 44 additions & 38 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,50 @@
import React, { useEffect, useRef, useState } from 'react';
import { Chessground as ChessgroundApi } from 'chessground';
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';

import { Api } from 'chessground/api';
import { Chessground as ChessgroundApi } from 'chessground';
import { Config } from 'chessground/config';
import { Api } from 'chessground/api';
import { Key } from 'chessground/types';


interface Props {
width?: number
height?: number
width?: number;
height?: number;
contained?: boolean;
config?: Config
}

function Chessground({
width = 900, height = 900, config = {}, contained = false,
}: Props) {
const [api, setApi] = useState<Api | null>(null);

const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
if (ref && ref.current && !api) {
const chessgroundApi = ChessgroundApi(ref.current, {
animation: { enabled: true, duration: 200 },
...config,
});
setApi(chessgroundApi);
} else if (ref && ref.current && api) {
api.set(config);
}
}, [ref]);

useEffect(() => {
api?.set(config);
}, [api, config]);

return (
<div style={{ height: contained ? '100%' : height, width: contained ? '100%' : width }}>
<div ref={ref} style={{ height: '100%', width: '100%', display: 'table' }} />
</div>
);
}

config?: Config;
};

const Chessground = forwardRef<Api | undefined, Props>(
(
{ width = 900, height = 900, config = {}, contained = false }: Props,
apiRef,
) => {
const [api, setApi] = useState<Api | undefined>();
const divRef = useRef<HTMLDivElement>(null);

useImperativeHandle(apiRef, () => {
return api;
}, [api]);

useEffect(() => {
if (divRef.current && !api) {
const chessgroundApi = ChessgroundApi(divRef.current, config);
setApi(chessgroundApi);
}
}, [divRef.current, api]);

useEffect(() => {
if (api) {
api.set(config);
}
}, [config]);

return (
<div style={{ height: contained ? '100%' : height, width: contained ? '100%' : width }}>
<div ref={divRef} style={{ height: '100%', width: '100%', display: 'table' }} />
</div>
);
}
);

export type { Api, Config, Key };
export default Chessground;