lexical_list 1.7.4 copy "lexical_list: ^1.7.4" to clipboard
lexical_list: ^1.7.4 copied to clipboard

List and list-item nodes for lexical_core, including check lists, wire-compatible with Lexical's @lexical/list. Pure Dart.

example/main.dart

// Run it with:  dart run example/main.dart
//
// Lists, and the two behaviours that make them usable: Enter on an empty item
// leaves the list, and Tab nests. Without the first there is no way out of a
// list except the mouse, and the second Enter — the one everybody presses —
// silently adds another blank bullet.
import 'package:lexical_core/lexical_core.dart';
import 'package:lexical_list/lexical_list.dart';

void show(LexicalEditor editor, String label) {
  print('\n$label');
  editor.read(() {
    void walk(ElementNode node, int depth) {
      for (final child in node.children) {
        final indent = '  ' * (depth + 1);
        if (child is ListNode) {
          print('$indent<${child.listType.wire}>');
          walk(child, depth + 1);
        } else if (child is ListItemNode) {
          final tick = switch (child.checked) {
            null => '•',
            true => '[x]',
            false => '[ ]',
          };
          final own = child.children
              .where((node) => node is! ListNode)
              .map((node) => node.getTextContent())
              .join();
          if (own.isNotEmpty || child.childrenSize == 0) {
            print('$indent$tick $own');
          }
          // Only nested lists are walked: an item's own inline children are
          // its text, and they were just printed.
          for (final nested in child.children.whereType<ListNode>()) {
            print('$indent  <${nested.listType.wire}>');
            walk(nested, depth + 2);
          }
        } else {
          print('$indent¶ ${child.getTextContent()}');
        }
      }
    }

    walk($getRoot(), 0);
  });
}

void main() {
  final editor = LexicalEditor(nodes: listNodes);
  registerRichText(editor);
  registerList(editor);

  editor.update(() {
    final list = $createListNode(ListType.bullet)
      ..append($createListItemNode()..append($createTextNode('one')))
      ..append($createListItemNode()..append($createTextNode('two')));
    $getRoot()
      ..clear()
      ..append(list);
    (list.getLastChild()! as ListItemNode).selectEnd();
  }, discrete: true);
  show(editor, 'a bullet list');

  // Tab nests the item the caret is in.
  editor.dispatchCommand(indentContentCommand, null);
  show(editor, 'after Tab on the second item');

  // Enter opens a new item; Enter again on the empty one un-nests it, and
  // once more leaves the list altogether.
  editor.dispatchCommand(insertParagraphCommand, null);
  editor.dispatchCommand(insertParagraphCommand, null);
  editor.dispatchCommand(insertParagraphCommand, null);
  show(editor, 'after Enter on the empty item, twice');

  // Numbering is derived from position, so it never has to be maintained.
  editor.update(() {
    $getRoot().append(
      $createListNode(ListType.number, 3)
        ..append($createListItemNode()..append($createTextNode('drittens')))
        ..append($createListItemNode()..append($createTextNode('viertens'))),
    );
  }, discrete: true);
  editor.read(() {
    final list = $getRoot().getLastChild()! as ListNode;
    final values = list.children
        .cast<ListItemNode>()
        .map((item) => item.value)
        .toList();
    print('\nordered list starting at ${list.start}, values: $values');
  });

  // A check list is the same node with a different type, and its items carry
  // a tri-state: null means "not a check list item at all".
  editor.update(() {
    $getRoot().append(
      $createListNode(ListType.check)
        ..append($createListItemNode(true)..append($createTextNode('done')))
        ..append($createListItemNode(false)..append($createTextNode('open'))),
    );
  }, discrete: true);
  show(editor, 'a check list');
}
0
likes
160
points
605
downloads

Documentation

API reference

Publisher

verified publisherahmadre.com

Weekly Downloads

List and list-item nodes for lexical_core, including check lists, wire-compatible with Lexical's @lexical/list. Pure Dart.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

lexical_core, meta

More

Packages that depend on lexical_list