/element-tiptap

๐ŸŒธA modern WYSIWYG rich-text editor using tiptap and Element UI for Vue.js

Primary LanguageTypeScriptMIT LicenseMIT

ElTiptap logo

npm CircleCI gzipped size GitHub Release Date npm peer dependency version semantic-release GitHub

Element Tiptap Editor

A WYSIWYG rich-text editor using tiptap and Element UI for Vue.js

that's easy to use, friendly to developers, fully extensible and clean in design.

๐Ÿ“” Languages

English | ็ฎ€ไฝ“ไธญๆ–‡

๐ŸŽ„ Demo

๐Ÿ‘‰https://leecason.github.io/element-tiptap

๐Ÿ‘พCode Sandbox

โœจ Features

  • ๐ŸŽจUse element-ui components
  • ๐Ÿ’…Many out of box extensions (welcome to submit an issue for feature request๐Ÿ‘)
  • ๐Ÿ”–Markdown support
  • ๐Ÿ“˜TypeScript support
  • ๐ŸŒI18n support(en, zh, pl, ru, de, ko, es, zh_tw, fr). welcome to contribute more languages
  • ๐ŸŽˆEvents you might use: init, transaction, focus, blur, paste, drop, update
  • ๐Ÿ€Fully extensible, you can customize editor extension and its menu button view
  • ๐Ÿ’ปAlso can control the behavior of the editor directly, customize the editor for yourself.

๐Ÿ“ฆ Installation

NPM

yarn add element-tiptap

Or

npm install --save element-tiptap

Install plugin

import Vue from 'vue';
import ElementUI from 'element-ui';
import { ElementTiptapPlugin } from 'element-tiptap';
// import ElementUI's styles
import 'element-ui/lib/theme-chalk/index.css';
// import this package's styles
import 'element-tiptap/lib/index.css';

// use ElementUI's plugin
Vue.use(ElementUI);
// use this package's plugin
Vue.use(ElementTiptapPlugin, { /* plugin options */ });
// Now you register `'el-tiptap'` component globally.

Default plugin options:

{
  lang: "en", // see i18n
  spellcheck: true, // can be overwritten by editor prop
}

Or

Partial import

<template>
  <div>
    <el-tiptap ...></el-tiptap>
  </div>
</template>

<script>
import { ElementTiptap } from 'element-tiptap';

export default {
  components: {
    'el-tiptap': ElementTiptap,
  },
};
</script>

๐ŸŒ I18n

You can declare when you install the plugin.

Vue.use(ElementTiptapPlugin, {
  lang: 'zh',
});

Available languages:

  • en(default)
  • zh
  • pl by @FurtakM
  • ru by @baitkul
  • de by @Thesicstar
  • ko by @Hotbrains
  • es by @koas
  • zh_tw by @eric0324
  • fr by @LPABelgium

Welcome contribution.

๐Ÿš€ Usage

<template>
  <div>
    <el-tiptap
      v-model="content"
      :extensions="extensions"
    />
  </div>
</template>

<script>
import {
  // necessary extensions
  Doc,
  Text,
  Paragraph,
  Heading,
  Bold,
  Underline,
  Italic,
  Strike,
  ListItem,
  BulletList,
  OrderedList,
} from 'element-tiptap';

export default {
  data () {
    // editor extensions
    // they will be added to menubar and bubble menu by the order you declare.
    return {
      extensions: [
        new Doc(),
        new Text(),
        new Paragraph(),
        new Heading({ level: 5 }),
        new Bold({ bubble: true }), // render command-button in bubble menu.
        new Underline({ bubble: true, menubar: false }), // render command-button in bubble menu but not in menubar.
        new Italic(),
        new Strike(),
        new ListItem(),
        new BulletList(),
        new OrderedList(),
      ],
      // editor's content
      content: `
        <h1>Heading</h1>
        <p>This Editor is awesome!</p>
      `,
    };
  },
},
</script>

๐Ÿ“” Props

extensions

Type: Array

You can use the necessary extensions. The corresponding command-buttons will be added by declaring the order of the extension.

All available extensions:

  • Doc
  • Text
  • Paragraph
  • Heading
  • Bold
  • Italic
  • Strike
  • Underline
  • Link
  • Image
  • Iframe
  • CodeBlock
  • Blockquote
  • ListItem
  • BulletList (use with ListItem)
  • OrderedList (use with ListItem)
  • TodoItem
  • TodoList (use with TodoItem)
  • TextAlign
  • Indent
  • LineHeight
  • HorizontalRule
  • HardBreak
  • TrailingNode
  • History
  • Table (use with TableHeader, TableCell, TableRow)
  • TableHeader
  • TableCell
  • TableRow
  • FormatClear
  • TextColor
  • TextHighlight
  • Preview
  • Print
  • Fullscreen
  • SelectAll
  • FontType
  • FontSize
  • CodeView (๐Ÿ†•)

You can find all extensions docs here.

You can customize the extension menu button view

  1. create your custom extension.
// create your extension file
import { Bold } from 'element-tiptap';

export default class CustomBold extends Bold {
  menuBtnView (editorContext) {
    // editorContext contains some properties that are useful to you, such as isActive, commands, etc
    // more detailed docs check this https://github.com/scrumpy/tiptap#editormenubar
    // this package append editor instance to editorContext
    return {
      component: CustomButton, // your component
      componentProps: { // bind to your component with v-bind
        ...
      },
      componentEvents: { // bind to your component with v-on
        ...
      },
    },
  }
}
  1. use custom extension in component
<template>
  <el-tiptap :extensions="extensions" />
</template>

<script>
import CustomBold from '...'; // import your extension

export default {
  ...
  data () {
    return {
      extensions: [
        ...
        new CustomBold(),
      ],
    };
  },
};
</script>

Here is the example of how to create your extension button view (an extension can also render multiple menu buttons).

editorProperties

Type: Object

Default: {}

Tiptap Editor properties (passed to the constructor).

see the full list of properties here.

editorProps is a powerful prop in this list, you can use this prop to control the behavior of the editor directly, customize the editor for yourself.

โ—not available propertiesโ—(they are used in this package):

  • content
  • editable
  • useBuiltInExtensions
  • extensions
  • onInit
  • OnFocus
  • onBlur
  • onUpdate

placeholder

Type: string

Default: ''

When editor is empty, placeholder will display.

<el-tiptap
  placeholder="Write something โ€ฆ"
/>

content

Type: string

Default: ''

Editor's content

<el-tiptap
  :content="content"
  @onUpdate="onEditorUpdate"
/>

or Use 'v-model'

<el-tiptap
  v-model="content"
/>

output

Type: string

Default: 'html'

Output can be defined to 'html' or 'json'.

<el-tiptap
  output="json"
/>

further reading: prosemirror data structure

readonly

Type: boolean

Default: false

<el-tiptap
  :readonly="true"
/>

when readonly is true, editor is not editable.

spellcheck

Type: boolean

Default: plugin spellcheck option value

<el-tiptap
  :spellcheck="true"
>
</el-tiptap>

Whether the content is spellcheck enabled.

width, height

Type: string | number

A string value with unit or a simple value (the default unit is px)๏ผš

<el-tiptap
  :width="700"
  height="100%"
>
</el-tiptap>

The above example will be converted to:

width: 700px;
height: 100%;

showMenubar

Type: boolean

Default: true

Enables or disables the display of the menubar.

charCounterCount

Type: boolean

Default: true

Enables or disables the display of the character counter.

tooltip

Type: boolean

Default: true

Control if tooltips are shown when getting with mouse over the buttons from the toolbar.

lang

Type: string

Default: plugin lang option value

<el-tiptap
  lang="zh"
>
</el-tiptap>

Specifies the editor i18n language.

๐Ÿ‘ฝ Events

Init

<template>
  <el-tiptap
    @onInit="onInit"
  />
</template>

<script>
export default {
  ...
  methods: {
    /*
     * the tiptap editor instance
     * see https://tiptap.scrumpy.io/docs/guide/editor.html
    */
    onInit ({ editor }) {

    },
  },
},
</script>

Transaction, Focus, Blur, Paste, Drop

The same as init

โš—๏ธ Slots

menubar

You can customize the menubar and will receive some properties through a scoped slot.

properties: https://github.com/scrumpy/tiptap#editormenubar

<el-tiptap
  v-model="content"
  :extensions="extensions"
>
  <!-- new syntax for slot since Vue 2.6.0
  see: https://vuejs.org/v2/guide/components-slots.html -->
  <template #menubar="{ commands, isActive }">
    <!--You can render custom menu buttons.-->
    <custom-button
      :class="{ 'is-active': isActive.bold() }"
      @click="commands.bold"
    >
      Bold
    </custom-button>
  </template>
</el-tiptap>

menububble

Customize the bubble menu like menubar.

properties: https://github.com/scrumpy/tiptap#editormenububble

<el-tiptap
  v-model="content"
  :extensions="extensions"
>
  <template #menububble="{ commands, isActive }">
    <custom-button
      :class="{ 'is-active': isActive.bold() }"
      @click="commands.bold"
    >
      Bold
    </custom-button>
  </template>
</el-tiptap>

footer

Footer of the editor, after the editor content.

๐Ÿ— Contributing

Please see CONTRIBUTING for details.

๐Ÿ“ Changelog

Changelog

๐Ÿ“„ License

MIT

๐Ÿ’ Buy Me A Coffee

I am so happy that so many people like this project, and I will do better with your support.

reward Buy Me A Coffee