> ## Documentation Index
> Fetch the complete documentation index at: https://zero-true.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Layout

This document aims to explain how the layout behavior works for components in Zero-True. Defining a layout is optional but provides a way to explicitly define the position of components defined in a cell. By default, each component is rendered in its own row, taking up the full width available.

## Specifying Rows, Cols and Nested Layouts

Zero-True allows you to create complicated nested layouts. These are the docs for columns, rows, and the layout:

`pydantic model zero_true.Layout`

Layout is an object that contains the list of rows to be rendered.

<Accordion title="Json Schema">
  ```json theme={null}
  {
     "title": "Layout",
     "description": "Layout is an object that contains the list of rows to be rendered",
     "type": "object",
     "properties": {
        "rows": {
           "default": [],
           "description": "List of rows in this layout",
           "items": {
              "$ref": "#/$defs/Row"
           },
           "title": "Rows",
           "type": "array"
        }
     },
     "$defs": {
        "Column": {
           "description": "A Column must be a subcomponent of a Row. It can contain both individual components and rows",
           "properties": {
              "components": {
                 "default": [],
                 "description": "List of component IDs and rows that belong to this column, rendered in order",
                 "items": {
                    "anyOf": [
                       {
                          "type": "string"
                       },
                       {
                          "$ref": "#/$defs/Row"
                       }
                    ]
                 },
                 "title": "Components",
                 "type": "array"
              },
              "width": {
                 "anyOf": [
                    {
                       "type": "integer"
                    },
                    {
                       "type": "boolean"
                    }
                 ],
                 "default": false,
                 "description": "Width of the column. It can be a number 1-12 and by default is automatically calculated",
                 "title": "Width"
              }
           },
           "title": "Column",
           "type": "object"
        },
        "Row": {
           "description": "Rows can contain both individual components and columns. They are the top level components of a layout and can be subcomponents of columns",
           "properties": {
              "components": {
                 "default": [],
                 "description": "List of component IDs and columns that belong to this row, rendered in order",
                 "items": {
                    "anyOf": [
                       {
                          "type": "string"
                       },
                       {
                          "$ref": "#/$defs/Column"
                       }
                    ]
                 },
                 "title": "Components",
                 "type": "array"
              }
           },
           "title": "Row",
           "type": "object"
        }
     }
  }
  ```
</Accordion>

`pydantic model zero_true.Row`

<Accordion title="field rows">
  **field rows:** List\[Row] = \[]
  List of rows in this layout.
</Accordion>

Rows can contain both individual components and columns. They are the top level components of a layout and can be subcomponents of columns.

<Accordion title="JSON Schema">
  ```json theme={null}
  {
     "$defs": {
        "Column": {
           "description": "A Column must be a subcomponent of a Row. It can contain both individual components and rows",
           "properties": {
              "components": {
                 "default": [],
                 "description": "List of component IDs and rows that belong to this column, rendered in order",
                 "items": {
                    "anyOf": [
                       {
                          "type": "string"
                       },
                       {
                          "$ref": "#/$defs/Row"
                       }
                    ]
                 },
                 "title": "Components",
                 "type": "array"
              },
              "width": {
                 "anyOf": [
                    {
                       "type": "integer"
                    },
                    {
                       "type": "boolean"
                    }
                 ],
                 "default": false,
                 "description": "Width of the column. It can be a number 1-12 and by default is automatically calculated",
                 "title": "Width"
              }
           },
           "title": "Column",
           "type": "object"
        },
        "Row": {
           "description": "Rows can contain both individual components and columns. They are the top level components of a layout and can be subcomponents of columns",
           "properties": {
              "components": {
                 "default": [],
                 "description": "List of component IDs and columns that belong to this row, rendered in order",
                 "items": {
                    "anyOf": [
                       {
                          "type": "string"
                       },
                       {
                          "$ref": "#/$defs/Column"
                       }
                    ]
                 },
                 "title": "Components",
                 "type": "array"
              }
           },
           "title": "Row",
           "type": "object"
        }
     },
     "allOf": [
        {
           "$ref": "#/$defs/Row"
        }
     ]
  }
  ```
</Accordion>

<ResponseField name="zero_true.Column" type="Zero True Component">
  <Expandable title="properties">
    <AccordionGroup title="test">
      <Accordion title="field components (columns)">
        **field components:** List\[str | Column] = \[]
        List of component IDs and columns that belong to this row, rendered in order.
      </Accordion>

      <Accordion title="field components (rows)">
        **field components:** List\[str | Row] = \[]
        List of component IDs and rows that belong to this column, rendered in order.
      </Accordion>

      <Accordion title="field width">
        **field width:** int | bool = False
        Width of the column. It can be a number 1-12 and by default is automatically calculated.
      </Accordion>
    </AccordionGroup>
  </Expandable>
</ResponseField>

A Column must be a subcomponent of a Row. It can contain both individual components and rows.

<Accordion title="JSON Schema">
  ```json theme={null}
  {
     "$defs": {
        "Column": {
           "description": "A Column must be a subcomponent of a Row. It can contain both individual components and rows",
           "properties": {
              "components": {
                 "default": [],
                 "description": "List of component IDs and rows that belong to this column, rendered in order",
                 "items": {
                    "anyOf": [
                       {
                          "type": "string"
                       },
                       {
                          "$ref": "#/$defs/Row"
                       }
                    ]
                 },
                 "title": "Components",
                 "type": "array"
              },
              "width": {
                 "anyOf": [
                    {
                       "type": "integer"
                    },
                    {
                       "type": "boolean"
                    }
                 ],
                 "default": false,
                 "description": "Width of the column. It can be a number 1-12 and by default is automatically calculated",
                 "title": "Width"
              }
           },
           "title": "Column",
           "type": "object"
        },
        "Row": {
           "description": "Rows can contain both individual components and columns. They are the top level components of a layout and can be subcomponents of columns",
           "properties": {
              "components": {
                 "default": [],
                 "description": "List of component IDs and columns that belong to this row, rendered in order",
                 "items": {
                    "anyOf": [
                       {
                          "type": "string"
                       },
                       {
                          "$ref": "#/$defs/Column"
                       }
                    ]
                 },
                 "title": "Components",
                 "type": "array"
              }
           },
           "title": "Row",
           "type": "object"
        }
     },
     "allOf": [
        {
           "$ref": "#/$defs/Column"
        }
     ]
  }
  ```
</Accordion>

<Note>Note that any Rows and Columns defined must be placed inside of a Layout or will not be rendered.</Note>

## Mixed Layouts

If some components are placed in a layout and others are not, the layout will accommodate both:

<Steps>
  <Step title="Rendering Order">
    Rows defined in the layout will be rendered in the order they are in the list and their subcomponents and columns will be rendered in the order they are defined in the list.
  </Step>

  <Step title="Multiple Rendering">
    If a row or column is a subcomponent of another row/column or the layout itself, its components will be rendered multiple times wherever it is included.
  </Step>

  <Step title="Component Definition">
    Any components included in a row, column, or layout must be defined in the cell where that row, column, or layout is defined or they will not be rendered.
  </Step>

  <Step title="Full Width Rendering">
    All other components not in a row or column will be rendered in the order they are defined in code and take up the full width available, each in their own row.
  </Step>
</Steps>

## Example

Here is an example with actual code that shows how the layout works:

```python theme={null}
import zero_true as zt

image = zt.Image(id='image', src='https://www.escapemotions.com/images/mainpage/images/blog_posts_bg/landing-page_blog_93303113643.jpg', width=500, height=300)
slider = zt.Slider(id='slider', label='slider')
slider2 = zt.Slider(id='slider2', label='slider2')
slider3 = zt.Slider(id='slider3', label='slider3')
slider4 = zt.Slider(id='slider4', label='slider4')
slider5 = zt.Slider(id='slider5', label='slider5')
button = zt.Button(id='button', text='button')
button2 = zt.Button(id='button2', text='button2')
button3 = zt.Button(id='button3', text='button3')
button4 = zt.Button(id='button4', text='button4')
button5 = zt.Button(id='button5', text='button5')

col = zt.Column([slider.id, button.id])
col2 = zt.Column([slider4.id, button4.id])
row2 = zt.Row([slider3.id, button3.id, col2])

row = zt.Row([image.id, slider2.id, button2.id, col])

zt.Layout([row, row2])
```

And this is the resulting layout:
