New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

vuetify-pro-tiptap

Package Overview
Dependencies
Maintainers
0
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vuetify-pro-tiptap

tiptap text editor on vuejs and vuetify

2.5.7
latest
Source
npm
Version published
Maintainers
0
Created
Source

Vuetify Pro Tiptap

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

download version gzip Test LICENSE semantic-release: vue

English | 中文

Demo

👉https://yikoyu.github.io/vuetify-pro-tiptap/

👾Stackblitz

👾Nuxt3 Stackblitz

Features

  • Use vuetify components
  • Many out of box extension (welcome to submit an issue for feature request)
  • Markdown support
  • TypeScript support
  • I18n support(en, zhHans, nl)
  • Vuetify 3.x and Vue 3.x support

Vuetify 2.x

For Vuetify 2.x please use the latest version of vuetify-pro-tiptap@1.X.X

Installation

NPM

pnpm add vuetify-pro-tiptap
# or
yarn add vuetify-pro-tiptap
# or
npm i vuetify-pro-tiptap -S

Install plugin

tiptap.ts
import { markRaw } from 'vue'
import { VuetifyTiptap, VuetifyViewer, createVuetifyProTipTap } from 'vuetify-pro-tiptap'
import { BaseKit, Bold, Italic, Underline, Strike, Color, Highlight, Heading, TextAlign, FontFamily, FontSize, SubAndSuperScript, BulletList, OrderedList, TaskList, Indent, Link, Image, Video, Table, Blockquote, HorizontalRule, Code, CodeBlock, Clear, Fullscreen, History } from 'vuetify-pro-tiptap'
import 'vuetify-pro-tiptap/style.css'
import SelectImage from './components/SelectImage.vue'

export const vuetifyProTipTap = createVuetifyProTipTap({
  lang: 'zhHans',
  components: {
    VuetifyTiptap,
    VuetifyViewer
  },
  extensions: [
    BaseKit.configure({
      placeholder: {
        placeholder: 'Enter some text...'
      }
    }),
    Bold,
    Italic,
    Underline,
    Strike,
    Code.configure({ divider: true }),
    Heading,
    TextAlign,
    FontFamily,
    FontSize,
    Color,
    Highlight.configure({ divider: true }),
    SubAndSuperScript.configure({ divider: true }),
    Clear.configure({ divider: true }),
    BulletList,
    OrderedList,
    TaskList,
    Indent.configure({ divider: true }),
    Link,
    Image.configure({
      imageTabs: [{ name: 'SELECT', component: markRaw(SelectImage) }],
      // hiddenTabs: ['upload'],
      upload(file: File) {
        const url = URL.createObjectURL(file)
        console.log('mock upload api :>> ', url)
        return Promise.resolve(url)
      }
    }),
    Video,
    Table.configure({ divider: true }),
    Blockquote,
    HorizontalRule,
    CodeBlock.configure({ divider: true }),
    History.configure({ divider: true }),
    Fullscreen
  ]
})
main.ts
import { createApp } from 'vue'
import { createVuetify } from 'vuetify'
import App from './App.vue'
import { vuetifyProTipTap } from './tiptap'

import 'vuetify/styles'

const vuetify = createVuetify()

const app = createApp(App)
app.use(vuetify)
app.use(vuetifyProTipTap)

// fix warning injected property "decorationClasses" is a ref and will be auto-unwrapped
// https://github.com/ueberdosis/tiptap/issues/1719
app.config.unwrapInjectedRef = true

app.mount('#app')

Global Settings

import { markRaw } from 'vue'
import { VuetifyTiptap, VuetifyViewer, createVuetifyProTipTap, defaultBubbleList } from 'vuetify-pro-tiptap'
import { BaseKit, Image, Fullscreen } from 'vuetify-pro-tiptap'
import 'vuetify-pro-tiptap/style.css'
import SelectImage from './components/SelectImage.vue'

export const vuetifyProTipTap = createVuetifyProTipTap({
  // Set default lang
  lang: 'zhHans',
  // Set markdown theme
  markdownTheme: 'github',
  // Global registration app.component
  components: {
    VuetifyTiptap,
    VuetifyViewer
  },
  // Global registration extensions
  extensions: [
    BaseKit.configure({
      placeholder: {
        placeholder: 'Enter some text...'
      },
      bubble: {
        // default config
        list: {
          image: [ 'float-left', 'float-none', 'float-right', 'divider', 'size-small', 'size-medium', 'size-large', 'divider', 'textAlign', 'divider', 'image', 'image-aspect-ratio', 'remove'],
          text: ['bold', 'italic', 'underline', 'strike', 'divider', 'color', 'highlight', 'textAlign', 'divider', 'link'],
          video: ['video', 'remove']
        },
        defaultBubbleList: editor => {
          // You can customize the bubble menu here
          return defaultBubbleList(editor) // default customize bubble list
        }
      }
    }),
    Image.configure({
      // Generate a VDivider after the button
      divider: true,
      // Custom image tabs
      imageTabs: [{ name: 'SELECT', component: markRaw(SelectImage) }],
      // hidden default tab
      hiddenTabs: ['upload'],
      // custom upload function
      upload(file) {
        const url = URL.createObjectURL(file)
        console.log('mock upload api :>> ', url)
        return Promise.resolve(url)
      }
    }),
    Fullscreen.configure({
      // Generate a VSpacer after the button
      spacer: true
    })
  ]
})

Extensions

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

All available extensions:

Custom theme

Create github.scss

$value: 'github';

.vuetify-pro-tiptap-editor__content.markdown-theme-#{$value} {
  // your custom styles
  &.__dark {
    // your dark mode custom styles
  }
}

Import github.scss in ts

// import 'vuetify-pro-tiptap/style.css' // import all(editor and markdown) styles
import 'vuetify-pro-tiptap/styles/editor.css' // only use editor style, not using markdown style
import './styles/markdown/github.scss'

In the component using

<template>
  <VuetifyTiptap v-model="content" markdown-theme="github" />
  <VuetifyViewer :value="content" markdown-theme="github" />
</template>

Custom extensions

PreviewActionButton.vue
<script setup lang="ts">
import type { Editor } from '@tiptap/vue-3'
import { mdiClose, mdiFileCodeOutline } from '@mdi/js'
import { ref } from 'vue'
import { ActionButton } from 'vuetify-pro-tiptap'

interface Props {
  editor: Editor
  tooltip?: string
  disabled?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  tooltip: undefined,
  disabled: false
})

const dialog = ref(false)
const maxWidth = ref<number>(900)
</script>

<template>
  <ActionButton tooltip="全屏" :disabled="disabled">
    <VIcon>{{ `svg:${mdiFileCodeOutline}` }}</VIcon>
    <VDialog v-model="dialog" fullscreen hide-overlay activator="parent">
      <VCard>
        <VToolbar dark color="primary">
          <VBtn icon dark @click="dialog = false">
            <VIcon>{{ `svg:${mdiClose}` }}</VIcon>
          </VBtn>
        </VToolbar>

        <VContainer>
          <VSheet class="mx-auto" :max-width="maxWidth">
            <VuetifyViewer :value="editor.getHTML()" />
          </VSheet>
        </VContainer>
      </VCard>
    </VDialog>
  </ActionButton>
</template>
preview.ts
import type { ButtonView, GeneralOptions } from 'vuetify-pro-tiptap'

import { Extension } from '@tiptap/core'
import PreviewActionButton from '../components/PreviewActionButton.vue'

export interface PreviewOptions extends GeneralOptions {
  button: ButtonView
}

export default Extension.create<PreviewOptions>({
  name: 'preview',
  addOptions() {
    return {
      divider: false,
      spacer: false,
      button: () => ({
        component: PreviewActionButton,
        componentProps: {}
      })
    }
  }
})

I18n

Setting language

You can declare when you install the plugin.

import { createVuetifyProTipTap } from 'vuetify-pro-tiptap'

const VuetifyProTipTap = createVuetifyProTipTap({
  lang: 'zhHans'
})

Or use setLang dynamic change

import { locale } from 'vuetify-pro-tiptap'

locale.setLang('en')

Available languages:

  • en (default)
  • zhHans
  • nl
  • de

Use unavailable language

Loading unavailable language, use setMessage for Settings

import { locale } from 'vuetify-pro-tiptap'

locale.setMessage('zhHant', {
  // i18n text
})
locale.setLang('zhHant')

Usage

<script setup lang="ts">
import { ref } from 'vue'
import { BaseKit, Bold, Color, Fullscreen, Heading, Highlight, History, Image, Italic, Link, Strike, Table, Underline, Video, VuetifyTiptap, VuetifyViewer } from 'vuetify-pro-tiptap'
import 'vuetify-pro-tiptap/style.css'

const extensions = [
  BaseKit.configure({
    placeholder: {
      placeholder: 'Enter some text...'
    }
  }),
  Bold,
  Italic,
  Underline,
  Strike,
  Color,
  Highlight,
  Heading,
  Link,
  Image,
  Video,
  Table,
  Fullscreen,
  History
]

const content = ref('')
</script>

<template>
  <VApp id="app">
    <VContainer>
      <VuetifyTiptap v-model="content" label="Title" rounded :min-height="200" :max-height="465" :max-width="900" :extensions="extensions" />
      <VuetifyViewer :value="content" />
    </VContainer>
  </VApp>
</template>

Props

VuetifyTiptap

Props
NameTypeDefaultDescription
modelValuestring | JSONContent''The input’s value
markdownThemestring | false'default'Markdown theme
output'html' | 'json' | 'text''html'Output format
darkbooleanfalseApplies the dark theme variant to the component.
densebooleanfalseReduces the input height
outlinedbooleantrueApplies the outlined style to the input
flatbooleantrueRemoves the card’s elevation
disabledbooleanfalseDisable the input
labelstringundefinedSets input label
hideToolbarbooleanfalseHidden the toolbar
disableToolbarbooleanfalseDisable the toolbar
hideBubblebooleanfalseHidden the bubble menu
removeDefaultWrapperbooleanfalseDefault wrapper when the delete editor is empty
maxWidthstring | numberundefinedSets the maximum width for the component.
minHeightstring | numberundefinedSets the minimum height for the component.
maxHeightstring | numberundefinedSets the maximum height for the component.
extensionsAnyExtension[][]Tiptap the extensions
editorClassstring | string[] | Record<string, any>undefinedEditor class
Slots
NameDescription
editorSlot to customize editor
bottomSlot to customize editor bottom
Event
NameTypeDescription
update:modelValuestring | JSONContentEmitted when editor onUpdate
update:markdownThemestringEmitted when change theme
change{ editor: Editor, output: string | JSONContent }Emitted when editor onUpdate
enterKeyboard enter return

VuetifyViewer

Props
NameTypeDefaultDescription
valuestring | JSONContent''The preview’s value
darkbooleanfalseApplies the dark theme variant to the component.
densebooleanfalseReduces the input height
markdownThemestring | false'default'Markdown theme
xssbooleantrueEnable xss filter
xssOptionsxss.IWhiteListDefault ruleXss filter rule config
maxWidthstring | numberundefinedSets the maximum width for the component.
extensionsAnyExtension[][]Tiptap the extensions
Slots
NameDescription
beforeAdd content at the before
afterAdd content at the after

🏗 Contributing

  • 🍴Fork it
  • 🔀Create your branch: git checkout -b your-branch
  • 🎨Make your changes
  • 📝Commit your changes with Semantic Commit Messages (recommended)
  • 🚀Push to the branch: git push origin your-branch
  • 🎉Submit a PR to develop branch

📄 License

MIT

Thanks

Keywords

vue

FAQs

Package last updated on 03 Jan 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts