Arranges children vertically with configurable gap.
Preview
code
1[child1]2[child2]3[child3]Usage
go
1node := models.WidgetNode{2 Type: models.WidgetNodeTypeCol,3 Gap: 2,4 Children: []models.WidgetNode{5 {Type: models.WidgetNodeTypeText, Value: "Item 1"},6 {Type: models.WidgetNodeTypeText, Value: "Item 2"},7 {Type: models.WidgetNodeTypeText, Value: "Item 3"},8 },9}Props
| Name | Type | Description | Default |
|---|---|---|---|
type | "col" | Node type | required |
gap | number | Gap between children (Tailwind spacing scale) | 2 |
children | WidgetNode[] | Child nodes to arrange vertically | - |
Gap Values
Gap uses Tailwind's spacing scale:
| Gap | Pixels | Use Case |
|---|---|---|
0 | 0px | No gap (tight grouping) |
1 | 4px | Related content (title + description) |
2 | 8px | Default item spacing |
3 | 12px | Section spacing |
4 | 16px | Large section spacing |
Examples
Text with Description
go
1{2 Type: models.WidgetNodeTypeCol,3 Gap: 1,4 Children: []models.WidgetNode{5 {Type: models.WidgetNodeTypeText, Value: "Step Title", Variant: "title"},6 {Type: models.WidgetNodeTypeText, Value: "This is a description of what this step does.", Variant: "muted"},7 },8}List of Steps
go
1{2 Type: models.WidgetNodeTypeCol,3 Gap: 2,4 Children: []models.WidgetNode{5 // Step 16 {Type: models.WidgetNodeTypeRow, Gap: 2, Children: []models.WidgetNode{7 {Type: models.WidgetNodeTypeBadge, Label: "✓", Variant: "secondary"},8 {Type: models.WidgetNodeTypeText, Value: "Install dependencies"},9 }},10 // Step 211 {Type: models.WidgetNodeTypeRow, Gap: 2, Children: []models.WidgetNode{12 {Type: models.WidgetNodeTypeBadge, Label: "●", Variant: "default"},13 {Type: models.WidgetNodeTypeText, Value: "Build application"},14 }},15 // Step 316 {Type: models.WidgetNodeTypeRow, Gap: 2, Children: []models.WidgetNode{17 {Type: models.WidgetNodeTypeBadge, Label: "○", Variant: "outline"},18 {Type: models.WidgetNodeTypeText, Value: "Deploy to production"},19 }},20 },21}Form Layout
go
1{2 Type: models.WidgetNodeTypeCol,3 Gap: 3,4 Children: []models.WidgetNode{5 {Type: models.WidgetNodeTypeInput, Name: "name", Placeholder: "Enter name"},6 {Type: models.WidgetNodeTypeInput, Name: "email", Placeholder: "Enter email"},7 {Type: models.WidgetNodeTypeSelect, Name: "role", Placeholder: "Select role", Options: []models.WidgetSelectOption{8 {Label: "Admin", Value: "admin"},9 {Label: "User", Value: "user"},10 }},11 },12}CSS Output
css
1.col {2 display: flex;3 flex-direction: column;4 gap: var(--gap);5}TypeScript
typescript
1const node: WidgetNode = {2 type: "col",3 gap: 2,4 children: [5 { type: "text", value: "Title", variant: "title" },6 { type: "text", value: "Description", variant: "muted" },7 ],8}Best Practices
- Use Gap: 1 for related content - Title + description pairs
- Use Gap: 2 for list items - Standard spacing for lists
- Nest Row inside Col - Create complex layouts by combining
- Top-level wrapper - Widget.Children usually starts with a Col