Skip to content

Latest commit

 

History

History
367 lines (290 loc) · 8.45 KB

File metadata and controls

367 lines (290 loc) · 8.45 KB
outline deep

Examples

This page showcases different editor configurations and use cases built with vue-quilly. Each example demonstrates specific features and integration patterns.

Snow Theme Editor

The classic Quill editor with the Snow theme, featuring a full toolbar with all formatting options.

Features:

  • Complete toolbar with all formatting options
  • Formula support with KaTeX
  • Image and video embedding
  • Font, size, and color customization
  • Headers, lists, and alignment
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { QuillyEditor } from 'vue-quilly'
import { Delta, Range } from 'quill/core'
import Quill from 'quill'
import 'quill/dist/quill.snow.css'
import katex from 'katex'
import 'katex/dist/katex.min.css'

// Enable formula support
(window.katex as typeof katex) = katex

const editor = ref<InstanceType<typeof QuillyEditor>>()
const model = ref<string>('<h1>Hello World!</h1><p>Start writing...</p>')
const editorDelta = ref<Delta>()
const editorRange = ref<Range>()

let quill: Quill | undefined

const options = ref({
  theme: 'snow',
  modules: {
    toolbar: [
      [{ font: [] }, { size: [] }],
      ['bold', 'italic', 'underline', 'strike'],
      [{ color: [] }, { background: [] }],
      [{ script: 'super' }, { script: 'sub' }],
      [{ header: '1' }, { header: '2' }, 'blockquote', 'code-block'],
      [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
      ['direction', { align: [] }],
      ['link', 'image', 'video', 'formula'],
      ['clean']
    ]
  },
  placeholder: 'Insert text here ...',
  readOnly: false
})

onMounted(() => {
  quill = editor.value?.initialize(Quill)!
})

const onTextChange = ({ delta }: { delta: Delta }) => (editorDelta.value = delta)
const onSelectionChange = ({ range }: { range: Range }) => (editorRange.value = range)
</script>

<template>
  <QuillyEditor
    ref="editor"
    v-model="model"
    :options="options"
    @text-change="onTextChange"
    @selection-change="onSelectionChange"
  />
</template>

View Source


Bubble Theme Editor

Lightweight editor with the Bubble theme that shows toolbar on text selection.

Features:

  • Medium-style inline toolbar
  • Appears on text selection
  • Same formatting capabilities as Snow theme
  • Cleaner, more minimalist interface
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { QuillyEditor } from 'vue-quilly'
import Quill from 'quill'
import 'quill/dist/quill.bubble.css'
import katex from 'katex'
import 'katex/dist/katex.min.css'

(window.katex as typeof katex) = katex

const editor = ref<InstanceType<typeof QuillyEditor>>()
const model = ref<string>('<p>Select text to see the bubble toolbar!</p>')

const options = ref({
  theme: 'bubble',
  modules: {
    toolbar: [
      [{ font: [] }, { size: [] }],
      ['bold', 'italic', 'underline', 'strike'],
      [{ color: [] }, { background: [] }],
      ['link', 'image', 'video', 'formula'],
      ['clean']
    ]
  },
  placeholder: 'Insert text here ...',
  readOnly: false
})

onMounted(() => {
  editor.value?.initialize(Quill)
})
</script>

<template>
  <QuillyEditor
    ref="editor"
    v-model="model"
    :options="options"
  />
</template>

View Source


Semantic HTML Editor

Editor configured to output clean, semantic HTML without Quill-specific classes.

Features:

  • Clean HTML output (e.g., <h1> instead of <p class="ql-header-1">)
  • Better for SEO and accessibility
  • Easy content portability
  • Ideal for CMS and blog posts
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { QuillyEditor } from 'vue-quilly'
import Quill from 'quill'
import 'quill/dist/quill.snow.css'

const editor = ref<InstanceType<typeof QuillyEditor>>()
const model = ref<string>('<h1>Semantic HTML</h1><p>Clean output!</p>')

const options = ref({
  theme: 'snow',
  modules: {
    toolbar: [
      ['bold', 'italic', 'underline'],
      [{ header: [1, 2, false] }],
      [{ list: 'ordered' }, { list: 'bullet' }],
      ['link', 'image']
    ]
  },
  placeholder: 'Insert text here ...',
  readOnly: false
})

onMounted(() => {
  editor.value?.initialize(Quill)
})
</script>

<template>
  <QuillyEditor
    ref="editor"
    v-model="model"
    :options="options"
    :is-semantic-html-model="true"
  />
</template>

Output comparison:

::: code-group

<p class="ql-header-1">Heading</p>
<ul>
  <li class="ql-list-item">Item</li>
</ul>
<h1>Heading</h1>
<ul>
  <li>Item</li>
</ul>

:::

View Source


Image Resize Editor

Editor with image resize functionality using the quill-image-resize-module.

Features:

  • Drag to resize images
  • Display size indicator
  • Resize handles on images
  • Image alignment toolbar
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { QuillyEditor } from 'vue-quilly'
import Quill from 'quill'
import 'quill/dist/quill.snow.css'

// Expose Quill to window for the resize module
window.Quill = Quill

const editor = ref<InstanceType<typeof QuillyEditor>>()
const model = ref<string>('<p>Add an image and resize it!</p>')

const options = ref({
  theme: 'snow',
  modules: {
    toolbar: [
      ['bold', 'italic', 'underline'],
      ['image'],
      ['clean']
    ],
    imageResize: {
      modules: ['Resize', 'DisplaySize', 'Toolbar'],
    },
  },
  placeholder: 'Insert text here ...',
  readOnly: false
})

onMounted(async () => {
  window.Quill.imports.parchment.Attributor.Style = 
    window.Quill.imports.parchment.StyleAttributor
  
  // Dynamically import resize module
  await import('quill-image-resize-module')
  
  editor.value?.initialize(window.Quill)
})
</script>

<template>
  <QuillyEditor
    ref="editor"
    v-model="model"
    :options="options"
  />
</template>

Installation:

pnpm add quill-image-resize-module

View Source


Custom Editor (Core Build)

Minimal custom editor using quill/core with only specific blots registered.

Features:

  • Minimal bundle size (uses quill/core)
  • Custom blots (Bold, Italic, Headers)
  • External toolbar controls
  • Perfect for custom implementations
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { QuillyEditor } from 'vue-quilly'
import Quill, { Delta, Range } from 'quill/core'
import { type BlotConstructor } from 'parchment'
import 'quill/dist/quill.core.css'

const editor = ref<InstanceType<typeof QuillyEditor>>()
const model = ref<string>('<h1>Custom Editor</h1><p>Minimal setup!</p>')

let quill: Quill | undefined

// Import base blots
const Inline = Quill.import('blots/inline') as BlotConstructor
const Block = Quill.import('blots/block') as BlotConstructor

// Define custom blots
class BoldBlot extends Inline {}
BoldBlot.blotName = 'bold'
BoldBlot.tagName = 'strong'

class ItalicBlot extends Inline {}
ItalicBlot.blotName = 'italic'
ItalicBlot.tagName = 'em'

class HeaderBlot extends Block {
  static formats(node: Element) {
    return HeaderBlot.tagName.indexOf(node.tagName) + 1
  }
}
HeaderBlot.blotName = 'header'
HeaderBlot.tagName = ['H1', 'H2']

// Register blots
Quill.register(BoldBlot)
Quill.register(ItalicBlot)
Quill.register(HeaderBlot)

const options = {
  placeholder: 'Start your story here...',
  readOnly: false
}

onMounted(() => {
  quill = editor.value!.initialize(Quill)
})
</script>

å<template>
  <div id="toolbar">
    <button @click="quill?.format('bold', true)">Bold</button>
    <button @click="quill?.format('italic', true)">Italic</button>
    <button @click="quill?.format('header', 1)">H1</button>
    <button @click="quill?.format('header', 2)">H2</button>
  </div>
  
  <QuillyEditor
    ref="editor"
    v-model="model"
    :options="options"
  />
</template>

View Source


Live Demo

Try all these examples live: vue-quilly.vercel.app

More Examples