Content nodes
List
Ordered, unordered, and custom-marker lists with nesting.
List(
ListItem(Text("Automatic page breaking").size(12)),
ListItem(Text("Repeating headers & footers").size(12)),
).listStyle("disc").markerGap(10).gap(8)Built-in markers
List(...).listStyle("disc") // •
List(...).listStyle("circle") // ○
List(...).listStyle("square") // ▪
List(...).listStyle("decimal") // 1. 2. 3.
List(...).listStyle("dash") // –
List(...).listStyle("none")Numbered lists
List(
ListItem(Text("npm install sone").size(12)),
ListItem(Text("Compose your node tree").size(12)),
ListItem(Text("sone(root).pdf()").size(12)),
).listStyle("decimal").startIndex(1).gap(8)Custom Span markers
Pass a Span for full typographic control:
List(
ListItem(Text("Tab stops").size(12)),
ListItem(Text("Text orientation").size(12)),
).listStyle(Span("→").color("black").weight("bold")).markerGap(10).gap(8)Dynamic markers
A function (index: number) => Span gives per-item control:
const labels = ["①", "②", "③"];
List(
ListItem(Text("Install dependencies").size(12)),
ListItem(Text("Configure the environment").size(12)),
ListItem(Text("Run the build").size(12)),
)
.listStyle((index) => Span(labels[index]).color("royalblue").weight("bold"))
.gap(8)The index is 0-based.
Nesting
ListItem accepts any SoneNode children, so nested lists are just nested calls:
List(
ListItem(Text("First item").size(12)),
ListItem(
Text("Nested").size(12).weight("bold"),
List(
ListItem(Text("Child item").size(11)),
).listStyle(Span("·").color("gray")).markerGap(6),
),
).listStyle("disc").gap(8)API
| Method | Description |
|---|---|
listStyle(v) | Built-in keyword, Span, or (i) => Span. |
markerGap(v) | Pixels between marker and content. Default 8. |
startIndex(v) | Starting number for numeric lists. |
ListItem supports all layout methods and accepts arbitrary children.