Vuetify Pro Tiptap

repository·master·Indexed 42 days ago

https://github.com/yikoyu/vuetify-pro-tiptap

A WYSIWYG rich-text editor for Vue.js that integrates the Tiptap engine with Vuetify components. Version 3.0.0 provides a customizable editing experience with support for markdown, TypeScript, and internationalization, featuring components like VuetifyTiptap and VuetifyViewer.

Tokens
14.3K
Snippets
48
Records
56
Agent score
54%

What's inside Vuetify Pro Tiptap

  1. Customize the Markdown theme with SCSS

    master

    To create a custom markdown theme, define an SCSS file using the .markdown-theme-{name} class pattern. You can then import your custom styles instead of the default ones.

    1. Create a .scss file:
    $value: 'my-custom-theme';
    .vuetify-pro-tiptap-editor__content.markdown-theme-#{$value} {
      .tiptap.ProseMirror, .content {
        /* your custom styles */
      }
    }
    1. Import the editor styles and your custom theme in your entry point:
    import 'vuetify-pro-tiptap/styles/editor.css'
    import './styles/markdown/my-custom-theme.scss'
    1. Apply the theme to the components:
    <VuetifyTiptap v-model="content" markdown-theme="my-custom-theme" />
    <template>
      <VuetifyTiptap v-model="content" markdown-theme="github" />
      <VuetifyViewer :value="content" markdown-theme="github" />
    </template>
  2. Initialize and install the Vuetify Pro Tiptap plugin

    master

    To use the editor, you must create a plugin instance using createVuetifyProTipTap and register it with your Vue application. You should provide the components (VuetifyTiptap, VuetifyViewer) and an array of extensions to define the editor's capabilities.

    Note: When using Vue 3, it is recommended to set app.config.unwrapInjectedRef = true to avoid warnings related to injected properties.

    import { createApp } from 'vue'
    import { createVuetify } from 'vuetify'
    import { VuetifyTiptap, VuetifyViewer, createVuetifyProTipTap } from 'vuetify-pro-tiptap'
    import 'vuetify-pro-tiptap/style.css'
    
    // 1. Create the plugin instance
    export const vuetifyProTipTap = createVuetifyProTipTap({
      lang: 'zhHans',
      fallbackLang: 'en',
      components: {
        VuetifyTiptap,
        VuetifyViewer
      },
      extensions: [
        // Add extensions here, e.g., Bold, Italic, etc.
      ]
    })
    
    // 2. Register with Vue app
    const app = createApp(App)
    app.use(createVuetify())
    app.use(vuetifyProTipTap)
    app.config.unwrapInjectedRef = true
    app.mount('#app')
  3. Configure and install the Vuetify Pro Tiptap plugin

    master

    To use the editor, you must initialize it using createVuetifyProTipTap. This function allows you to configure global settings, register components (like VuetifyTiptap and VuetifyViewer), and define which extensions are available in the editor toolbar.

    Note: For Vue 3 projects, you should also set app.config.unwrapInjectedRef = true to prevent warnings related to injected properties.

    import { markRaw } from 'vue'
    import { VuetifyTiptap, VuetifyViewer, createVuetifyProTipTap } from 'vuetify-pro-tiptap'
    import { BaseKit, Bold, Italic, Underline, Strike, Code, Heading, TextAlign, FontFamily, FontSize, SubAndSuperScript, BulletList, OrderedList, TaskList, Indent, Link, Image, Video, Table, Blockquote, HorizontalRule, CodeBlock, Clear, Fullscreen, History } from 'vuetify-pro-tiptap'
    import 'vuetify-pro-tiptap/style.css'
    
    export const vuetifyProTipTap = createVuetifyProTipTap({
      lang: 'zhHans',
      fallbackLang: 'en',
      components: {
        VuetifyTiptap,
        VuetifyViewer
      },
      extensions: [
        BaseKit.configure({
          placeholder: { placeholder: 'Enter some text...' }
        }),
        Bold,
        Italic,
        // ... add other extensions as needed
        Image.configure({
          imageTabs: [{ name: 'SELECT', component: markRaw(MySelectComponent) }],
          upload(file: File) {
            const url = URL.createObjectURL(file)
            return Promise.resolve(url)
          }
        }),
        Fullscreen
      ]
    })
    
    // In your main.ts
    const app = createApp(App)
    app.use(vuetify)
    app.use(vuetifyProTipTap)
    app.config.unwrapInjectedRef = true
    app.mount('#app')
  4. Customize Markdown themes with SCSS

    master

    To create a custom markdown theme, define an SCSS file using the .markdown-theme-{value} class pattern. You can then import the specific editor styles and your custom theme separately to avoid loading unnecessary styles.

    1. Create github.scss:
    $value: 'github';
    .vuetify-pro-tiptap-editor__content.markdown-theme-#{$value} {
      &.__dark { /* dark mode styles */ }
      .tiptap.ProseMirror, .content { /* custom styles */ }
    }
    1. Import in your TypeScript entry point:
    import 'vuetify-pro-tiptap/styles/editor.css' // Editor only
    import './styles/markdown/github.scss'       // Your custom theme
    1. Use in component:
    <VuetifyTiptap v-model="content" markdown-theme="github" />
    import 'vuetify-pro-tiptap/styles/editor.css'
    import './styles/markdown/github.scss'
    
    // In template
    <VuetifyTiptap v-model="content" markdown-theme="github" />
  5. Install vuetify-pro-tiptap via NPM

    master

    Install the package using your preferred package manager:

    pnpm add vuetify-pro-tiptap
    # or
    yarn add vuetify-pro-tiptap
    # or
    npm i vuetify-pro-tiptap -S
    pnpm add vuetify-pro-tiptap
  6. Configure global settings and bubble menu

    master

    You can customize the editor's behavior globally via createVuetifyProTipTap. Key configuration options include:

    • lang: The default language.
    • fallbackLang: The fallback language if the current language is missing a translation.
    • markdownTheme: The theme used for rendering markdown (e.g., 'github').
    • components: Global registration of components like VuetifyTiptap and VuetifyViewer.
    • extensions: An array of extensions. You can use BaseKit.configure to customize the bubble menu items for different content types (image, text, video).
    export const vuetifyProTipTap = createVuetifyProTipTap({
      lang: 'zhHans',
      fallbackLang: 'en',
      markdownTheme: 'github',
      components: {
        VuetifyTiptap,
        VuetifyViewer
      },
      extensions: [
        BaseKit.configure({
          bubble: {
            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 => defaultBubbleList(editor)
          }
        }),
        // ... other extensions
      ]
    })
  7. Define custom ButtonViews for extensions

    master

    To customize how an extension's button appears in the toolbar, you can provide a ButtonView function via GeneralOptions.

    1. Implement the ButtonView function: It receives ButtonViewParams containing the editor, the extension instance, and a translation function t.
    2. Return a ButtonViewReturn: This object specifies the Vue component to render, its props (like icon, tooltip, and isActive state), and its slots.

    This allows you to inject custom logic, such as toggling states or opening dialogs, directly into the toolbar buttons.

    // Example structure of a ButtonView return
    export interface ButtonViewReturn {
      component: unknown
      componentProps: {
        action?: (value?: unknown) => void
        isActive?: () => boolean
        icon?: keyof IconsOptions
        tooltip?: string
        [x: string]: any
      }
      componentSlots?: {
        dialog: () => any
        [x: string]: () => any
      }
    }
  8. Automatic video URL conversion

    master

    The Video extension automatically converts various video platform URLs into embeddable formats during the renderHTML process. Supported conversions include:

    • YouTube: Converts https://youtu.be/ or watch?v= links to https://www.youtube.com/embed/.
    • Vimeo: Converts https://vimeo.com/ links to https://player.vimeo.com/video/.
    • Bilibili: Converts https://www.bilibili.com/video/ links to the Bilibili player format (https://player.bilibili.com/player.html?bvid=...).
    • Google Drive: Converts /view links to /preview links to allow embedding.
  9. Configure Bubble Menu items and node types

    master

    The bubble menu is configured using BubbleOptions, which defines which menu items appear for specific Tiptap node types. You can map NodeTypeKey values (like 'table', 'image', 'text', 'link', or 'video') to arrays of BubbleAllType items.

    Key Types

    • NodeTypeKey: The supported Tiptap node types: 'table', 'image', 'text', 'link', 'video'.
    • BubbleAllType: The identifier for a specific menu action. This can be a built-in type (e.g., 'divider', 'remove', 'unlink'), a node-specific type (e.g., 'table-add-row-before', 'image-size-small'), or a custom extension name.
    • BubbleMenuItem: An object representing a single button in the menu. It must include a type and follows the ButtonViewReturn structure (providing a component, componentProps, and componentSlots).
  10. Configure the BaseKit bubble menu

    master

    The bubble option in BaseKitOptions controls the bubble menu functionality. It accepts a Partial<BubbleOptions<BaseKitOptions>> object. This allows you to customize how the bubble menu is triggered and what content it displays.

    Key configuration properties within bubble include:

    • list: A mapping of node types to menus (uses NODE_TYPE_MENU by default).
    • defaultBubbleList: A function that returns the default list of menu items for the editor.
    • button: A function used to generate the menu button, providing access to the editor, extension, and a translation function t.
  11. Configure global settings for Vuetify Pro Tiptap

    master

    You can customize the editor's behavior globally via the createVuetifyProTipTap configuration object. Key options include:

    • lang: The default language.
    • fallbackLang: The language to use if the current language is unavailable.
    • markdownTheme: The theme used for rendering markdown (e.g., 'github').
    • components: Global registration of VuetifyTiptap and VuetifyViewer.
    • extensions: An array of extensions. You can use .configure() on extensions like BaseKit or Image to set specific behaviors, such as custom bubble menus or upload functions.
    export const vuetifyProTipTap = createVuetifyProTipTap({
      lang: 'zhHans',
      fallbackLang: 'en',
      markdownTheme: 'github',
      components: {
        VuetifyTiptap,
        VuetifyViewer
      },
      extensions: [
        BaseKit.configure({
          bubble: {
            list: {
              text: ['bold', 'italic', 'underline', 'strike', 'divider', 'color', 'highlight', 'textAlign', 'divider', 'link']
            },
            defaultBubbleList: editor => defaultBubbleList(editor)
          }
        }),
        Image.configure({
          divider: true,
          upload(file) {
            const url = URL.createObjectURL(file)
            return Promise.resolve(url)
          }
        })
      ]
    })