diff --git a/README.md b/README.md
index d5e7eaa..afa7ea7 100644
--- a/README.md
+++ b/README.md
@@ -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
@@ -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
@@ -40,3 +42,51 @@ import "chessground/assets/chessground.cburnett.css";
ReactDOM.render(, document.getElementById("root"));
```
+
+## Example: showing the moves of a game
+
+```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();
+
+ 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 (
+
+ );
+}
+```
\ No newline at end of file
diff --git a/src/index.tsx b/src/index.tsx
index 317e5f6..94246ff 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -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(null);
-
- const ref = useRef(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 (
-
- );
-}
-
+ config?: Config;
+};
+
+const Chessground = forwardRef(
+ (
+ { width = 900, height = 900, config = {}, contained = false }: Props,
+ apiRef,
+ ) => {
+ const [api, setApi] = useState();
+ const divRef = useRef(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 (
+
+ );
+ }
+);
+
+export type { Api, Config, Key };
export default Chessground;