Leecason / element-tiptap

🌸A modern WYSIWYG rich-text editor using tiptap and Element UI for Vue3 (1.0 for Vue2)
https://element-tiptap.vercel.app/
MIT License
1.33k stars 164 forks source link

Subscript/superscript #443

Open t56k opened 2 years ago

t56k commented 2 years ago

I'm trying to implement both these extensions but I'm stuck. Has anyone had any luck with these?

t56k commented 2 years ago

For anyone else that's stuck:

import { Mark } from 'tiptap'
import { toggleMark, markInputRule, markPasteRule } from 'tiptap-commands'

import { MenuBtnView } from 'element-tiptap'
import CommandButton from 'components/CommandButton.vue'

export default class Subscript extends Mark {
  get name() {
    return 'subscript'
  }

  get schema() {
    return {
      parseDOM: [{
        tag: 'sub',
      }],
      toDOM: () => ['sub', 0],
    }
  }

  keys({ type }) {
    return {
      'Mod-,': () => toggleMark(type)
    }
  }

  commands({ type }) {
    return () => toggleMark(type)
  }

  inputRules({ type }) {
    return [
      markInputRule(/~([^~]+)~$/, type),
    ]
  }

  pasteRules({ type }) {
    return [
      markPasteRule(/~([^~]+)~/g, type),
    ]
  }

  menuBtnView({ isActive, commands }) {
    return {
      component: CommandButton,
      componentProps: {
        command: commands.subscript,
        isActive: isActive.subscript(),
        icon: 'subscript',
        tooltip: 'Subscript',
      },
    }
  }
}

This project is in Javascript so I had to convert it from Typescript. I made a custom CommandButton too:

<template>
  <el-tooltip
    :content="tooltip"
    :open-delay="350"
    :disabled="!enableTooltip || readonly"
    transition="el-zoom-in-bottom"
    effect="dark"
    placement="top"
  >
    <div
      :class="`
        el-tiptap-editor__command-button
        ${this.isActive ? 'el-tiptap-editor__command-button--active' : ''}
        ${this.readonly ? 'el-tiptap-editor__command-button--readonly' : ''}
      `"
      @mousedown.prevent
      @click="onClick"
    >
      <v-icon :name="icon"/>
    </div>
  </el-tooltip>
</template>

<script>
  import Icon from 'vue-awesome'

  import 'vue-awesome/icons/subscript'
  import 'vue-awesome/icons/superscript'

  import { Tooltip } from 'element-ui'

  export default {
    name: 'CommandButton',

    props: {
      icon: {
        type: String,
        required: true,
      },
      isActive: {
        type: Boolean,
        default: false,
      },
      tooltip: {
        type: String,
        required: true,
      },
      enableTooltip: {
        type: Boolean,
        required: true,
      },
      command: {
        type: Function,
      },
      readonly: {
        type: Boolean,
        default: false,
      }
    },

    components: {
      'v-icon': Icon,
      [Tooltip.name]: Tooltip,
    },

    methods: {
      onClick() {
        if (!this.readonly) this.command()
      }
    }
  }
</script>

Hope this helps someone.