@test2flow/tip2flow
v0.8.0
Published
A feature-rich Vue 3 rich text editor component built on [Tiptap](https://tiptap.dev/) and ProseMirror. Ships as UMD + ES module bundles via Vite's library mode.
Downloads
560
Keywords
Readme
Tip2Flow
A feature-rich Vue 3 rich text editor component built on Tiptap and ProseMirror. Ships as UMD + ES module bundles via Vite's library mode.
Installation
npm install @test2flow/tip2flow
# or
yarn add @test2flow/tip2flowPeer Dependencies
Make sure you have these installed in your project:
npm install vue@^3.4 prosemirror-model@^1.7Usage
Basic Example
<script setup>
import { ref } from 'vue'
import { Tip2FlowEditor } from '@test2flow/tip2flow'
import '@test2flow/tip2flow/dist/style.css'
const content = ref('<p>Hello world!</p>')
</script>
<template>
<Tip2FlowEditor v-model="content" />
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| modelValue | String | '' | HTML content (v-model) |
| fullScreenMode | String | undefined | CSS class applied when full-screen mode is active |
| addHiddenInputField | Boolean | false | Renders a hidden <textarea> with the editor content, useful for traditional form submissions |
| name | String | undefined | name attribute for the hidden textarea |
| id | String | undefined | id attribute for the editor |
| dependencies | Object | {} | Configuration object for custom menu layouts, editor props, and extensions |
v-model
The editor supports two-way binding via v-model. The bound value is an HTML string.
<script setup>
import { ref } from 'vue'
import { Tip2FlowEditor } from '@test2flow/tip2flow'
const content = ref('')
</script>
<template>
<Tip2FlowEditor v-model="content" />
<pre>{{ content }}</pre>
</template>Hidden Input for Form Submissions
When used inside a traditional <form>, set addHiddenInputField to include the editor content as a form field:
<form method="POST" action="/save">
<Tip2FlowEditor
v-model="content"
name="description"
:addHiddenInputField="true"
/>
<button type="submit">Save</button>
</form>Custom Menu Configuration
You can customize the toolbar by passing a menuConfig inside the dependencies prop. The config references menu items by name.
<script setup>
import { ref } from 'vue'
import { Tip2FlowEditor } from '@test2flow/tip2flow'
const content = ref('')
const dependencies = {
menuConfig: {
menu: [
[
{ name: 'bold' },
{ name: 'italic' },
{ name: 'underline' },
{ name: 'heading' },
{ name: 'anchorTag' },
],
[
{ name: 'unorderedList' },
{ name: 'orderedList' },
{ name: 'undo' },
{ name: 'redo' },
{ name: 'image' },
],
],
},
}
</script>
<template>
<Tip2FlowEditor v-model="content" :dependencies="dependencies" />
</template>Available Menu Items
Formatting: bold, italic, underline, strikeThrough, textSmall, removeFormat, quote, superScript, subScript
Text Style: fontSize, heading, fontFamily, textColor, backgroundColor
Lists & Structure: unorderedList, orderedList, inlineCode, codeBlock, horizontalRule, pageBreak
Alignment: alignLeft, alignCenter, alignRight, alignJustified
Insert: anchorTag, table, image, video
Editor: undo, redo, showCode, addElementWrapper, removeElementWrapper
Table Bubble Menu: addColumnBefore, addColumnAfter, deleteColumn, addRowBefore, addRowAfter, deleteRow, mergeCells, splitCell, toggleHeaderColumn, toggleHeaderRow, cellAlign
Wrapper Menu: wrapperSize, wrapperPadding, wrapperAlign, wrapperPosition
Disabling Tooltips on Menu Items
You can disable the tooltip for any menu item by setting tooltip: false in its config entry:
<script setup>
import { ref } from 'vue'
import { Tip2FlowEditor } from '@test2flow/tip2flow'
const content = ref('')
const dependencies = {
menuConfig: {
menu: [
[
{ name: 'bold' },
{ name: 'italic', tooltip: false },
{ name: 'underline' },
],
],
},
}
</script>
<template>
<Tip2FlowEditor v-model="content" :dependencies="dependencies" />
</template>Showing the Active Value in Dropdowns
Dropdown menu items like fontFamily and fontSize can display the currently active value (e.g., the selected font name or size) in the dropdown button instead of the default label. Enable this by setting showActiveText: true in the item's config:
<script setup>
import { ref } from 'vue'
import { Tip2FlowEditor } from '@test2flow/tip2flow'
const content = ref('')
const dependencies = {
menuConfig: {
menu: [
[
{ name: 'fontFamily', showActiveText: true },
{ name: 'fontSize', showActiveText: true },
],
],
},
}
</script>
<template>
<Tip2FlowEditor v-model="content" :dependencies="dependencies" />
</template>When showActiveText is true, the dropdown will show the current font or size at the cursor position. When false (the default), it shows the static label (e.g., "Fonts" or "Font Size").
Overriding a Menu Item Command (CMS Image Picker)
Each menu item config is merged with the built-in defaults, so any property you set in the config overrides the default. This lets you replace the default image dialog with your own logic — for example, opening an external CMS image picker:
<script setup>
import { ref } from 'vue'
import { Tip2FlowEditor } from '@test2flow/tip2flow'
const content = ref('')
function openCmsImagePicker(editor) {
// Open your CMS media library in a new window
const picker = window.open('/cms/media-library', 'cms-images', 'width=900,height=600')
// Listen for the selected image URL sent back via postMessage
window.addEventListener('message', (event) => {
if (event.data?.type === 'cms-image-selected') {
editor
.chain()
.focus()
.setImage({ src: event.data.src, alt: event.data.alt })
.run()
}
}, { once: true })
}
const dependencies = {
menuConfig: {
menu: [
[
{ name: 'bold' },
{ name: 'italic' },
{ name: 'underline' },
],
[
{
name: 'image',
command: ({ editor }) => openCmsImagePicker(editor),
},
],
],
},
}
</script>
<template>
<Tip2FlowEditor v-model="content" :dependencies="dependencies" />
</template>The same pattern works for any menu item — override command to run your own logic instead of the built-in behavior.
Custom Editor Props
You can pass Tiptap/ProseMirror editorProps through the dependencies prop:
<script setup>
const dependencies = {
editorProps: {
handleClick(view, pos, event) {
console.log('Clicked at position', pos)
return false
},
},
}
</script>
<template>
<Tip2FlowEditor v-model="content" :dependencies="dependencies" />
</template>Features
- Rich text formatting (bold, italic, underline, strikethrough, superscript, subscript)
- Headings (levels 1-5)
- Font family and font size selection
- Text and background color pickers
- Ordered and unordered lists
- Text alignment (left, center, right, justify)
- Links with target selection
- Images with alt text
- Video embeds
- Tables with resizable columns, merge/split cells, and header toggling
- Code blocks with syntax highlighting (via Lowlight)
- Inline code
- Blockquotes
- Horizontal rules and page breaks
- Element wrappers for layout control (padding, width, alignment)
- HTML source editing (via CodeMirror)
- Undo/redo history
- Word and character count
- Reading time estimate
- Customizable toolbar layout
- Dark mode support
Development
Prerequisites
- Node.js
- Yarn
Setup
git clone <repository-url>
cd tip2flow
yarn installCommands
yarn dev # Start dev server on localhost:3000
yarn build # Production library build (outputs to dist/)
yarn preview # Preview production buildProject Structure
src/
├── index.js # Library export entry point
├── main.js # Demo app entry point
├── App.vue # Demo component
├── components/
│ ├── tip2FlowEditor.vue # Main editor component
│ ├── defaultMenuConfig.js # Default toolbar layout
│ ├── menuItems.js # Menu item registry
│ ├── menu.js # Menu config resolver
│ ├── elementWrapper.js/vue # Style container extension
│ ├── divWrapper.js/vue # Nested div extension
│ ├── pageBreak.js # Page break extension
│ ├── rawHtml.js/vue # Raw HTML block extension
│ ├── backgroundColor.js # Background color mark
│ ├── link.js # Link extension
│ ├── small.js # Small text mark
│ ├── video.js # Video embed extension
│ ├── toolbarButton.vue # Toolbar button component
│ ├── toolbarDropdown.vue # Toolbar dropdown component
│ ├── toolbarColorPicker.vue # Color picker component
│ └── modal.vue # Modal dialog component
└── assets/icons/ # SVG icons (light, micro, plump, regular)License
See LICENSE for details.
