<template> <div> <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"> <button type="button" v-if="char" v-on:mouseup="$emit('input', char.character)" > {{ char.character }} </button> <button type="button" v-else> </button> </span> </div> </div> </template> <script> export default { props: { keyboard: { type: Object, required: true, }, }, computed: { characters() { return this.keyboard.characters; }, 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; }, }, }; </script> <style scoped> button { width: 3rem; height: 3rem; margin: 0.1rem; } </style>