fluent_editor_comments 1.0.0
fluent_editor_comments: ^1.0.0 copied to clipboard
Comments plugin for FluentEditor — provides a concrete CommentProvider implementation with sidebar UI.
fluent_editor_comments #
Comments and annotations plugin for Fluent Editor.
Provides inline comment anchoring, threaded replies, resolve/unresolve workflow, and a sidebar UI — all through the core editor's plugin API with zero coupling to the editor internals.
Features #
- Text-Anchored Comments: Anchor comments to specific text ranges within paragraphs
- Threaded Replies: Support for reply chains on each comment
- Resolve / Unresolve: Mark comments as resolved and toggle visibility of resolved comments
- Offset Tracking: Automatic offset adjustment when document text is mutated (insertions and deletions)
- Import / Export: Serialize comments to JSON and restore them on document load
- Unified Sidebar: Comments integrate seamlessly into the core editor's unified sidebar alongside suggestions
- Localization: All labels are customizable via
FluentCommentLabels
Installation #
dependencies:
fluent_editor_comments:
path: ../fluent-editor-comments # or git URL
Quick Start #
import 'package:fluent_editor/fluent_editor.dart';
import 'package:fluent_editor_comments/fluent_editor_comments.dart';
// 1. Create the comment provider
final commentProvider = FluentCommentProvider();
// 2. Attach the provider to the document
final document = FluentDocument();
document.commentProvider = commentProvider;
// 3. Register the plugin with the editor
FluentEditor(
document: document,
plugins: [
FluentCommentPlugin(provider: commentProvider),
],
bubbleActions: [
CommentBubbleAction(
document: document,
provider: commentProvider,
),
],
);
Architecture #
┌──────────────────────────────────────────────────┐
│ fluent_editor │
│ │
│ FluentEditorPlugin (abstract) │
│ └─ buildSidebarItems() │
│ └─ onTextMutation() │
│ │
│ CommentProvider (abstract interface) │
│ └─ commentsForNode() │
│ └─ addComment() / deleteComment() │
│ └─ onDocumentMutation() │
└──────────────────────┬───────────────────────────┘
│ implements
┌──────────────────────▼───────────────────────────┐
│ fluent_editor_comments │
│ │
│ FluentCommentPlugin │
│ └─ builds FluentSidebarItem list for sidebar │
│ │
│ FluentCommentProvider │
│ └─ in-memory comment store │
│ └─ offset tracking on mutations │
│ └─ import/export to JSON │
│ │
│ FluentCommentCard (widget) │
│ └─ author avatar, timestamp, reply thread │
│ │
│ CommentBubbleAction │
│ └─ "Add Comment" action on text selection │
└──────────────────────────────────────────────────┘
Data Model #
Comment #
| Field | Type | Description |
|---|---|---|
id |
String |
Unique identifier (nanoid) |
nodeId |
String |
ID of the paragraph node the comment is anchored to |
startOffset |
int |
Start character offset within the paragraph |
endOffset |
int |
End character offset within the paragraph |
authorName |
String |
Author display name |
text |
String |
Comment body text |
createdAt |
DateTime |
Creation timestamp |
replies |
List<Reply> |
Threaded replies |
resolved |
bool |
Whether the comment has been resolved |
orphan |
bool |
Whether the anchored text has been deleted |
Reply #
| Field | Type | Description |
|---|---|---|
id |
String |
Unique identifier |
authorName |
String |
Author display name |
text |
String |
Reply body text |
createdAt |
DateTime |
Creation timestamp |
API Reference #
FluentCommentProvider #
The in-memory implementation of the core editor's CommentProvider interface.
final provider = FluentCommentProvider();
// Set the active author name
provider.currentAuthor = 'Alice';
// Add a comment to a text range
provider.addComment(nodeId, startOffset, endOffset, 'Alice', 'Needs revision');
// Add a reply
provider.addReply(commentId, 'Bob', 'Fixed in the latest draft');
// Resolve / unresolve
provider.resolveComment(commentId);
// Delete
provider.deleteComment(commentId);
// Toggle visibility of resolved comments
provider.showResolved = true;
// Export to JSON
final json = provider.exportComments();
// Import from JSON
provider.importComments(json);
// Listen for changes
provider.commentsChanged.listen((_) {
// rebuild UI
});
FluentCommentPlugin #
Implements FluentEditorPlugin. Registered via FluentEditor(plugins: [...]).
FluentCommentPlugin(
provider: commentProvider,
labels: FluentCommentLabels(
addCommentLabel: 'Add comment',
resolveButton: 'Resolve',
deleteButton: 'Delete',
),
);
CommentBubbleAction #
Adds an "Add Comment" action to the bubble toolbar that appears on text selection:
CommentBubbleAction(
document: document,
provider: commentProvider,
);
Localization #
All labels are customizable via FluentCommentLabels. Default values are in English. Labels can also be inherited from FluentEditorLabels on the core document:
// Option 1: Pass labels directly
FluentCommentPlugin(
provider: provider,
labels: FluentCommentLabels(
sidebarTitle: 'Comentarios',
replyHint: 'Responder...',
resolveButton: 'Resolver',
),
);
// Option 2: Inherit from core editor labels
// The plugin automatically reads document.labels when no explicit labels are provided.
| Label | Default | Description |
|---|---|---|
sidebarTitle |
'Comments' |
Sidebar header title |
emptyState |
'No comments yet...' |
Shown when no comments exist |
replyHint |
'Reply...' |
Reply text field placeholder |
replyButton |
'Reply' |
Reply submit button |
resolveButton |
'Resolve' |
Resolve action button |
unresolveButton |
'Unresolve' |
Unresolve action button |
deleteButton |
'Delete' |
Delete action button |
resolvedLabel |
'Resolved' |
Badge shown on resolved comments |
addCommentLabel |
'Add comment' |
Context menu / bubble action label |
Testing #
flutter analyze # static analysis
flutter test # unit tests
License #
MIT — see the LICENSE file.