Skip to content
Snippets Groups Projects
KeyboardDisplay.vue 3.15 KiB
Newer Older
  <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>
import Modal from "./Modal.vue";
  components: {
    Modal,
  },
  props: {
    inputField: {
      type: [HTMLInputElement, HTMLTextAreaElement],
      required: true,
    },
    keysSwitch: {
      a: "ǻ",
      A: "Ǡ",
    },
    optionsModal: false,
  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);
  },
  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();
    },
  /* Avoid properties inheritance */
  all: initial;
  /* Override required attributes */
  /* 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;
  width: 3rem;
  height: 3rem;
  margin: 0.1rem;