> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qomicex.top/llms.txt
> Use this file to discover all available pages before exploring further.

# Layout elements

## Layout elements

QWidget layouts are built entirely from nested elements. There are no pixel properties like `Width` / `Height` / `Margin`; size is decided by the dashboard grid and the layout containers.

## Container types

| Element | Purpose | Visual |
| :- | :- | :- |
| `Container` | Card/panel with border, background, radius and padding | Yes |
| `Row` | Horizontal arrangement | No |
| `Column` | Vertical arrangement | No |
| `Grid` | Multi-column grid | No |
| `Tabs` | Tab pages | Tab bar |
| `List` | Array list | Decided by items |
| `If` | Conditional rendering | No |

## Container

```xml theme={null}
<Container Direction="Column" Padding="4" Gap="3"
           Border="True" Background="Card" Radius="Lg"
           Align="Stretch" Justify="Start">
  ...
</Container>
```

| Attribute | Values | Default | Description |
| :- | :- | :- | :- |
| `Direction` | `Row` / `Column` | `Column` | Main axis |
| `Gap` | 0–8 | `0` | Space between children |
| `Padding` | 0–8 | `0` | Inner padding |
| `Align` | `Start` / `Center` / `End` / `Stretch` | — | Cross-axis alignment |
| `Justify` | `Start` / `Center` / `End` / `Between` | — | Main-axis alignment |
| `Border` | `True` / `False` | `True` | Show a border |
| `Background` | `Transparent` / `Card` / `Muted` / `Primary` | `Card` | Background |
| `Radius` | `None` / `Sm` / `Md` / `Lg` / `Full` | `Lg` | Corner radius |

Use `Container` for cards; when you only want arrangement without visuals, use `Row` / `Column`.

## Row / Column

```xml theme={null}
<Row Gap="2" Align="Center" Wrap="True">
  <Button Text="A" />
  <Button Text="B" />
  <Button Text="C" />
</Row>
```

| Attribute | Values | Default |
| :- | :- | :- |
| `Gap` | 0–8 | `0` |
| `Padding` | 0–8 | `0` |
| `Align` | `Start` / `Center` / `End` / `Stretch` | — |
| `Justify` | `Start` / `Center` / `End` / `Between` | — |
| `Wrap` | `True` / `False` | `False` |

## Grid

```xml theme={null}
<Grid Columns="2" Gap="2" Padding="2">
  <Button Text="左上" />
  <Button Text="右上" />
  <Button Grid.Row="1" Grid.Column="0" Text="左下" />
  <Button Grid.Row="1" Grid.Column="1" Text="右下" />
</Grid>
```

| Attribute | Values | Description |
| :- | :- | :- |
| `Columns` | 1–6, required | Column count |
| `Gap` | 0–8 | Row and column spacing |
| `Padding` | 0–8 | Inner padding |
| `Align` / `Justify` | Same as containers | Alignment |

Children support attached properties:

* `Grid.Row`: starts at 0
* `Grid.Column`: starts at 0
* `Grid.RowSpan`: default 1
* `Grid.ColumnSpan`: default 1

Attached properties can be written as attributes or as property elements:

```xml theme={null}
<Button Grid.Row="1" Grid.Column="0" Text="A" />
<Button>
  <Grid.Row>1</Grid.Row>
  <Grid.Column>1</Grid.Column>
  <Button.Text>B</Button.Text>
</Button>
```

When no row or column is given, children fill the grid in flow order.

## Tabs

```xml theme={null}
<Tabs Default="0">
  <TabItem Title="公告">
    <Text Value="公告内容" />
  </TabItem>
  <TabItem Title="快捷入口">
    <Grid Columns="2" Gap="2">
      <Button Text="启动" OnClick="Launch" />
      <Button Text="实例" OnClick="Navigate" To="Instances" />
    </Grid>
  </TabItem>
</Tabs>
```

* `Tabs.Default`: initially selected index, 0-based.
* `TabItem.Title`: tab title, required.
* Selection lives in memory only and is not persisted.
* All `TabItem` elements are parsed on mount, and `Data` is prefetched too, so switching tabs does not flash.

## List

```xml theme={null}
<List Items="{Data.News.Items}" As="Item" Gap="2" EmptyText="暂无内容">
  <ListItem>
    <Text Value="{Item.Title}" />
  </ListItem>
</List>
```

* `Items`: array path, required; either `{Data.Items}` or `Data.Items`.
* `As`: item variable name, defaults to `item` (case-sensitive).
* `ListItem`: exactly one is required, and it may contain only one root element.
* Inside an item you can use `{Item.Xxx}` and `{Index}`.
* At most 200 items are rendered; an empty array shows `EmptyText`.

## If

```xml theme={null}
<If Test="{State.Error}">
  <Text Value="加载失败" Color="Destructive" />
</If>
```

`Test` is a truthiness check: `False` / empty string / `0` / `null` / empty array count as false.

## Divider / Spacer

```xml theme={null}
<Divider />
<Spacer Size="12" />
```

* `Divider`: a 1px separator line.
* `Spacer`: fixed pixel spacing; it sets both width and height, so it works horizontally and vertically.

## Page content

`Container`, `Row`, `Column`, `Grid`, `If`, `Tabs`, `TabItem`, `List`, and `ListItem` can use `Content="{PageName}"` instead of inline children:

```xml theme={null}
<Resources>
  <Resource Type="Page" Name="InfoPage">
    <Text Value="From a Page" />
  </Resource>
</Resources>

<Container Content="{InfoPage}" />
```

`Content` and child elements are mutually exclusive; see [Page system](https://docs.qomicex.top/en/guide/custom-widget/advanced/pages.md).

## Adaptive sizing

A custom widget renders inside a dashboard grid cell whose width and height change when the user resizes it:

* Top-level `Container` / `Row` / `Column` / `Grid` / `Tabs` / `List` stretch to the cell height; `Text`, `Button`, and similar nodes keep their content height.
* The widget scrolls when content exceeds the cell; a top-level `List` or `Tabs` content area scrolls internally first.
* Wrap the whole card in one top-level `Container` or `Column` so its background/border fills the cell; multiple top-level nodes follow content height and may leave empty space below.
* `Justify="Between"` separates top and bottom content; `Row Wrap="True"` reflows when the cell gets narrower.
* `Grid` columns are fixed and do not change with width; use fewer `Columns` or `Row Wrap` for narrow cards.

### Declarative breakpoints

```xml theme={null}
<Text When="Size.Width &lt;= 1" Value="Narrow" />
<Grid When="Size.Width &gt;= 2" Columns="2">...</Grid>
```

`When` supports `Size.Width` / `Size.Height` / `Size.PixelWidth` / `Size.PixelHeight` with `<`, `<=`, `>`, `>=`, `==`, `!=`, joined by `and` / `or`. In XML attributes, write `<` as `&lt;`.

### Script breakpoints

```xml theme={null}
<Triggers>
  <Trigger Event="Resize" Function="OnResize" />
</Triggers>

<Function Name="OnResize">
  <Function.Script><![CDATA[
    await Host.SetProperty("Title", "Visible", Size.Width > 1);
    await Host.SetProperty("InfoGrid", "Columns", Size.Width >= 3 ? 3 : 2);
    return {};
  ]]></Function.Script>
</Function>
```

`Resize` fires after a debounce when size changes; use a `Loaded` function to read the initial `Size`.

## Common layouts

**Two-column split**

```xml theme={null}
<Row Gap="3">
  <Container Padding="3" Direction="Column">左侧</Container>
  <Container Padding="3" Direction="Column">右侧</Container>
</Row>
```

**Two-column cards**

```xml theme={null}
<Grid Columns="2" Gap="2">
  <Container Padding="3"><Text Value="A" /></Container>
  <Container Padding="3"><Text Value="B" /></Container>
</Grid>
```

## Limits and gotchas

* A container's content is its children; do not put bare text directly inside a container.
* `Grid` attached properties only apply to direct children.
* There is no pixel width or height: the widget size is decided by the dashboard grid cell. If you need internal scrolling, handle it in the outer widget.
* Deep nesting and long lists slow down rendering; the per-widget element limit is 1000.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.