Newer
Older

Valentin Rigal
committed
<template>
<div v-if="characters && characters.length">
<div v-if="!charTable">An error occured loading the keyboard</div>
<div v-else v-for="(row, i) in charTable" :key="i">
<span v-for="(char, j) in row" :key="j">
<!-- Emit a key of the keyboard or its position when it is empty -->
:class="{
'is-selected':
selectedKey && selectedKey.row == i && selectedKey.column == j,
}"
v-on:mouseup="
char ? $emit('input', char) : $emit('input', { row: i, column: j })
"
<template v-if="char">{{ char.character }}</template>
<template v-else> </template>

Valentin Rigal
committed
</div>
</template>
<script>
import { mapState } from "vuex";

Valentin Rigal
committed
export default {
props: {
keyboardIndex: {
type: Number,

Valentin Rigal
committed
required: true,
},
// Row and column value of the selected keyboard key
selectedKey: {
type: Object,
default: null,
},
...mapState(["keyboards"]),
return this.keyboards[this.keyboardIndex].characters;

Valentin Rigal
committed
},
rowsCount() {
return (
this.characters && Math.max(...this.characters.map((c) => c.row)) + 1
);
columnsCount() {
return (
this.characters && Math.max(...this.characters.map((c) => c.column)) + 1
);
charTable() {
if (!this.columnsCount || !this.rowsCount) return;
// Return a list of every column with padding
const table = Array.from(
Array(this.rowsCount),
() => new Array(this.columnsCount)
);
if (!this.characters) return table;
this.characters.forEach((c) => {
table[c.row][c.column] = c;
});
return table;

Valentin Rigal
committed
},
};
</script>
<style scoped>
button {
width: 3rem;
height: 3rem;
margin: 0.1rem;

Valentin Rigal
committed
}
button.is-selected {
border: solid black 0.25rem;
border-radius: 0.25rem;
}