<template>
  <span class="wrapper" title="Click to edit text" icon-right="">
    <span ref="text" class="text" :contenteditable="enabled" @blur="input" @keydown="keydown">{{ value }}</span>
    <b-icon class="edit-icon" icon="lead-pencil"/>
  </span>
</template>

<script>
  /**
   * The TextEditable component wraps inline text to allow it to be edited using the HTML contenteditable property. Newlines are replaced with the empty string.
   *
   * @vue-prop [value] {String} Text content.
   * @vue-prop [enabled=true] {Boolean} Whether the content can be edited.
   */
  export default {
  name: 'TextEditable',
  props: {
    value: {type: String, required: false},
    enabled: {type: Boolean, required: false, default: true}
  },
  methods: {
    /**
     * Catch keydown events and translate 'enter' to signal completed input.
     * @param e {KeyboardEvent}
     * @return {boolean|void} Whether to continue event bubbling.
     */
    keydown: function(e) {
      if(e.key.toLowerCase() === 'enter') {
        this.input(e);
        e.preventDefault();
        return false;
      }
    },
    /**
     * Set the content to a new value.
     * @param e {Event}
     */
    input: function(e) {
      const value = e.target.innerText.replace(/\n/g, '');
      this.$refs.text.innerText = value;
      this.$emit('input', value);
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
  .edit-icon {
    margin-left: .5em;
    opacity: 0;
  }
  span:hover > .edit-icon, span:focus + .edit-icon   { opacity: inherit; }
</style>