New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@prezly/slate-lists

Package Overview
Dependencies
Maintainers
11
Versions
303
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@prezly/slate-lists

The best Slate lists extension out there

0.80.2
Source
npm
Version published
Weekly downloads
18K
2.01%
Maintainers
11
Weekly downloads
 
Created
Source

@prezly/slate-lists

The best Slate lists extension out there.

Demo: https://veu8mp.csb.app/ (source code).

API inspired by https://github.com/GitbookIO/slate-edit-list.

Version License

Table of contents

Demo

Live: https://ocbkit.csb.app/

Source code: https://codesandbox.io/s/prezly-slate-lists-demo-ocbkit?file=/src/MyEditor.tsx

Features

  • Nested lists
  • Customizable list types (ordered, bulleted, dashed - anything goes)
  • Transformations support multiple list items in selection
  • Normalizations recover from invalid structure (helpful when pasting)
  • Merges sibling lists of same type
  • Range.prototype.cloneContents monkey patch to improve edge cases that occur when copying lists

Constraints

  • There are two types of lists: ordered and unordered. You can initialize the plugin to work with any project-level data model via ListsSchema.

  • There is an assumption that there is a default text node type to which the plugin can convert list-related nodes (e.g. during normalization, or unwrapping lists). Normally, this is a paragraph block, but it's up to you.

Schema

  • a list node can only contain list item nodes

  • a list item node can contain either:

    • a list item text node
    • a pair of list item text node and a list node (in that order) (nesting lists)
  • a list node can either:

    • have no parent node
    • have a parent list item node
As TypeScript interfaces...

Sometimes code can be better than words. Here are example TypeScript interfaces that describe the above schema (some schema rules are not expressible in TypeScript, so please treat it just as a quick overview).

import { Node } from 'slate';

interface ListNode {
    children: ListItemNode[];
    type: 'ordered-list' | 'unordered-list'; // depends on your ListsSchema 
}

interface ListItemNode {
    children: [ListItemTextNode] | [ListItemTextNode, ListNode];
    type: 'list-item'; // depends on your ListsSchema
}

interface ListItemTextNode {
    children: Node[]; // by default everything is allowed here
    type: 'list-item-text'; // depends on your ListsSchema
}

Installation

npm

npm install --save @prezly/slate-lists

yarn

yarn add @prezly/slate-lists

User guide

0. Basic Editor

Let's start with a minimal Slate + React example which we will be adding lists support to. Nothing interesting here just yet.

Live example: https://codesandbox.io/s/prezly-slate-lists-user-guide-0-basic-editor-veu8mp?file=/src/MyEditor.tsx

import { useMemo, useState } from 'react';
import { createEditor, BaseElement, Descendant } from 'slate';
import { withHistory } from 'slate-history';
import { Editable, ReactEditor, RenderElementProps, Slate, withReact } from 'slate-react';

declare module 'slate' {
    interface CustomTypes {
        Element: { type: Type } & BaseElement;
    }
}

enum Type {
    PARAGRAPH = 'paragraph',
}

function renderElement({ element, attributes, children }: RenderElementProps) {
    switch (element.type) {
        case Type.PARAGRAPH:
            return <p {...attributes}>{children}</p>;
    }
}

const initialValue: Descendant[] = [{ type: Type.PARAGRAPH, children: [{ text: 'Hello world!' }] }];

export function MyEditor() {
    const [value, setValue] = useState(initialValue);
    const editor = useMemo(() => withHistory(withReact(createEditor() as ReactEditor)), []);

    return (
        <Slate editor={editor} value={value} onChange={setValue}>
            <Editable renderElement={renderElement} />
        </Slate>
    );
}

1. Define Lists Model

First, you're going to want to define the model to power the lists functionality.

You'll need at least three additional node types:

  • List Node
  • List Item Node
  • List Item Text Node

Additionally, you may want to split List Node into two types: ordered list and unordered list. Or alternatively, achieve the split with an additional node property (like listNode: ListType).

In this example, for the sake of simplicity, we'll use two different node types:

  • Ordered List Node
  • Unordered List Node

Live example: https://codesandbox.io/s/prezly-slate-lists-user-guide-1-list-nodes-model-qyepe4?file=/src/MyEditor.tsx

 import { useMemo, useState } from 'react';
 import { createEditor, BaseElement, Descendant } from 'slate';
 import { withHistory } from 'slate-history';
 import { Editable, ReactEditor, RenderElementProps, Slate, withReact } from 'slate-react';

 declare module 'slate' {
     interface CustomTypes {
         Element: { type: Type } & BaseElement;
     }
 }
 
 enum Type {
     PARAGRAPH = 'paragraph',
+    ORDERED_LIST = 'ordered-list',
+    UNORDERED_LIST = 'unordered-list',
+    LIST_ITEM = 'list-item',
+    LIST_ITEM_TEXT = 'list-item-text',
 }
 
 function renderElement({ element, attributes, children }: RenderElementProps) {
     switch (element.type) {
         case Type.PARAGRAPH:
             return <p {...attributes}>{children}</p>;
+        case Type.ORDERED_LIST:
+            return <ol {...attributes}>{children}</ol>;
+        case Type.UNORDERED_LIST:
+            return <ul {...attributes}>{children}</ul>;
+        case Type.LIST_ITEM:
+            return <li {...attributes}>{children}</li>;
+        case Type.LIST_ITEM_TEXT:
+            return <div {...attributes}>{children}</div>;
     }
 }
 
 const initialValue: Descendant[] = [
     { type: Type.PARAGRAPH, children: [{ text: 'Hello world!' }] },
+    {
+        type: Type.ORDERED_LIST,
+        children: [
+            {
+                type: Type.LIST_ITEM,
+                children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'One' }] }],
+            },
+            {
+                type: Type.LIST_ITEM,
+                children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Two' }] }],
+            },
+            {
+                type: Type.LIST_ITEM,
+                children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Three' }] }],
+            },
+        ],
+    },
+    {
+        type: Type.UNORDERED_LIST,
+        children: [
+            {
+                type: Type.LIST_ITEM,
+                children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Red' }] }],
+            },
+            {
+                type: Type.LIST_ITEM,
+                children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Green' }] }],
+            },
+            {
+                type: Type.LIST_ITEM,
+                children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Blue' }] }],
+            },
+        ],
+    },
 ];
 
 export function MyEditor() {
     const [value, setValue] = useState(initialValue);
     const editor = useMemo(() => withHistory(withReact(createEditor() as ReactEditor)), []);

     return (
         <Slate editor={editor} value={value} onChange={setValue}>
             <Editable renderElement={renderElement} />
         </Slate>
     );
 }

2. Define lists plugin schema and connect withLists plugin to your model

withLists is a Slate plugin that enables normalizations which enforce schema constraints and recover from unsupported structures.

Live example: https://codesandbox.io/s/prezly-slate-lists-user-guide-2-add-withlists-plugin-r2xscj?file=/src/MyEditor.tsx

 import { useMemo, useState } from 'react';
 import { createEditor, BaseElement, Descendant, Element, Node } from 'slate';
 import { withHistory } from 'slate-history';
 import { Editable, ReactEditor, RenderElementProps, Slate, withReact } from 'slate-react';
+import { ListType, withLists } from '@prezly/slate-lists';
 
 declare module 'slate' {
     interface CustomTypes {
         Element: { type: Type } & BaseElement;
     }
 }
 
 enum Type {
     PARAGRAPH = 'paragraph',
     ORDERED_LIST = 'ordered-list',
     UNORDERED_LIST = 'unordered-list',
     LIST_ITEM = 'list-item',
     LIST_ITEM_TEXT = 'list-item-text',
 }
 
+const withListsPlugin = withLists({
+    isConvertibleToListTextNode(node: Node) {
+        return Element.isElementType(node, Type.PARAGRAPH);
+    },
+    isDefaultTextNode(node: Node) {
+        return Element.isElementType(node, Type.PARAGRAPH);
+    },
+    isListNode(node: Node, type?: ListType) {
+        if (type) {
+            return Element.isElementType(node, type);
+        }
+        return (
+            Element.isElementType(node, Type.ORDERED_LIST) ||
+            Element.isElementType(node, Type.UNORDERED_LIST)
+        );
+    },
+    isListItemNode(node: Node) {
+        return Element.isElementType(node, Type.LIST_ITEM);
+    },
+    isListItemTextNode(node: Node) {
+        return Element.isElementType(node, Type.LIST_ITEM_TEXT);
+    },
+    createDefaultTextNode(props = {}) {
+        return { children: [{ text: '' }], ...props, type: Type.PARAGRAPH };
+    },
+    createListNode(type: ListType = ListType.UNORDERED, props = {}) {
+        const nodeType = type === ListType.ORDERED ? Type.ORDERED_LIST : Type.UNORDERED_LIST;
+        return { children: [{ text: '' }], ...props, type: nodeType };
+    },
+    createListItemNode(props = {}) {
+        return { children: [{ text: '' }], ...props, type: Type.LIST_ITEM };
+    },
+    createListItemTextNode(props = {}) {
+        return { children: [{ text: '' }], ...props, type: Type.LIST_ITEM_TEXT };
+    },
+});
 
 function renderElement({ element, attributes, children }: RenderElementProps) {
     switch (element.type) {
         case Type.PARAGRAPH:
             return <p {...attributes}>{children}</p>;
         case Type.ORDERED_LIST:
             return <ol {...attributes}>{children}</ol>;
         case Type.UNORDERED_LIST:
             return <ul {...attributes}>{children}</ul>;
         case Type.LIST_ITEM:
             return <li {...attributes}>{children}</li>;
         case Type.LIST_ITEM_TEXT:
             return <div {...attributes}>{children}</div>;
     }
 }
 
 const initialValue: Descendant[] = [
     { type: Type.PARAGRAPH, children: [{ text: 'Hello world!' }] },
     {
         type: Type.ORDERED_LIST,
         children: [
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'One' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Two' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Three' }] }],
             },
         ],
     },
     {
         type: Type.UNORDERED_LIST,
         children: [
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Red' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Green' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Blue' }] }],
             },
         ],
     },
 ];
 
 export function MyEditor() {
     const [value, setValue] = useState(initialValue);
+    const editor = useMemo(() => withListsPlugin(withHistory(withReact(createEditor() as ReactEditor))), []);
 
     return (
         <Slate editor={editor} value={value} onChange={setValue}>
             <Editable renderElement={renderElement} />
         </Slate>
     );
 }

3. Use withListsReact plugin

withListsReact is useful on the client-side - it's a Slate plugin - that overrides editor.setFragmentData. It enables Range.prototype.cloneContents monkey patch to improve copying behavior in some edge cases.

Live example: https://codesandbox.io/s/prezly-slate-lists-user-guide-3-add-withlistsreact-plugin-t81im0?file=/src/MyEditor.tsx

 import { useMemo, useState } from 'react';
 import { createEditor, BaseElement, Descendant, Element, Node } from 'slate';
 import { withHistory } from 'slate-history';
 import { Editable, ReactEditor, RenderElementProps, Slate, withReact } from 'slate-react';
+import { ListType, withLists, withListsReact } from '@prezly/slate-lists';
 
 declare module 'slate' {
     interface CustomTypes {
         Element: { type: Type } & BaseElement;
     }
 }
 
 enum Type {
     PARAGRAPH = 'paragraph',
     ORDERED_LIST = 'ordered-list',
     UNORDERED_LIST = 'unordered-list',
     LIST_ITEM = 'list-item',
     LIST_ITEM_TEXT = 'list-item-text',
 }
 
 const withListsPlugin = withLists({
     isConvertibleToListTextNode(node: Node) {
         return Element.isElementType(node, Type.PARAGRAPH);
     },
     isDefaultTextNode(node: Node) {
         return Element.isElementType(node, Type.PARAGRAPH);
     },
     isListNode(node: Node, type: ListType) {
         if (type) {
             return Element.isElementType(node, type);
         }
         return (
             Element.isElementType(node, Type.ORDERED_LIST) ||
             Element.isElementType(node, Type.UNORDERED_LIST)
         );
     },
     isListItemNode(node: Node) {
         return Element.isElementType(node, Type.LIST_ITEM);
     },
     isListItemTextNode(node: Node) {
         return Element.isElementType(node, Type.LIST_ITEM_TEXT);
     },
     createDefaultTextNode(props = {}) {
         return { children: [{ text: '' }], ...props, type: Type.PARAGRAPH };
     },
     createListNode(type: ListType = ListType.UNORDERED, props = {}) {
         const nodeType = type === ListType.ORDERED ? Type.ORDERED_LIST : Type.UNORDERED_LIST;
         return { children: [{ text: '' }], ...props, type: nodeType };
     },
     createListItemNode(props = {}) {
         return { children: [{ text: '' }], ...props, type: Type.LIST_ITEM };
     },
     createListItemTextNode(props = {}) {
         return { children: [{ text: '' }], ...props, type: Type.LIST_ITEM_TEXT };
     },
 });
 
 function renderElement({ element, attributes, children }: RenderElementProps) {
     switch (element.type) {
         case Type.PARAGRAPH:
             return <p {...attributes}>{children}</p>;
         case Type.ORDERED_LIST:
             return <ol {...attributes}>{children}</ol>;
         case Type.UNORDERED_LIST:
             return <ul {...attributes}>{children}</ul>;
         case Type.LIST_ITEM:
             return <li {...attributes}>{children}</li>;
         case Type.LIST_ITEM_TEXT:
             return <div {...attributes}>{children}</div>;
     }
 }
 
 const initialValue: Descendant[] = [
     { type: Type.PARAGRAPH, children: [{ text: 'Hello world!' }] },
     {
         type: Type.ORDERED_LIST,
         children: [
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'One' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Two' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Three' }] }],
             },
         ],
     },
     {
         type: Type.UNORDERED_LIST,
         children: [
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Red' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Green' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Blue' }] }],
             },
         ],
     },
 ];
 
 export function MyEditor() {
     const [value, setValue] = useState(initialValue);
     const editor = useMemo(
+        () => withListsReact(withListsPlugin(withHistory(withReact(createEditor() as ReactEditor)))),
         [],
     );
 
     return (
         <Slate editor={editor} value={value} onChange={setValue}>
             <Editable renderElement={renderElement} />
         </Slate>
     );
 }

4. Add onKeyDown handler

@prezly/slate-lists comes with a pre-defined onKeyDown handler to implement keyboard interactions for lists. For example, pressing Tab in a list will indent the current list item one level deeper. Pressing Shift+Tab will raise the current list item one level up.

Live example: https://codesandbox.io/s/prezly-slate-lists-user-guide-4-add-onkeydown-handler-5wpqxv?file=/src/MyEditor.tsx

 import { useMemo, useState } from 'react';
 import { createEditor, BaseElement, Descendant, Element, Node } from 'slate';
 import { withHistory } from 'slate-history';
 import { Editable, ReactEditor, RenderElementProps, Slate, withReact } from 'slate-react';
+import { ListType, onKeyDown, withLists, withListsReact } from '@prezly/slate-lists';
 
 declare module 'slate' {
     interface CustomTypes {
         Element: { type: Type } & BaseElement;
     }
 }
 
 enum Type {
     PARAGRAPH = 'paragraph',
     ORDERED_LIST = 'ordered-list',
     UNORDERED_LIST = 'unordered-list',
     LIST_ITEM = 'list-item',
     LIST_ITEM_TEXT = 'list-item-text',
 }
 
 const withListsPlugin = withLists({
     isConvertibleToListTextNode(node: Node) {
         return Element.isElementType(node, Type.PARAGRAPH);
     },
     isDefaultTextNode(node: Node) {
         return Element.isElementType(node, Type.PARAGRAPH);
     },
     isListNode(node: Node, type: ListType) {
         if (type) {
             return Element.isElementType(node, type);
         }
         return (
             Element.isElementType(node, Type.ORDERED_LIST) ||
             Element.isElementType(node, Type.UNORDERED_LIST)
         );
     },
     isListItemNode(node: Node) {
         return Element.isElementType(node, Type.LIST_ITEM);
     },
     isListItemTextNode(node: Node) {
         return Element.isElementType(node, Type.LIST_ITEM_TEXT);
     },
     createDefaultTextNode(props = {}) {
         return { children: [{ text: '' }], ...props, type: Type.PARAGRAPH };
     },
     createListNode(type: ListType = ListType.UNORDERED, props = {}) {
           const nodeType = type === ListType.ORDERED ? Type.ORDERED_LIST : Type.UNORDERED_LIST;
           return { children: [{ text: '' }], ...props, type: nodeType };
     },
     createListItemNode(props = {}) {
         return { children: [{ text: '' }], ...props, type: Type.LIST_ITEM };
     },
     createListItemTextNode(props = {}) {
         return { children: [{ text: '' }], ...props, type: Type.LIST_ITEM_TEXT };
     },
 });
 
 function renderElement({ element, attributes, children }: RenderElementProps) {
     switch (element.type) {
         case Type.PARAGRAPH:
             return <p {...attributes}>{children}</p>;
         case Type.ORDERED_LIST:
             return <ol {...attributes}>{children}</ol>;
         case Type.UNORDERED_LIST:
             return <ul {...attributes}>{children}</ul>;
         case Type.LIST_ITEM:
             return <li {...attributes}>{children}</li>;
         case Type.LIST_ITEM_TEXT:
             return <div {...attributes}>{children}</div>;
         default:
             return <div {...attributes}>{children}</div>;
     }
 }
 
 const initialValue: Descendant[] = [
     { type: Type.PARAGRAPH, children: [{ text: 'Hello world!' }] },
     {
         type: Type.ORDERED_LIST,
         children: [
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'One' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Two' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Three' }] }],
             },
         ],
     },
     {
         type: Type.UNORDERED_LIST,
         children: [
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Red' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Green' }] }],
             },
             {
                 type: Type.LIST_ITEM,
                 children: [{ type: Type.LIST_ITEM_TEXT, children: [{ text: 'Blue' }] }],
             },
         ],
     },
 ];
 
 export function MyEditor() {
     const [value, setValue] = useState(initialValue);
     const editor = useMemo(
         () => withListsReact(withListsPlugin(withHistory(withReact(createEditor() as ReactEditor)))),
         [],
     );
 
     return (
         <Slate editor={editor} value={value} onChange={setValue}>
             <Editable
+                onKeyDown={(event) => onKeyDown(editor, event)}
                 renderElement={renderElement}
             />
         </Slate>
     );
 }

Good to go

Now you can use the API exposed on the ListsEditor functions.

Be sure to check the complete usage example.

API

There are JSDocs for all core functionality.

Only core API is documented although all utility functions are exposed. Should you ever need anything beyond the core API, please have a look at src/index.ts to see what's available.

ListsSchema

Lists schema wires the Lists plugin to your project-level defined Slate model. It is designed with 100% customization in mind, not depending on any specific node types, or non-core interfaces.

NameDescription
isConvertibleToListTextNodeCheck if a node can be converted to a list item text node.
isDefaultTextNodeCheck if a node is a plain default text node, that list item text node will become when it is unwrapped or normalized.
isListNodeCheck if a node is representing a list.
isListItemNodeCheck if a node is representing a list item.
isListItemTextNodeCheck if a node is representing a list item text.
createDefaultTextNodeCreate a plain default text node. List item text nodes become these when unwrapped or normalized.
createListNodeCreate a new list node of the given type.
createListItemNodeCreate a new list item node.
createListItemTextNodeCreate a new list item text node.

ListsEditor

ListsEditor is an instance of Slate Editor, extends with ListsSchema methods:

type ListsEditor = Editor & ListsSchema;

withLists

/**
 * Enables normalizations that enforce schema constraints and recover from unsupported cases.
 */
withLists(schema: ListsSchema) => (<T extends Editor>(editor: T) => T & ListsEditor)

withListsReact

/**
 * Enables Range.prototype.cloneContents monkey patch to improve pasting behavior
 * in few edge cases.
 */
withListsReact<T extends ReactEditor & ListsEditor>(editor: T): T

ListsEditor

ListsEditor is a namespace export with all list-related editor utility functions. Most of them require an instance of ListsEditor as the first argument.

Here are the functions methods:

/**
 * Returns true when editor.deleteBackward() is safe to call (it won't break the structure).
 */
canDeleteBackward(editor: ListsEditor) => boolean

/**
 * Decreases nesting depth of all "list-items" in the current selection.
 * All "list-items" in the root "list" will become "default" nodes.
 */
decreaseDepth(editor: ListsEditor) => void

/**
 * Decreases nesting depth of "list-item" at a given Path.
 */
decreaseListItemDepth(editor: ListsEditor, listItemPath: Path) => void

/**
 * Returns all "list-items" in a given Range.
 * @param at defaults to current selection if not specified
 */
getListItemsInRange(editor: ListsEditor, at: Range | null | undefined) => NodeEntry<Node>[]

/**
 * Returns all "lists" in a given Range.
 * @param at defaults to current selection if not specified
 */
getListsInRange(editor: ListsEditor, at: Range | null | undefined) => NodeEntry<Node>[]

/**
 * Returns the "type" of a given list node.
 */
getListType(node: Node) => string

/**
 * Returns "list" node nested in "list-item" at a given path.
 * Returns null if there is no nested "list".
 */
getNestedList(editor: ListsEditor, listItemPath: Path) => NodeEntry<Element> | null

/**
 * Returns parent "list" node of "list-item" at a given path.
 * Returns null if there is no parent "list".
 */
getParentList(editor: ListsEditor, listItemPath: Path) => NodeEntry<Element> | null

/**
 * Returns parent "list-item" node of "list-item" at a given path.
 * Returns null if there is no parent "list-item".
 */
getParentListItem(editor: ListsEditor, listItemPath: Path) => NodeEntry<Element> | null

/**
 * Increases nesting depth of all "list-items" in the current selection.
 * All nodes matching options.wrappableTypes in the selection will be converted to "list-items" and wrapped in a "list".
 */
increaseDepth(editor: ListsEditor) => void

/**
 * Increases nesting depth of "list-item" at a given Path.
 */
increaseListItemDepth(editor: ListsEditor, listItemPath: Path) => void

/**
 * Returns true when editor has collapsed selection and the cursor is in an empty "list-item".
 */
isCursorInEmptyListItem(editor: ListsEditor) => boolean

/**
 * Returns true when editor has collapsed selection and the cursor is at the beginning of a "list-item".
 */
isCursorAtStartOfListItem(editor: ListsEditor) => boolean

/**
 * Returns true if given "list-item" node contains a non-empty "list-item-text" node.
 */
isListItemContainingText(editor: ListsEditor, node: Node) => boolean

/**
 * Moves all "list-items" from one "list" to the end of another "list".
 */
moveListItemsToAnotherList(editor: ListsEditor, parameters: { at: NodeEntry<Node>; to: NodeEntry<Node>; }) => void

/**
 * Nests (moves) given "list" in a given "list-item".
 */
moveListToListItem(editor: ListsEditor, parameters: { at: NodeEntry<Node>; to: NodeEntry<Node>; }) => void

/**
 * Sets "type" of all "list" nodes in the current selection.
 */
setListType(editor: ListsEditor, listType: string) => void

/**
 * Collapses the current selection (by removing everything in it) and if the cursor
 * ends up in a "list-item" node, it will break that "list-item" into 2 nodes, splitting
 * the text at the cursor location.
 */
splitListItem(editor: ListsEditor) => void

/**
 * Unwraps all "list-items" in the current selection.
 * No list be left in the current selection.
 */
unwrapList(editor: ListsEditor) => void

/**
 * All nodes matching options.wrappableTypes in the current selection
 * will be converted to "list-items" and wrapped in "lists".
 */
wrapInList(editor: ListsEditor, listType: ListType) => void

Brought to you by Prezly.

FAQs

Package last updated on 04 Apr 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts