Editor
TkEditor is a WYSIWYG editor component that wraps Tiptap editor.
- React
- Vue
- Angular
Default
The TkEditor component provides a rich text editing experience with a comprehensive toolbar. It supports common text formatting features, headings, lists, alignment options, and more.
- React
- Vue
- Angular
const content = `
<h2 style="text-align: center">Takeoff UI Rich Text Editor</h2>
</br>
<p>
TkEditor is delivers a modern, intutive rich text editing experience built on <a target="_blank" rel="noopener noreferrer" class="tk-editor-link" href="https://tiptap.dev/">@tiptap</a>.
</br>
The component supports all of its features:
</p>
<ul>
<li><p>Text formatting: <strong>bold</strong>, <em>italic</em>, <u>underline</u>, <s>strike-through</s></p></li>
<li><p>Headings (h1-h4)</p></li>
<li><p>Ordered and bullet lists</p></li><li><p>Text align </p></li>
</ul>
`;
<TkEditor value={content} />
const content = ref(`
<h2 style="text-align: center">Takeoff UI Rich Text Editor</h2>
</br>
<p>
TkEditor is delivers a modern, intutive rich text editing experience built on <a target="_blank" rel="noopener noreferrer" class="tk-editor-link" href="https://tiptap.dev/">@tiptap</a>.
</br>
The component supports all of its features:
</p>
<ul>
<li><p>Text formatting: <strong>bold</strong>, <em>italic</em>, <u>underline</u>, <s>strike-through</s></p></li>
<li><p>Headings (h1-h4)</p></li>
<li><p>Ordered and bullet lists</p></li><li><p>Text align </p></li>
</ul>
`);
<TkEditor v-model="content" />
Label
Add a label and hint - supporting text to provide context for your editor. Use the showAsterisk property to indicate required fields.
- React
- Vue
- Angular
const content = `
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
`;
<TkEditor label="Rich Text Editor" value={content} hint="Supporting text" showAsterisk />
const content = ref(`
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
`);
<TkEditor label="Rich Text Editor" :value="content" hint="Supporting text" showAsterisk />
States
The editor supports readonly and disabled states to control user interaction.
- React
- Vue
- Angular
const content = `
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
`;
<TkEditor value={content} readonly showAsterisk />
<TkEditor value={content} disabled />
const content = ref(`
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
`);
<TkEditor v-model="content" readonly showAsterisk />
<TkEditor v-model="content" disabled />
Toolbar Template
Customize the toolbar by providing your own configuration and extensions. This example shows how to add a highlight feature and customize the toolbar layout.
- React
- Vue
- Angular
import Highlight from "@tiptap/extension-highlight";
const content = `
<p><mark>Lorem </mark>ipsum dolor sit amet, consectetur adipisicing elit.</p>
`;
const editorRef = useRef<HTMLTkEditorElement>(null);
<TkEditor
ref={editorRef}
label="Rich Text Editor"
hint="You can format text using the toolbar"
showAsterisk={true}
value={content}
extensions={[
Highlight.configure()
]}
toolbar={[
['h1', 'h2', 'bold', 'italic'],
['align-left', 'align-center', 'align-right'],
[{
action: 'highlight',
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9" color="#717784"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" color="#717784"/></svg>',
label: 'Highlight Text',
behavior: 'toggle',
command: (editor) => editor.chain().focus().toggleHighlight().run()
}]
]}
/>
import Highlight from "@tiptap/extension-highlight";
const content = ref(`
<p><mark>Lorem </mark>ipsum dolor sit amet, consectetur adipisicing elit.</p>
`);
const editorRef = ref();
<TkEditor
ref="editorRef"
label="Rich Text Editor"
hint="You can format text using the toolbar"
showAsterisk
v-model="content"
:extensions={[
Highlight.configure()
]}
toolbar={[
['h1', 'h2', 'bold', 'italic'],
['align-left', 'align-center', 'align-right'],
[{
action: 'highlight',
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9" color="#717784"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" color="#717784"/></svg>',
label: 'Highlight Text',
behavior: 'toggle',
command: (editor) => editor.chain().focus().toggleHighlight().run()
}]
]}
/>
Placeholder
Shows how the placeholder is displayed only when the editor is empty.
CSS Override
Target the placeholder selector to customize its style:
.custom-placeholder .ProseMirror p.is-editor-empty:first-child::before {
color: #6A5ACD;
font-style: italic;
}- React
- Vue
- Angular
const customPlaceholderStyle = `
.custom-placeholder .ProseMirror p.is-editor-empty:first-child::before {
color: #6A5ACD;
font-style: italic;
}`;
<React.Fragment>
<style>{customPlaceholderStyle}</style>
<TkEditor
placeholder="Lorem ipsum dolor sit amet"
/>
<div className="custom-placeholder">
<TkEditor placeholder="Lorem ipsum dolor sit amet" />
</div>
</React.Fragment>
<TkEditor placeholder="Lorem ipsum dolor sit amet" />
<div class="custom-placeholder">
<TkEditor placeholder="Lorem ipsum dolor sit amet" />
</div>
<style>
.custom-placeholder .ProseMirror p.is-editor-empty:first-child::before {
color: #6A5ACD;
font-style: italic;
}
</style>
Media&URL Handling
The editor comes with built-in support for adding URLs and images. The URL tool helps create and manage hyperlinks, while the image tool allows embedding images via URL.
- React
- Vue
- Angular
Custom Height
Control the editor's content area height or other content element styles using the contentStyle property. This demo creates a scrollable editing area while maintaining a fixed container size.
- React
- Vue
- Angular
const content = `
<h3>Scrollable Content</h3>
<p>This editor has a fixed height with scrollable content area. The content will scroll when it exceeds the container height.</p>
</br>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
<p>Cras ut pulvinar arcu. Aliquam vel turpis vulputate, iaculis ipsum vitae, feugiat nisi.</p>
<p>Cras ut pulvinar arcu. Aliquam vel turpis vulputate, iaculis ipsum vitae, feugiat nisi.</p>
<p>Donec gravida molestie eros, eget venenatis nibh mattis et.</p>
<p>Sed bibendum, neque non interdum tincidunt, magna lacus vulputate turpis, ac venenatis eros neque at tellus. Integer nec magna urna.</p>
<p>Sed convallis sapien a laoreet tempor. Proin enim lectus, tincidunt a magna non, gravida imperdiet urna. Maecenas non ultrices lacus.</p>
`;
<TkEditor
contentStyle={{ height: "200px" }}
value={content}
/>
const content = ref(`
<h3>Scrollable Content</h3>
<p>This editor has a fixed height with scrollable content area. The content will scroll when it exceeds the container height.</p>
</br>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
<p>Cras ut pulvinar arcu. Aliquam vel turpis vulputate, iaculis ipsum vitae, feugiat nisi.</p>
<p>Cras ut pulvinar arcu. Aliquam vel turpis vulputate, iaculis ipsum vitae, feugiat nisi.</p>
<p>Donec gravida molestie eros, eget venenatis nibh mattis et.</p>
<p>Sed bibendum, neque non interdum tincidunt, magna lacus vulputate turpis, ac venenatis eros neque at tellus. Integer nec magna urna.</p>
<p>Sed convallis sapien a laoreet tempor. Proin enim lectus, tincidunt a magna non, gravida imperdiet urna. Maecenas non ultrices lacus.</p>
`);
<TkEditor
:contentStyle="{ height: '200px' }"
v-model="content"
/>
Content Methods
The editor provides flexible content retrieval through its getContent() method. Choose between HTML, plain text, or JSON formats based on your needs. This makes it easy to integrate with different data storage and processing requirements.
- React
- Vue
- Angular
API
Props
| Name | Type | Default | Description |
|---|---|---|---|
CSSStyleProperties | null | The style attribute of tabs item element | |
TkEditorCustomButton[] | [] | Custom toolbar buttons for extensions | |
boolean | false | Whether the editor is disabled | |
string | null | This is the error message that will be displayed. | |
AnyExtension[] | [] | Custom extensions | |
boolean | false | Whether to hide the toolbar | |
string | null | Provided a hint or additional information about the input. | |
boolean | false | Indicates whether the editor is in an invalid state | |
string | null | The label for the toggle | |
string | null | The placeholder text when editor is empty | |
boolean | false | Whether the editor is readonly | |
boolean | false | Displays a red asterisk (*) next to the label for visual emphasis. | |
(TkEditorDefaultButton, TkEditorCustomButton)[][] | null | Toolbar configuration | |
string | '' | The value of the editor |
Events
| Name | Description |
|---|---|
| tk-change | Emitted when editor content changes |
| tkBlur | Emitted when editor loses focus |
| tkFocus | Emitted when editor gets focus |
Methods
| Name | Description |
|---|---|
| getContent | Gets the current content of the editor |
| getEditor | Returns the Tiptap Editor instance |
| setContent | Sets the content of the editor |
Interfaces
interface TkEditorCustomButton {
/**
* The action to perform when the button is clicked
*/
action: string;
/**
* The icon to display in the toolbar button
*/
icon: string;
/**
* The label to display in the toolbar button
*/
label: string;
/**
* The behavior of the button
*/
behavior: TkEditorToolbarButtonBehavior;
/**
* The level of the heading to apply when the button is clicked
*/
level?: HeadingLevel;
/**
* The command to run when the button is clicked
*/
command?: (editor: Editor) => boolean | void;
}