Appearance
Vizel provides a comment/annotation system that lets you add comments to specific text selections in the editor.
Comments enable:
import { useVizelEditor, useVizelComment, VizelProvider, VizelEditor } from "@vizel/react"; function Editor() { const editor = useVizelEditor({ features: { comment: true }, }); const { comments, addComment, resolveComment, removeComment, setActiveComment } = useVizelComment(() => editor, { key: "my-doc-comments", }); const handleAddComment = () => { const text = prompt("Enter comment:"); if (text) addComment(text, "Author"); }; return ( <VizelProvider editor={editor}> <VizelEditor /> <button onClick={handleAddComment}>Add Comment</button> <ul> {comments.map((c) => ( <li key={c.id} onClick={() => setActiveComment(c.id)}> {c.text} {c.resolved ? "(resolved)" : ""} <button onClick={() => resolveComment(c.id)}>Resolve</button> <button onClick={() => removeComment(c.id)}>Delete</button> </li> ))} </ul> </VizelProvider> ); }
<script setup lang="ts"> import { useVizelEditor, useVizelComment, VizelProvider, VizelEditor } from "@vizel/vue"; const editor = useVizelEditor({ features: { comment: true }, }); const { comments, addComment, resolveComment, removeComment, setActiveComment } = useVizelComment(() => editor.value, { key: "my-doc-comments", }); function handleAddComment() { const text = prompt("Enter comment:"); if (text) addComment(text, "Author"); } </script> <template> <VizelProvider :editor="editor"> <VizelEditor /> <button @click="handleAddComment">Add Comment</button> <ul> <li v-for="c in comments" :key="c.id" @click="setActiveComment(c.id)" > {{ c.text }} {{ c.resolved ? "(resolved)" : "" }} <button @click="resolveComment(c.id)">Resolve</button> <button @click="removeComment(c.id)">Delete</button> </li> </ul> </VizelProvider> </template>
<script lang="ts"> import { createVizelEditor, createVizelComment, VizelProvider, VizelEditor } from "@vizel/svelte"; const editor = createVizelEditor({ features: { comment: true }, }); const comment = createVizelComment(() => editor.current, { key: "my-doc-comments", }); function handleAddComment() { const text = prompt("Enter comment:"); if (text) comment.addComment(text, "Author"); } </script> <VizelProvider editor={editor.current}> <VizelEditor /> <button onclick={handleAddComment}>Add Comment</button> <ul> {#each comment.comments as c} <li onclick={() => comment.setActiveComment(c.id)}> {c.text} {c.resolved ? "(resolved)" : ""} <button onclick={() => comment.resolveComment(c.id)}>Resolve</button> <button onclick={() => comment.removeComment(c.id)}>Delete</button> </li> {/each} </ul> </VizelProvider>
The comment feature is disabled by default. You can enable it via features.comment:
features.comment
const editor = useVizelEditor({ features: { comment: true, // Enable with defaults }, }); // Or with options const editor = useVizelEditor({ features: { comment: { onCommentClick: (commentId) => { console.log("Clicked comment:", commentId); }, }, }, });
interface VizelCommentOptions { /** Enable comments (default: true) */ enabled?: boolean; /** Storage backend (default: 'localStorage') */ storage?: VizelCommentStorage; /** Storage key for localStorage (default: 'vizel-comments') */ key?: string; /** Callback when a comment is added */ onAdd?: (comment: VizelComment) => void; /** Callback when a comment is removed */ onRemove?: (commentId: string) => void; /** Callback when a comment is resolved */ onResolve?: (comment: VizelComment) => void; /** Callback when a comment is reopened */ onReopen?: (comment: VizelComment) => void; /** Callback when an error occurs */ onError?: (error: Error) => void; }
useVizelComment(() => editor, { storage: { save: async (comments) => { await fetch("/api/comments", { method: "PUT", body: JSON.stringify(comments), }); }, load: async () => { const res = await fetch("/api/comments"); return res.json(); }, }, });
interface VizelComment { /** Unique identifier */ id: string; /** Comment text */ text: string; /** Optional author name */ author?: string; /** Unix timestamp (milliseconds) */ createdAt: number; /** Whether the comment is resolved */ resolved: boolean; /** Replies to this comment */ replies: VizelCommentReply[]; }
interface VizelCommentReply { /** Unique identifier */ id: string; /** Reply text */ text: string; /** Optional author name */ author?: string; /** Unix timestamp (milliseconds) */ createdAt: number; }
useVizelComment(getEditor, options)
createVizelComment(getEditor, options)
comments
VizelComment[]
activeCommentId
string | null
isLoading
boolean
error
Error | null
addComment(text, author?)
Promise<VizelComment | null>
removeComment(id)
Promise<void>
resolveComment(id)
Promise<boolean>
reopenComment(id)
replyToComment(id, text, author?)
Promise<VizelCommentReply | null>
setActiveComment(id)
void
loadComments()
Promise<VizelComment[]>
getCommentById(id)
VizelComment | undefined
TIP
In Vue, comments, activeCommentId, isLoading, and error are ComputedRef values — access them with .value in script or directly in templates.
ComputedRef
.value
Comment highlights use these CSS classes:
.vizel-comment-marker
.vizel-comment-marker--active
:root { /* Comment highlight */ --vizel-comment-bg: rgba(255, 212, 100, 0.3); --vizel-comment-border: rgba(255, 180, 50, 0.6); --vizel-comment-hover-bg: rgba(255, 212, 100, 0.5); /* Active comment */ --vizel-comment-active-bg: rgba(255, 180, 50, 0.5); --vizel-comment-active-border: rgba(255, 150, 0, 0.8); --vizel-comment-active-outline: rgba(255, 150, 0, 0.4); }
For advanced use cases, you can use the core handlers directly:
import { createVizelCommentHandlers, type VizelCommentState, } from "@vizel/core"; const handlers = createVizelCommentHandlers( () => editor, { key: "my-comments" }, (state: Partial<VizelCommentState>) => { // Handle state changes } ); await handlers.addComment("Needs review", "Alice"); await handlers.replyToComment(commentId, "Fixed!", "Bob"); await handlers.resolveComment(commentId);
Comments & Annotations
Vizel provides a comment/annotation system that lets you add comments to specific text selections in the editor.
Overview
Comments enable:
Quick Start
React
Vue
Svelte
Enabling the Feature
The comment feature is disabled by default. You can enable it via
features.comment:Comment Options
Custom Storage Backend
Data Model
Comment
Reply
API Reference
Hook / Composable / Rune
useVizelComment(getEditor, options)useVizelComment(getEditor, options)createVizelComment(getEditor, options)Return Values
commentsVizelComment[]activeCommentIdstring | nullisLoadingbooleanerrorError | nulladdComment(text, author?)Promise<VizelComment | null>removeComment(id)Promise<void>resolveComment(id)Promise<boolean>reopenComment(id)Promise<boolean>replyToComment(id, text, author?)Promise<VizelCommentReply | null>setActiveComment(id)voidloadComments()Promise<VizelComment[]>getCommentById(id)VizelComment | undefinedTIP
In Vue,
comments,activeCommentId,isLoading, anderrorareComputedRefvalues — access them with.valuein script or directly in templates.Styling
Comment highlights use these CSS classes:
.vizel-comment-marker.vizel-comment-marker--activeCSS Custom Properties
Core Handlers
For advanced use cases, you can use the core handlers directly: