Newer
Older

Valentin Rigal
committed
<template>
<div class="virtual-keyboard">
<!-- Allow focus on the keyboard to automatically restore focus on the input -->
<section tabindex="0">
<button type="button" v-on:mouseup="addChar('ȵ')">ȵ</button>
<button type="button" v-on:mouseup="addChar('Ȫ')">Ȫ</button>
<button type="button" v-on:mouseup="addChar('ɀ')">ɀ</button>
<button type="button" v-on:mouseup="addChar('Ɇ')">Ɇ</button>
<a v-if="manager" v-on:click.prevent="optionsModal = true" href="#"
>Options</a
>
</section>
<Modal v-if="optionsModal" v-model="optionsModal">
<span>option 1: </span>
<input />
</Modal>

Valentin Rigal
committed
</div>
</template>
<script>
import Modal from "./Modal.vue";

Valentin Rigal
committed
export default {

Valentin Rigal
committed
props: {
inputField: {
type: [HTMLInputElement, HTMLTextAreaElement],
required: true,
},

Valentin Rigal
committed
type: Boolean,
default: false,
},
},
data: () => ({
keysSwitch: {
a: "ǻ",
A: "Ǡ",
},
optionsModal: false,

Valentin Rigal
committed
}),
created() {
this.inputField.addEventListener("blur", this.looseFocus);
this.inputField.addEventListener("keydown", this.keyInput);
},
beforeDestroy() {
this.inputField.removeEventListener("blur", this.looseFocus);
this.inputField.removeEventListener("keydown", this.keyInput);

Valentin Rigal
committed
},
methods: {
addChar(char) {
// Add a character to the input depending on the cursor selection
const start = this.inputField.selectionStart;
const value = this.inputField.value;
this.inputField.value =
value.slice(0, start) +
char +
value.slice(this.inputField.selectionEnd);
// Reset the input caret after modifying the input value
this.inputField.selectionStart = this.inputField.selectionEnd = start + 1;
},
keyInput(e) {
const character = this.keysSwitch[e.key];
if (!character) return;
this.addChar(character);
e.preventDefault();
},
looseFocus() {
if (this.optionsModal) return;
// We need a short delay before checking where the user moved the focus
setTimeout(() => {
// In case the user typed on the keyboard, restore focus on the input
if (this.$el.contains(document.activeElement))
return this.inputField.focus();
// Otherwise emit a custom event on the input for the keyboard to be removed
this.inputField.dispatchEvent(
new CustomEvent("vk_rmkeyboard", { detail: this })
);
}, 1);
},
},
watch: {
optionsModal(value) {
// Focus the input when closing the modal
if (!value) this.inputField.focus();
},

Valentin Rigal
committed
},
};
</script>
<style scoped>
.virtual-keyboard {
/* Avoid properties inheritance */
all: initial;
/* Override required attributes */

Valentin Rigal
committed
position: absolute;
display: flex;
/* Arbitrary z-index */
z-index: 99999;
width: 20rem;
}
.virtual-keyboard > section {
/* reset style in order to use Pure CSS framework only */
all: unset;
width: 100%;
background-color: white;
border: solid #bfbfbf 1px;
border-radius: 0.25rem;
padding: 0.25rem;

Valentin Rigal
committed
}
button {
width: 3rem;
height: 3rem;
margin: 0.1rem;

Valentin Rigal
committed
}
</style>