List

Last updated on

An ordered or unordered list whose markers are text, so both outputs draw the same ones.

List prints numbered or bulleted items. The markers are text — 1., a., i., • — written into the tree rather than asked of the renderer, because the default PDF engine draws no list markers of its own. That is what makes the preview and the PDF show the same characters.

Preview

Rendering live preview requires JavaScript.

Installation

npx shadcn@4 add @paradoc/list

Or, with the Paradoc CLI, which writes the namespace into components.json for you:

npx paradoc-cli add list

Installs to components/paradoc/list.tsx and brings along keep-together.

Usage

import { List } from "@/components/paradoc/list";<List  id="recitals"  marker="roman"  items={[{ text: "The provider supplies equipment." }, { text: "The customer procures it." }]}/>
PropTypeDefaultDescription
itemsreadonly ListItem[]—The items, in order.
marker?ListMarker"decimal"How the top level's items are marked.
nestedMarker?ListMarker"lower-alpha"How every level nested under the top one is marked.
idstring—Prefix for each item's pagination id; an item's own id is <id>:<index>. Required rather than defaulted: two lists sharing a prefix would claim the same keep ids, and a duplicated id fails the whole page plan.
className?string—Classes replacing the top level's default column layout; a nested level keeps its own.

Composition

Items are data, not children: items is an array of { text, items? }, and an item's own items are a nested level. text takes anything React can render, so a clause can carry a <span> of emphasis or a piece of text the composition built — but never a Field, Text, Table or any other Keep Together, because the item already is one and a keep inside a keep is measured twice. A value from the artifact goes into an item as the text a composition read for it, not as a nested keep.

<List
  id="clauses"
  items={[
    { text: "The provider performs the services." },
    {
      text: "The customer provides:",
      items: [{ text: "Site access." }, { text: "Power at each position." }],
    },
  ]}
/>

Every item is a Keep Together of its own, keyed <id>:<index>, and a nested item extends its parent's key (clauses:1:0). So a list that crosses a page boundary breaks between items, never inside one, and the page plan can name any item as a break. A level withdraws from a page holding none of its items, the same way a Table does, so a continued page carries no empty indent.

A nested list carries its parent's marker as a prefix: the second sub-item of clause 2 reads 2.b., which is how a numbered agreement refers to itself. A bullet contributes nothing to that chain, because a bullet names nothing.

marker sets the top level's style and nestedMarker sets every level under it. Markers, item text, and the gap between items all follow the document's typography token.

id is required, not defaulted: it is the prefix every item's keep id is built from, and two lists sharing one would claim the same ids and fail the page plan. className replaces the top level's column layout; a nested level keeps its own indent.

Variants

Unordered

marker="bullet" marks every item with the same character and numbers nothing.

Rendering live preview requires JavaScript.

Nested

An item's own items are a level of their own, marked with nestedMarker and prefixed with the parent's marker.

Rendering live preview requires JavaScript.

Roman

marker="roman" marks the items i., ii., iii., the way a recitals block is numbered.

Rendering live preview requires JavaScript.

On this page