TypeScript types
The package publishes declaration files with its ESM build. Import public types with import type so they do not become runtime imports.
import type {
EditorEmits,
EditorInit,
EditorInstance,
EditorMenuName,
EditorPluginName,
EditorProps,
EditorTemplateItem,
EditorTemplatesConfig,
EditorToolbarGroup,
ImageBlobInfo,
ImageDeleteInfo,
ImagesDeleteHandler,
ImagesUploadHandler,
MentionConfig,
MentionItem,
MentionRemoveEvent,
MentionSearchEvent,
MentionSelectEvent,
MergeTagConfig,
MergeTagItem,
MergeTagRemoveEvent,
MergeTagSelectEvent,
TemplateInsertEvent,
} from '@erag/text-editor-vue';Editor contracts
EditorProps
interface EditorProps {
modelValue?: string;
init?: EditorInit;
disabled?: boolean;
readonly?: boolean;
id?: string;
name?: string;
ariaLabel?: string;
}
const props: EditorProps = {
modelValue: '<p>Hello</p>',
ariaLabel: 'Email body',
};EditorInit is documented option by option in the configuration reference. EditorInstance and EditorEmits are documented in the API reference.
EditorMenuName
type EditorMenuName =
| 'file'
| 'edit'
| 'view'
| 'insert'
| 'merge-tags'
| 'templates'
| 'format'
| 'tools'
| 'table'
| 'help';
const menus: EditorMenuName[] = ['file', 'edit', 'insert', 'help'];EditorPluginName
Plugin names identify supported editor capabilities. An explicit array filters plugin-backed controls; core history, formatting, and list controls are still selected through toolbar and menubar.
const plugins: EditorPluginName[] = [
'history',
'formatting',
'lists',
'link',
'image',
'media',
'table',
'code',
'preview',
'fullscreen',
'find-replace',
'special-character',
'emoji',
'horizontal-rule',
'anchor',
'merge-tags',
'templates',
'date-time',
];EditorToolbarGroup
The array form and string form use the same toolbar renderer.
const toolbar: EditorToolbarGroup[] = [
{ name: 'history', items: ['undo', 'redo'] },
{ name: 'text', items: ['bold', 'italic', 'underline'] },
{ name: 'insert', items: ['link', 'image', 'table'] },
];Valid item names are: undo, redo, blocks, fontfamily, fontsize, bold, italic, underline, strikethrough, superscript, subscript, casechange, forecolor, backcolor, alignleft, aligncenter, alignright, alignjustify, bullist, numlist, outdent, indent, link, image, media, table, hr, removeformat, code, preview, fullscreen, and more.
Mention types
interface MentionItem {
id: string | number;
label: string;
description?: string;
avatar?: string;
value?: string;
}
interface MentionConfig {
enabled?: boolean;
minimumCharacters?: number;
debounce?: number;
limit?: number;
items?:
| MentionItem[]
| ((
query: string,
signal: AbortSignal,
) => MentionItem[] | Promise<MentionItem[]>);
}MentionItem intentionally has no arbitrary metadata field. Keep application-specific data outside the editor item.
const mention: MentionItem = {
id: 7,
label: 'Amit Gupta',
description: 'Senior Software Developer',
value: 'amit@example.com',
};
const searchEvent: MentionSearchEvent = { query: 'am' };
const selectEvent: MentionSelectEvent = { item: mention, query: 'am' };
const removeEvent: MentionRemoveEvent = { item: mention };Merge-tag types
interface MergeTagItem {
value: string;
group?: string;
}
interface MergeTagConfig {
enabled?: boolean;
limit?: number;
items?: MergeTagItem[];
}
const tag: MergeTagItem = {
value: '{{client.name}}',
group: 'Client',
};
const selected: MergeTagSelectEvent = { item: tag, query: 'client' };
const removed: MergeTagRemoveEvent = { item: tag };There is no label field. The normalized wrapped value is both the visible token and the value emitted to the application.
Template types
interface EditorTemplateItem {
id: string | number;
label: string;
content: string;
group?: string;
description?: string;
}
interface EditorTemplatesConfig {
enabled?: boolean;
items?: EditorTemplateItem[];
}
const template: EditorTemplateItem = {
id: 'follow-up',
label: 'Follow-up message',
description: 'A short follow-up for a client.',
group: 'Quick replies',
content: '<p>Hello {{client.name}},</p><p>Just checking in.</p>',
};
const event: TemplateInsertEvent = { item: template };Image types
interface ImageBlobInfo {
id(): string;
name(): string;
filename(): string;
blob(): Blob;
base64(): string;
blobUri(): string;
}
type ImagesUploadHandler = (
blobInfo: ImageBlobInfo,
progress: (percentage: number) => void,
) => Promise<string>;interface ImageDeleteInfo {
src: string;
alt: string;
width: number;
height: number;
}
type ImagesDeleteHandler = (image: ImageDeleteInfo) => void | Promise<void>;
const removeImage: ImagesDeleteHandler = async (image) => {
await fetch('/api/editor-images', {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ src: image.src }),
});
};The delete callback receives rendered dimensions. The editor emits the same ImageDeleteInfo only after removal succeeds.