This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/document-authoring/editing-content/lists.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Lists

Document Authoring stores list state as a paragraph property. Each paragraph is a bullet item, a numbered item, or not a list item.

Inside a transaction, you can:

Before you start, make sure the Document Authoring library is installed and running in your app. If you haven’t set it up yet, refer to the getting started guide.

The examples omit error handling. Add it before you use this code in production.

Apply list formatting

Use setParagraphList() to turn a contiguous range of paragraphs into a list. The range uses { index, count } over the block-level content. This example creates three paragraphs and formats them as a bullet list:

const currentDoc = editor.currentDocument();
await currentDoc.transaction(async ({ draft }) => {
const content = draft.body().content();
const start = content.blocklevels().length;
content.addParagraph().asTextView().setText('Draft the announcement');
content.addParagraph().asTextView().setText('Prepare the demo');
content.addParagraph().asTextView().setText('Send the follow-up');
content.setParagraphList({ index: start, count: 3 }, { kind: 'bullet' });
return true;
});

Use kind: 'numbered' for a numbered list. Set level to nest items. Level 0 is the top level:

content.setParagraphList({ index: start, count: 3 }, { kind: 'numbered', level: 1 });

Remove list formatting

Pass { kind: 'none' } to clear list formatting while keeping the paragraph text:

content.setParagraphList({ index: start, count: 3 }, { kind: 'none' });

Copy list formatting from another paragraph

Use applyParagraphListFrom() to copy a source paragraph’s list formatting to a target range. Set list: 'continue' to continue the source numbering, or set list: 'startNew' to start a new list with the same format:

await currentDoc.transaction(async ({ draft }) => {
const content = draft.body().content();
const sourceIndex = 0;
content.applyParagraphListFrom(
sourceIndex,
{ index: 1, count: 2 },
{ list: 'startNew' },
);
return true;
});

Read list state

Use list() to check whether a paragraph is a list item:

await currentDoc.transaction(async ({ draft }) => {
for (const blockLevel of draft.body().content().blocklevels()) {
if (blockLevel.type !== 'paragraph') continue;
const list = blockLevel.list();
if (!list) continue; // not a list item
if ('unsupported' in list) continue; // imported or custom format
console.log(`${list.kind} list, level ${list.level}`);
}
return false;
});

The method returns one of these values:

  • null when the paragraph isn’t a list item.
  • { kind, level } for a bullet or numbered item the API can classify.
  • { unsupported: true, level } for imported or custom list formats the API can’t safely classify.

Learn more

Text and formatting
Apply character formatting to list text.

Programmatic editing
Learn how transactions work and how to use paragraph properties and the document model.