Giter Site home page Giter Site logo

leecason / element-tiptap Goto Github PK

View Code? Open in Web Editor NEW
1.2K 14.0 154.0 7.38 MB

🌸A modern WYSIWYG rich-text editor using tiptap and Element UI for Vue3 (1.0 for Vue2)

Home Page: https://element-tiptap.vercel.app/

License: MIT License

JavaScript 0.07% HTML 0.19% Vue 32.81% TypeScript 59.35% SCSS 7.57%
vue tiptap tiptap-editor rich-text rich-text-editor wysiwyg element-ui i18n element-editor html-editor

element-tiptap's Introduction

ElTiptap logo

npm GitHub Release Date npm peer dependency version semantic-release GitHub

Element Tiptap Editor

A WYSIWYG rich-text editor using tiptap2 and Element Plus for Vue3

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

🧊 Legacy

Element Tiptap 1.0

📔 Languages

English | 简体中文

🎄 Demo

👉https://leecason.github.io/element-tiptap

👾Code Sandbox

✨ Features

  • 🎨Use element-plus 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, pt_br, nl, he). welcome to contribute more languages
  • 🎈Events you might use: create, transaction, focus, blur, destroy
  • 🍀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 { createApp } from 'vue';
import App from './App.vue';
import ElementPlus from 'element-plus';
import ElementTiptapPlugin from 'element-tiptap';
// import ElementTiptap's styles
import 'element-tiptap/lib/style.css';

const app = createApp(App);

// use ElementPlus's plugin
app.use(ElementPlus);
// use this package's plugin
app.use(ElementTiptapPlugin);
// Now you register `'el-tiptap'` component globally.

app.mount('#app');

Or

Partial import

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

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

🚀 Usage

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

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

// editor extensions
// they will be added to menubar and bubble menu by the order you declare.
const extensions = [
  Doc,
  Text,
  Paragraph,
  Heading.configure({ level: 5 }),
  Bold.configure({ bubble: true }), // render command-button in bubble menu.
  Underline.configure({ bubble: true, menubar: false }), // render command-button in bubble menu but not in menubar.
  Italic,
  Strike,
  BulletList,
  OrderedList,
];

// editor's content
const content = ref(`
  <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
  • BulletList
  • OrderedList
  • TaskList
  • TextAlign
  • Indent
  • LineHeight
  • HorizontalRule
  • HardBreak
  • History
  • Table
  • FormatClear
  • Color
  • Highlight
  • Print
  • Fullscreen
  • SelectAll
  • FontFamily
  • FontSize
  • CodeView

You can find all extensions docs here.

You can customize the extension. See Custom extensions.

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="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 />

when readonly is true, editor is not editable.

spellcheck

Type: boolean

Default: false

<el-tiptap spellcheck> </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%;

enableCharCount

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.

locale

Specifies the editor i18n language.

<template>
  <el-tiptap :locale="en"></el-tiptap>
</template>

<script setup>
import { ElementTiptap } from 'element-tiptap';
import en from 'element-tiptap/lib/locales/en';
</script>

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
  • pt_br by @valterleonardo
  • nl by @Arne-Jan
  • he by @shovalPMS

Welcome contribution.

👽 Events

onCreate

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

<script setup>
/**
 * the tiptap editor instance
 * see https://tiptap.dev/api/editor
 */
const onCreate = ({ editor }) => {
  // ...
};
</script>

onTransaction, onFocus, onBlur, onDestroy

The same as onCreate

🏗 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

element-tiptap's People

Contributors

arne-jan avatar baitkul avatar chlewicki avatar dependabot-preview[bot] avatar eric0324 avatar furtakm avatar halykon avatar hotbrains avatar koas avatar leecason avatar lpabelgium avatar semantic-release-bot avatar shovalpms avatar tbhaxor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

element-tiptap's Issues

shift+enter

Is shift+enter supported? If not, is it possible to add it?

Expected result:
Hitting shift+enter inserts a BR in active P tag.

Actual result:
Hitting shift+enter does nothing.

Inappropriate HTML Render

When the text is aligned centered, the editor should apply some inline styles like style='text-align: center' but its using data-*

<p><strong>This</strong></p><p></p><h1>ddddd</h1><p></p><p data-text-align="center">{{code}}</p>

Due to this the HTML in email not rendered properly

嵌套 dialog 组件 modal 显示异常

问题描述

版本: 1.15.0
问题: 在 dialog 组件中使用图片上传和预览组件的时候会出现遮罩层显示异常的问题
推断原因: dialog 组件没有使用 append-to-body 属性

截图

当期版本的表现
no append-to-body

添加了 append-to-body 后的表现
add append-to-body

Need more explanation regarding custom plugin

How do I create custom extension, say for Heading?
In the doc it is mentioned to extend the Base Class, but what if I want to add a custom class to it?
Is it similar to tiptap, wherein the we need to define it in the schema/doc?

Also can you explain what menuBtnView (editorContext) {} expects and needs to return.

Thanks.
Great work on the plugin!

Question: How do custom extensions pass props to their associated component?

Hello, I've had a hard time understanding the relationship between the custom extensions and their components. Is there perhaps a way you could provide a diagram with all the things you've added on top of TipTap with and how data is being passed back and forth? I've read both TipTap and Prosemirror documentation and I can't seem to understand how it all comes together.

New install `TypeError`

HI, upon new install i get the following error.
[Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'spellcheck' of undefined"
advice please?

Adding own action button

I want implement a template button, that has variables like {{first_name}}, whenever the user clicks on that button, it adds the {{first_name}} at current cursor position

Editor is not visible due to console error

Hey,

After release 1.17.1, I started getting error:
Error in nextTick: "TypeError: Cannot redefine property: isFullscreen"

I have tiptap editor on two different pages and I'm using simple vue transition to switch between them. On initial page load editor is fully visible and functional, but it breaks while navigating to a different page with different editor (same component).

Structure for reference:

Project
|-- components
| |-- ElementTipTap.vue
|-- views
| |-- Page1.vue (imports ElementTipTap component)
| |-- Page2.vue (imports ElementTipTap component)

[feature-request] Quick option for setting disableInputRules and disablePasteRules

The input and paste rules lead to annoying unexpected behavior.
So I suggest disabling them by default or adding a quick option to do so.

I for instance tried to paste LaTeX-Formulas but they were not displayed properly on the website. And it really took me a while to figure out, that the problem had to do something with the editor and that some parts of the formulas were misinterpreted to italian style ;)

Duplicate use of selection JSON ID cell

前几天npm install 之后 npm run dev console出现这样的错误,页面无法加载请问是tiptap-extensions 的问题么?

Uncaught RangeError: Duplicate use of selection JSON ID cell
    at Function.jsonID (webpack-internal:///./node_modules/prosemirror-state/dist/index.es.js:200)
    at eval (webpack-internal:///./node_modules/tiptap-extensions/node_modules/prosemirror-tables/dist/index.es.js:631)
    at Object../node_modules/tiptap-extensions/node_modules/prosemirror-tables/dist/index.es.js (app.js:3341)
    at __webpack_require__ (app.js:708)
    at fn (app.js:113)
    at eval (webpack-internal:///./node_modules/tiptap-extensions/dist/extensions.esm.js:40)
    at Object../node_modules/tiptap-extensions/dist/extensions.esm.js (app.js:3333)
    at __webpack_require__ (app.js:708)
    at fn (app.js:113)
    at Object.eval (webpack-internal:///./node_modules/element-tiptap/lib/element-tiptap.esm.js:38)

Not working in IE11

Hi,
Nothing is getting working in IE 11. It is working in firefox and chrome. Are there plans to support older browsers?
Thanks

H1,h2-h6 不生效

代码如何下

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

<script>
  import Vue from 'vue'
import ElementUI from 'element-ui'
import { ElementTiptapPlugin,
  Doc,
  Text,
  Paragraph,
  Heading,
  Bold,
  Underline,
  Italic,
  Strike,
  ListItem,
  BulletList,
  OrderedList,
  FontType,
  SelectAll,
  Fullscreen,
  Print,
  Preview,
  TextHighlight,
  TextColor,
  FormatClear,
  TableRow,
  TableCell,
  TableHeader,
  Table,
  History,
  TrailingNode,
  HardBreak,
  HorizontalRule,
  LineHeight,
  Indent,
  TextAlign,
  TodoList,
  TodoItem,
  Blockquote,
  CodeBlock,
  Iframe,
  Image,
  Link
  } from 'element-tiptap'

  // 安装 ElementUI 插件
  Vue.use(ElementUI)
// 安装 element-tiptap 插件
Vue.use(ElementTiptapPlugin, { lang: 'zh', spellcheck: true })
// 引入 ElementUI 样式
import 'element-ui/lib/theme-chalk/index.css'
// import element-tiptap 样式
import 'element-tiptap/lib/index.css'
export default {
  // components: {
  //   'el-tiptap': ElementTiptap
  // },
    data() {
      return {
        extensions: [
          new Doc(),
          new Text(),
          new Paragraph(),
          new Heading({level: 5}),
          new Bold(), // 在气泡菜单中渲染菜单按钮
          new Underline(),
          new Italic(),
          new Strike(),
          new ListItem(),
          new BulletList(),
          new OrderedList(),
          new FontType(),
          new SelectAll(),
          new Fullscreen(),
          new Print(),
          new Preview(),
          new TextHighlight(),
          new TextColor(),
          new FormatClear(),
          new TableRow(),
          new TableCell(),
          new TableHeader(),
          new Table(),
          new History(),
          new TrailingNode(),
          new HardBreak(),
          new HorizontalRule(),
          new LineHeight(),
          new Indent(),
          new TextAlign(),
          new TodoList(),
          new TodoItem(),
          new Blockquote(),
          new CodeBlock(),
          new Iframe(),
          new Image(),
          new Link()
        ],
        content: ''
      }
    }
}
</script>
<style lang="scss" scoped>
  .el-tips-page {
    width:100%;
    height:100%;
    min-height: 400px;
    min-width: 50vw;
  }
</style>

image

image

图片相关问题

图片上传到自定义的服务器暴露的api是什么,图片上传过程中是否可以提供可自定义的占位符,图片是否可以实现旋转。这些是希望开箱可用的。

Grouping extentions

I want to group the BOLD, ITALIC, UNDERLINE extensions under category, STYLES, is there any option?

视频插入不了

视频插入的时候提示这个是为什么?

vue.runtime.esm.js:619 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

found in

---> Anonymous>
EditorContent>
ElTiptap>

大佬,如何实现图片空间。。

终于看到一个一眼就心动的编辑器了,太棒了。
插入图片是否可以设计一个服务器得图片空间,从图片空间中得图片选择进行插入。同时页能批量上传图片到图片空间。
希望能有这样的一个组件或者指一条明路。

Custom upload image event

Can't upload image as a custom event? This event is used to upload directly to the server, return the image address, and insert it into the editor

Feature request: disable default content styles

Right now I need to overwrite default editor styles in order to apply my global styles. Would be nice if the editor could optionally inherit these styles for its content alone. Menu-bar is fine, I wouldn't want to change that.

i18n a translation error

zh:

      Indent: {
        buttons: {
          indent: {
            tooltip: '增加锁进',// error
          },
          outdent: {
            tooltip: '减少锁进',//error
          },
        },
      },

Indent = 缩进

[Bug]Table create and delete problem

For Creating

I selected 6 * 2 table in menubar, but got 2 * 6 table in content

image
image

For Deleting

No matter I select all the table and press 『Delete』to delete all the table,or focu on a table cell and press 『Delete』, I can't delete table、 table row or table column.

Insert link not working

Hi, I have problem with "apply link". Pasted link did not show up after insert.
Demo

Tested on Firefox and Chromium.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.