Skip to content

Commit

Permalink
Merge pull request #190 from gavin-lb/feature/updatedable-config
Browse files Browse the repository at this point in the history
Refactor and `reactive-config` prop feature
  • Loading branch information
Luca Hendrik Helms authored Jun 14, 2023
2 parents cf735a4 + 7201bda commit ed0b7d0
Show file tree
Hide file tree
Showing 16 changed files with 779 additions and 443 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ module.exports = {
semi: true,
},
],
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
'vue/require-explicit-emits': ['off'],
},
};
18 changes: 18 additions & 0 deletions docs/.vitepress/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
max-width: 600px;
}

coords.files {
bottom: 5px !important;
}

.move-container {
min-height: 250px;
}
Expand Down Expand Up @@ -61,3 +65,17 @@ h1 {
background-position: center;
background-repeat: no-repeat;
}

.buttons {
padding: 5px;
text-align: center;
}
.buttons .activated {
background-color: #888;
}
.buttons button {
background-color: #555;
border-radius: 5px;
margin: 5px;
padding: 5px;
}
24 changes: 20 additions & 4 deletions docs/board-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Here is a list of all the available methods:

```ts
/**
* Resets the board to the initial starting position.
* Resets the board to the initial starting configuration.
*/
resetBoard(): void;

Expand Down Expand Up @@ -95,10 +95,12 @@ getOpeningName(): Promise<string | null>;

/**
* make a move programmatically on the board
* @param move the san move to make like 'e4', 'O-O' or 'e8=Q'
* @param move either a string in Standard Algebraic Notation (SAN), eg. 'e4', 'exd5', 'O-O', 'Nf3' or 'e8=Q'
* or an object of shape { from: string; to: string; promotion?: string; }, eg. { from: 'g8', to: 'f6' } or
* { from: 'e7', to: 'e8', promotion: 'q'}
* @returns true if the move was made, false if the move was illegal
*/
move(move: string): boolean;
move(move: string | { from: Key; to: Key; promotion?: Promotion; }): boolean;

/**
* returns the current turn color
Expand Down Expand Up @@ -192,7 +194,8 @@ getSquareColor(square: string): SquareColor | null;
getSquare(square: Square): Piece | null;

/**
* Returns the piece on the square or null if there is no piece
* loads a fen into the board
* Caution: this will erase the game history. To set position with history call loadPgn with a pgn instead
*/
setPosition(fen: string): void;

Expand Down Expand Up @@ -236,6 +239,19 @@ loadPgn(pgn: string): void;
getPgnInfo(): {
[key: string]: string | undefined;
};

/**
* Sets the config of the board.
* Caution: providing a config with a fen will erase the game history and change the starting position
* for resetBoard. To keep history and starting position: omit fen from the given config and call
* loadPgn with a pgn instead.
*
* @param config - a subset of config options, eg. `{ viewOnly: true, animation: { enabled: false } }`
* or `{ movable: { events: { after: afterFunc }, showDests: false }, drawable: { enabled: false } }`
* @param fillDefaults - if true unprovided config options will be substituted with default values, if
* false the unprovided options will remain unchanged.
*/
setConfig(config: BoardConfig, fillDefaults = false): void {
```
## Example Board API Usage
Expand Down
170 changes: 167 additions & 3 deletions docs/board-props.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
<script setup>
import { TheChessboard } from '../dist/vue3-chessboard';
import { reactive } from 'vue';

const boardConfig = {
coordinates: false,
autoCastle: false,
orientation: 'black',
};

const boardConfig2 = reactive({
coordinates: true,
viewOnly: false,
animation: { enabled: true },
draggable: { enabled: true },
});
</script>

# Board props

## Configure the chessboard
Available props:
- `board-config`
- `player-color`
- `reactive-config`

## `board-config`: Configure the chessboard

To edit the chessboard you can pass a configuration object to the component.
Here are all the available options:
Expand Down Expand Up @@ -150,7 +162,7 @@ max-width: 90%;
}
</style>

## Configure the board for multiplayer
## `player-color`: Configure the board for multiplayer

The board can accept a player-color prop to denote the color that the corresponding client should be allowed to play. Moves from a players opponent can be applied to the board with the `BoardApi`'s `move` method - the turns will switch once the `move` method is called with a valid sen string. If no value is provided, turns will switch locally.

Expand Down Expand Up @@ -179,4 +191,156 @@ function onRecieveMove(move: string) {
:player-color="playerColor"
/>
</template>
```
```


## `reactive-config`: Using a reactive config object

The `TheChessboard` component can accept a `reactive-config` prop to allow the `board-config` prop to be reactive to changes. Any mutations of the `board-config` prop will propagate to changes of the board config. This works with nested properties in a non-destructive way, ie. setting `boardConfig.draggable = { distance: 10, showGhost: false }` won't affect the other properties of `draggable` on the actual board config, such as `draggable.enabled`. However, it will change the "default state" of the board so that if `boardAPI.resetBoard()` is called the current state of the `board-config` prop is considered to be the provided config, as if it was passed at the time of instantiation of the `TheChessboard` component.

Note that prop mutation is a *one-way flow of data*, so the state of the `board-config` prop won't necessarily reflect the state of the actual board config. For example, as the game progresses the `fen` property of the `board-config` prop **will not** update.

See the following example for how one might make use of this feature:

::: code-group

```vue [TypeScript]
<script setup lang="ts">
import { reactive } from 'vue';
import { TheChessboard, type BoardConfig } from 'vue3-chessboard';
import 'vue3-chessboard/style.css';
const boardConfig: BoardConfig = reactive({
coordinates: true,
viewOnly: false,
animation: { enabled: true },
draggable: { enabled: true },
});
</script>
<template>
<TheChessboard
:board-config="boardConfig"
reactive-config
/>
<div class="buttons">
<button @click="boardConfig.coordinates = !boardConfig.coordinates">
Toggle coordinates
</button>
<button @click="boardConfig.viewOnly = !boardConfig.viewOnly">
Toggle view only
</button>
<button
@click="boardConfig.animation!.enabled = !boardConfig.animation!.enabled"
>
Toggle animations
</button>
<button
@click="boardConfig.draggable!.enabled = !boardConfig.draggable!.enabled"
>
Toggle draggable
</button>
</div>
</template>
<style scoped>
.buttons {
padding: 5px;
text-align: center;
}
.buttons button {
border-radius: 5px;
margin: 5px;
padding: 5px;
}
</style>
```

```vue [JavaScript]
<script setup>
import { reactive } from 'vue';
import { TheChessboard } from 'vue3-chessboard';
import 'vue3-chessboard/style.css';
const boardConfig = reactive({
coordinates: true,
viewOnly: false,
animation: { enabled: true },
draggable: { enabled: true },
});
</script>
<template>
<TheChessboard
:board-config="boardConfig"
reactive-config
/>
<div class="buttons">
<button @click="boardConfig.coordinates = !boardConfig.coordinates">
Toggle coordinates
</button>
<button @click="boardConfig.viewOnly = !boardConfig.viewOnly">
Toggle view only
</button>
<button
@click="boardConfig.animation.enabled = !boardConfig.animation.enabled"
>
Toggle animations
</button>
<button
@click="boardConfig.draggable.enabled = !boardConfig.draggable.enabled"
>
Toggle draggable
</button>
</div>
</template>
<style scoped>
.buttons {
padding: 5px;
text-align: center;
}
.buttons button {
border-radius: 5px;
margin: 5px;
padding: 5px;
}
</style>
```

:::

The board should then look like this:

<div>
<TheChessboard
:board-config="boardConfig2"
reactive-config
/>
<div class="buttons">
<button
@click="boardConfig2.coordinates = !boardConfig2.coordinates"
:class="{ activated: boardConfig2.coordinates }"
>
Toggle coordinates
</button>
<button
@click="boardConfig2.viewOnly = !boardConfig2.viewOnly"
:class="{ activated: !boardConfig2.viewOnly }"
>
Toggle view only
</button>
<button
@click="boardConfig2.animation.enabled = !boardConfig2.animation.enabled"
:class="{ activated: boardConfig2.animation.enabled }"
>
Toggle animations
</button>
<button
@click="boardConfig2.draggable.enabled = !boardConfig2.draggable.enabled"
:class="{ activated: boardConfig2.draggable.enabled }"
>
Toggle draggable
</button>
</div>
</div>
Loading

0 comments on commit ed0b7d0

Please sign in to comment.