List item
One shared block type covers bulleted, numbered, to-do, and toggle lists — which flavor it is comes down to which props are set. Unlike paragraph/heading, a list item's own text lives in props.titleRunIds, not contentIds — contentIds is reserved for nested child blocks (indentation), which is why a list item is not a leaf block.
Variants
Bulleted / numbered
{ "id": "li1", "type": "listItem", "contentIds": [], "props": { "ordered": false, "titleRunIds": ["r1"] } }ordered: true renders a numbered marker instead of a bullet. Neither checked nor collapsed is set.
To-do
{ "id": "li2", "type": "listItem", "contentIds": [], "props": { "ordered": false, "checked": false, "titleRunIds": ["r2"] } }Setting checked (boolean) turns the marker into a checkbox.
Toggle
{ "id": "li3", "type": "listItem", "contentIds": ["p1"], "props": { "ordered": false, "collapsed": false, "titleRunIds": ["r3"] } }Setting collapsed (boolean) turns the marker into a disclosure triangle. Nested content lives in contentIds and only renders while collapsed is false. A fresh toggle item is seeded with one empty paragraph child, since otherwise there would be no way to get content into it.
checked and collapsed are mutually exclusive — whichever is set decides which marker renders. Setting both is not a supported combination.Nesting
Tab indents the current item under its previous sibling; Shift+Tab un-indents it — Notion-style. Enter on an empty item at the deepest level un-indents once before turning into a paragraph.
Slash commands
- Bulleted list — keywords: list, bullet, ul
- Numbered list — keywords: list, number, ordered, ol
- To-do list — keywords: todo, checkbox, task, checklist
- Toggle list — keywords: toggle, collapse, expand, dropdown, accordion
Markdown shortcuts also work: "- "/"* " for bulleted, "1. " for numbered, "[] " for to-do. Toggle lists are slash-command only — there's no markdown shortcut for them.
role="list" ancestor wrapping sibling list items — each is an independent block, not grouped in the DOM. Adding role="listitem" without that ancestor would be worse than no role at all, so it's deliberately left out pending a bigger structural change.Styling
.be-list-item on the item, .be-list-item-row for the marker+title row, and .be-list-item-children for the nested indent block.
Using it in your editor
useEditor() registers every built-in block by default, list item included. To register only the blocks you use instead:
import { useEditor, NoteloomEditor, registerBlocks, paragraphBlockType, listItemBlockType } from 'noteloom';
function Editor() {
const editor = useEditor({
registerBlocks: (registry) => registerBlocks(registry, { paragraph: paragraphBlockType, listItem: listItemBlockType }),
});
return <NoteloomEditor editor={editor} />;
}See Picking only the blocks you want for combining this with other types.