fluent_editor 1.1.0 copy "fluent_editor: ^1.1.0" to clipboard
fluent_editor: ^1.1.0 copied to clipboard

A powerful and feature-rich rich word processor for Flutter applications with support for rich text editing, tables, images, lists, and export to DOCX, ODT, and PDF formats.

FluentEditor

Fluent Editor

Flutter Version License Version Live Demo GitHub Sponsors Product Hunt

A powerful and feature-rich word processor for Flutter applications, inspired by nature 🍃.

Features #

  • Rich Text Editing: Bold, italic, underline, strikethrough, superscript, subscript, small caps
  • Paragraph Styles: Headings (H1–H6), normal text, paragraph formatting
  • Lists: Ordered and unordered lists with nested sublists and checkboxes
  • Tables: Create and edit tables with cell spanning (colspan/rowspan)
  • Images: Insert and resize images with inline and block positioning
  • Links: Insert and manage hyperlinks
  • Colors: Text color and highlight color support
  • Alignment: Left, center, right, and justify text alignment
  • Export: Export to DOCX, ODT, PDF, HTML, Markdown, and plain text
  • Import: Import from DOCX, ODT, HTML, and Markdown
  • Undo/Redo: Full undo/redo history with intelligent action grouping
  • Selection: Mouse and keyboard selection support
  • Word Count: Real-time word and character count
  • Clipboard: Cut, copy, and paste with formatting support
  • Plugin System: Extensible architecture for custom functionality

Tested On #

  • Web: Chrome
  • Windows: Windows 11
  • Linux: Ubuntu, Debian, Fedora
  • macOS: macOS 13+
  • iOS: iOS 15+
  • Android: Android 12+

Plugins #

Plugin Description
fluent_editor_comments Comments and annotations plugin — anchor comments to text ranges, reply, resolve, and manage discussion threads.
fluent_editor_review Track Changes / Review plugin — captures additions and deletions as reviewable suggestions with accept/reject workflow.
fluent_editor_character_map Special character grid, math symbols, and emoji picker.

Getting Started #

Add Fluent Editor to your pubspec.yaml:

dependencies:
  fluent_editor:
    git:
      url: https://github.com/exusr/fluent-editor.git

Basic Usage #

import 'package:flutter/material.dart';
import 'package:fluent_editor/fluent_editor.dart';

class MyEditor extends StatefulWidget {
  @override
  State<MyEditor> createState() => _MyEditorState();
}

class _MyEditorState extends State<MyEditor> {
  late final FluentDocument _document;

  @override
  void initState() {
    super.initState();
    _document = FluentDocument();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FluentEditor(
        document: _document,
        toolbarMode: FluentToolbarMode.fixed,
        labels: const FluentEditorLabels(), // English defaults
      ),
    );
  }
}

Usage with Plugins #

Fluent Editor uses a plugin architecture where external libraries register themselves through the FluentEditorPlugin API. The core editor has zero dependencies on any plugin library.

Comments + Review (Track Changes) #

import 'package:fluent_editor/fluent_editor.dart';
import 'package:fluent_editor_comments/fluent_editor_comments.dart';
import 'package:fluent_editor_review/fluent_editor_review.dart';

class EditorWithPlugins extends StatefulWidget {
  @override
  State<EditorWithPlugins> createState() => _EditorWithPluginsState();
}

class _EditorWithPluginsState extends State<EditorWithPlugins> {
  late final FluentDocument _document;
  final _commentProvider = FluentCommentProvider();
  final _suggestionController = FluentSuggestionController();

  @override
  void initState() {
    super.initState();
    _document = FluentDocument();
    _document.commentProvider = _commentProvider;
  }

  @override
  void dispose() {
    _commentProvider.dispose();
    _suggestionController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FluentEditor(
      document: _document,
      plugins: [
        // Comments plugin — adds comment highlights and context menu actions
        FluentCommentPlugin(provider: _commentProvider),
        // Review plugin — adds Editing/Review mode toggle to the toolbar
        FluentSuggestionPlugin(controller: _suggestionController),
      ],
      // Bubble toolbar actions (e.g. "Add comment" on text selection)
      bubbleActions: [
        CommentBubbleAction(
          document: _document,
          provider: _commentProvider,
        ),
      ],
    );
  }
}

Unified Sidebar #

When both plugins are registered, the editor automatically merges comments and suggestions into a single unified sidebar (FluentUnifiedSidebar). Items are displayed in document order and scroll-synced with the text:

FluentEditor(
  document: _document,
  plugins: [
    FluentCommentPlugin(provider: _commentProvider),
    FluentSuggestionPlugin(controller: _suggestionController),
  ],
  // The sidebar is automatically resolved from registered plugins.
);

Localization #

All UI labels are localizable. The core editor uses FluentEditorLabels, and each plugin uses its own labels class that falls back to the core labels:

FluentEditor(
  document: _document,
  labels: FluentEditorLabels(
    file: 'Archivo',
    edit: 'Editar',
    insert: 'Insertar',
    format: 'Formato',
    sidebarTitle: 'Actividades y Revisiones',
    emptySidebarMessage: 'No hay comentarios ni sugerencias.',
  ),
  plugins: [
    FluentCommentPlugin(
      provider: _commentProvider,
      labels: FluentCommentLabels(
        addCommentLabel: 'Añadir comentario',
        resolveButton: 'Resolver',
      ),
    ),
    FluentSuggestionPlugin(
      controller: _suggestionController,
      labels: SuggestionLabels(
        editingMode: 'Edición',
        suggestingMode: 'Revisión',
        additionLabel: 'Adición',
        deletionLabel: 'Eliminación',
      ),
    ),
  ],
);

Creating a Document Programmatically #

final document = FluentDocument();

// Add a heading
final heading = Paragraph()
  ..styleName = 'heading1'
  ..fragments = [Fragment('Annual Report')];
document.content.nodes.add(heading);

// Add a formatted paragraph
final p = Paragraph()
  ..fragments = [
    Fragment('This is '),
    Fragment('bold text')..bold = true,
    Fragment(' and '),
    Fragment('italic text.')..italic = true,
  ];
document.content.nodes.add(p);

// Add a list
final listItem1 = ListItem(bulletType: 'ordered', indexList: [1])
  ..children = [Paragraph()..fragments = [Fragment('First item')]];
final listItem2 = ListItem(bulletType: 'ordered', indexList: [2])
  ..children = [Paragraph()..fragments = [Fragment('Second item')]];
final list = FluentList(listType: 'ordered')
  ..items = [listItem1, listItem2];
document.content.nodes.add(list);

// Add a 2×2 table
final table = FluentTable()
  ..rows = [
    FluentRow()
      ..cells = [
        FluentCell()..fragments = [Fragment('Header 1')],
        FluentCell()..fragments = [Fragment('Header 2')],
      ],
    FluentRow()
      ..cells = [
        FluentCell()..fragments = [Fragment('Data 1')],
        FluentCell()..fragments = [Fragment('Data 2')],
      ],
  ];
document.content.nodes.add(table);

// Add an image
final image = FluentImage(src: 'https://example.com/image.png')
  ..width = 300
  ..height = 200;
document.content.nodes.add(image);

// Add a link inside a paragraph
final link = Link(url: 'https://example.com')
  ..fragments = [Fragment('Click here')];
final linkParagraph = Paragraph()
  ..fragments = [Fragment('Visit '), link, Fragment(' for more info')];
document.content.nodes.add(linkParagraph);

// Add a horizontal rule
document.content.nodes.add(HorizontalRule());

Plugin System #

The plugin API allows external libraries to extend Fluent Editor without introducing compile-time coupling. See DOCUMENTATION.md for the full API reference.

Creating a Custom Plugin #

import 'package:fluent_editor/plugins/plugin_api.dart';

class MyPlugin extends FluentEditorPlugin {
  @override
  String get id => 'com.example.my_plugin';

  @override
  String get version => '1.0.0';

  // Register custom toolbar buttons
  @override
  List<FluentUiContribution> get ui => [
    FluentUiContribution(
      id: 'my_plugin.toolbar_button',
      location: FluentPluginUiLocation.toolbar,
      order: 5,
      builder: (context, document) => IconButton(
        icon: const Icon(Icons.star),
        onPressed: () { /* custom action */ },
      ),
    ),
  ];

  // Intercept text operations (return true = handled)
  @override
  bool onInsertCharacter(String character, FluentDocument document) => false;

  @override
  bool onBackspace(FluentDocument document, {bool ctrl = false, bool lineStart = false}) => false;

  // Contribute sidebar items
  @override
  List<FluentSidebarItem> buildSidebarItems(BuildContext context, FluentDocument document) => [];

  // Lifecycle hooks
  @override
  void attach(FluentPluginContext context) { /* called on registration */ }

  @override
  void detach(FluentPluginContext context) { /* called on disposal */ }
}

Working with Selection #

final cursor = document.cursor;

if (cursor.isCollapsed) {
  print('Cursor at ${cursor.anchorId}:${cursor.anchorOffset}');
} else {
  print('Selection from ${cursor.anchorId}:${cursor.anchorOffset} '
      'to ${cursor.focusId}:${cursor.focusOffset}');
}

// Move the cursor
cursor.moveTo(fragmentId, offset);

// Extend selection
cursor.focusTo(targetFragmentId, targetOffset);

Additional Information #

Documentation #

For detailed technical documentation, see DOCUMENTATION.md.

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

This project is licensed under the MIT License — see the LICENSE file for details.

Issues #

If you find any bugs or have feature requests, please open an issue on GitHub.

0
likes
130
points
78
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A powerful and feature-rich rich word processor for Flutter applications with support for rich text editing, tables, images, lists, and export to DOCX, ODT, and PDF formats.

Repository (GitHub)
View/report issues
Contributing

License

MIT (license)

Dependencies

archive, characters, desktop_drop, file_picker, file_selector, flutter, google_fonts, html, json_annotation, json_serializable, nanoid, path_provider, pdf, shared_preferences, url_launcher, vector_math, xml

More

Packages that depend on fluent_editor