# Grid

`ui.grid` is a [grid](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/CSS_layout/Grids)-based layout container that can be used to layout its children in two dimensions.

> [!TIP]
> The `ui.grid` component follows the same rules as a browser CSS grid. The [CSS grid layout guide](https://css-tricks.com/snippets/css/complete-guide-grid/) from CSS-Tricks and the [Grid Garden](https://cssgridgarden.com/) game are great resources to learn more about grid.

The `columns` and `rows` props define the layout of the grid. The layout can use the `area` prop to define grid areas for child components to explicitly place components. Alternatively, an implicit layout can be created using `autoColumns`, `autoRows`, and helper functions like `repeat`.

Similar to [`flex`](./flex.md), a grid can justify and align items.

## Examples

### Explicit grid

This example demonstrates how to create a typical application layout featuring a header, sidebar, content area, and footer. The `areas` prop specifies the grid areas, while the `columns` and `rows` props define their sizes. Each child component utilizes the `grid_area` prop to indicate its designated area within the grid.

```python
from deephaven import ui


@ui.component
def explicit_grid():
    return ui.grid(
        ui.view(background_color="celery-600", grid_area="header"),
        ui.view(background_color="blue-600", grid_area="sidebar"),
        ui.view(background_color="purple-600", grid_area="content"),
        ui.view(background_color="magenta-600", grid_area="footer"),
        areas=["header header", "sidebar content", "footer footer"],
        columns=["1fr", "3fr"],
        rows=["size-1000", "auto", "size-1000"],
        height="size-6000",
        gap="size-100",
    )


explicit_grid_example = explicit_grid()
```

![explicit grid](../_assets/grid_explicit.png)

### Implicit grid

This example creates an implicit grid. It uses the `repeat` function to generate five columns of equal width automatically. The `auto_rows` prop sets the height of the rows, and the items are centered horizontally within the container. A gap is also added between the items.

```python
from deephaven import ui

colors = []
for i in range(100, 901, 100):
    colors.append(f"red-{i}")
    colors.append(f"green-{i}")
    colors.append(f"blue-{i}")


@ui.component
def implicit_grid():
    return ui.grid(
        [ui.view(background_color=color) for color in colors],
        columns="repeat(5, 1fr)",
        auto_rows="size-800",
        justify_content="center",
        gap="size-100",
    )


implicit_grid_example = implicit_grid()
```

![implicit grid](../_assets/grid_implicit.png)

## Justification

The `justify_content` prop is used to align items along the inline axis of a `grid`.

Options:

- `stretch` (default): the grid items are stretched to fill the container along the block axis.
- `start`: the grid items are aligned at the start of the block axis.
- `end`: the grid items are aligned at the end of the block axis.
- `center`: the grid items are centered along the block axis.
- `left`: the grid items are packed toward the left edge of the container.
- `right`: the grid items are packed toward the right edge of the container.
- `space-between`: the grid items are evenly distributed with the first item at the start and the last item at the end.
- `space-around`: the grid items are evenly distributed with equal space around them.
- `space-evenly`: the grid items are evenly distributed with equal space between them.
- `baseline`: the grid items are aligned based on their baselines.
- `first baseline`: the grid items are aligned based on the first baseline of the container.
- `last baseline`: the grid items are aligned based on the last baseline of the container.
- `safe center`: the grid items are centered along the block axis, ensuring they remain within the safe area.
- `unsafe center`: the grid items are centered along the block axis, without considering the safe area.

```python
from deephaven import ui

colors = []
for i in range(100, 901, 100):
    colors.append(f"red-{i}")
    colors.append(f"green-{i}")
    colors.append(f"blue-{i}")


@ui.component
def grid_justification():
    justify, set_justify = ui.use_state("stretch")
    return [
        ui.picker(
            ui.item("stretch"),
            ui.item("start"),
            ui.item("end"),
            ui.item("left"),
            ui.item("right"),
            ui.item("center"),
            ui.item("space-between"),
            ui.item("space-around"),
            ui.item("space-evenly"),
            ui.item("baseline"),
            ui.item("first baseline"),
            ui.item("last baseline"),
            ui.item("safe center"),
            ui.item("unsafe center"),
            selected_key=justify,
            on_selection_change=set_justify,
            label="Pick an option (controlled)",
        ),
        ui.grid(
            [
                ui.view(background_color=color, height="25px", width="25px")
                for color in colors
            ],
            columns="repeat(3, 80px)",
            justify_content=justify,
        ),
    ]


grid_justification_example = grid_justification()
```

## Alignment

The `align_items` prop aligns items along the block axis of a `grid`.

Options:

- `stretch` (default): the grid items are stretched to fill the container along the block axis.
- `start`: the grid items are aligned at the start of the block axis.
- `end`: the grid items are aligned at the end of the block axis.
- `center`: the grid items are centered along the block axis.
- `self-start`: the grid items are aligned at the start of their container.
- `self-end`: the grid items are aligned at the end of their container.
- `baseline`: the grid items are aligned based on their baselines.
- `first baseline`: the grid items are aligned based on the first baseline of the container.
- `last baseline`: the grid items are aligned based on the last baseline of the container.
- `safe center`: the grid items are centered along the block axis, ensuring they remain within the safe area.
- `unsafe center`: the grid items are centered along the block axis, without considering the safe area.

```python
from deephaven import ui

colors = []
for i in range(100, 901, 100):
    colors.append(f"red-{i}")
    colors.append(f"green-{i}")
    colors.append(f"blue-{i}")


@ui.component
def grid_align():
    align, set_align = ui.use_state("stretch")
    return [
        ui.picker(
            ui.item("stretch"),
            ui.item("start"),
            ui.item("end"),
            ui.item("center"),
            ui.item("self-start"),
            ui.item("self-end"),
            ui.item("baseline"),
            ui.item("first baseline"),
            ui.item("last baseline"),
            ui.item("safe center"),
            ui.item("unsafe center"),
            selected_key=align,
            on_selection_change=set_align,
            label="Pick an option (controlled)",
        ),
        ui.grid(
            [
                ui.view(background_color=color, height="25px", width="25px")
                for color in colors
            ],
            columns="repeat(3, 80px)",
            rows=["repeat(9, 80px)"],
            align_items=align,
        ),
    ]


grid_align_example = grid_align()
```

## API reference

A layout container using CSS grid. Supports Spectrum dimensions as values to ensure consistent and adaptive sizing and spacing.

**Returns:** `Element` The rendered grid.

<ParamTable param={{"module_name": "deephaven.ui.", "name": "grid", "parameters": [{"name": "*children", "type": "Any", "description": "The content to render within the container."}, {"name": "areas", "type": "list[str] | None", "description": "The named grid areas to use for the grid.", "default": "None"}, {"name": "rows", "type": "str | list[str | float] | None", "description": "The row sizes for the grid.", "default": "None"}, {"name": "columns", "type": "str | list[str | float] | None", "description": "The column sizes for the grid.", "default": "None"}, {"name": "auto_columns", "type": "str | float | None", "description": "The size of auto-generated columns.", "default": "None"}, {"name": "auto_rows", "type": "str | float | None", "description": "The size of auto-generated rows.", "default": "None"}, {"name": "auto_flow", "type": "Literal['row', 'column', 'row dense', 'column dense'] | None", "description": "The flow direction for auto-generated grid items.", "default": "None"}, {"name": "justify_items", "type": "Literal['auto', 'normal', 'start', 'end', 'center', 'left', 'right', 'stretch', 'self-start', 'self-end', 'baseline', 'first baseline', 'last baseline', 'safe center', 'unsafe center', 'legacy right', 'legacy left', 'legacy center'] | None", "description": "The defailt justify_self for all items in the grid.", "default": "None"}, {"name": "justify_content", "type": "Literal['start', 'end', 'center', 'left', 'right', 'space-between', 'space-around', 'space-evenly', 'stretch', 'baseline', 'first baseline', 'last baseline', 'safe center', 'unsafe center'] | None | UndefinedType", "description": "The distribution of space around items along the main axis.", "default": "<deephaven.ui.types.types.UndefinedType object>"}, {"name": "align_content", "type": "Literal['start', 'end', 'center', 'space-between', 'space-around', 'space-evenly', 'stretch', 'baseline', 'first baseline', 'last baseline', 'safe center', 'unsafe center'] | None | UndefinedType", "description": "The distribution of space around items along the cross axis.", "default": "<deephaven.ui.types.types.UndefinedType object>"}, {"name": "align_items", "type": "Literal['start', 'end', 'center', 'stretch', 'self-start', 'self-end', 'baseline', 'first baseline', 'last baseline', 'safe center', 'unsafe center'] | None | UndefinedType", "description": "The alignment of children within their container.", "default": "<deephaven.ui.types.types.UndefinedType object>"}, {"name": "gap", "type": "str | float | None", "description": "The gap between rows and columns.", "default": "'size-100'"}, {"name": "column_gap", "type": "str | float | None", "description": "The gap between columns.", "default": "None"}, {"name": "row_gap", "type": "str | float | None", "description": "The gap between rows.", "default": "None"}, {"name": "flex", "type": "str | float | bool | None", "description": "When used in a flex layout, specifies how the element will grow or shrink to fit the space available.", "default": "'auto'"}, {"name": "flex_grow", "type": "float | None", "description": "When used in a flex layout, specifies how the element will grow to fit the space available.", "default": "None"}, {"name": "flex_shrink", "type": "float | None", "description": "When used in a flex layout, specifies how the element will shrink to fit the space available.", "default": "None"}, {"name": "flex_basis", "type": "str | float | None", "description": "When used in a flex layout, specifies the initial main size of the element.", "default": "None"}, {"name": "align_self", "type": "Literal['auto', 'normal', 'start', 'end', 'center', 'flex-start', 'flex-end', 'self-start', 'self-end', 'stretch'] | None", "description": "Overrides the alignItems property of a flex or grid container.", "default": "None"}, {"name": "justify_self", "type": "Literal['auto', 'normal', 'start', 'end', 'flex-start', 'flex-end', 'self-start', 'self-end', 'center', 'left', 'right', 'stretch'] | None", "description": "Species how the element is justified inside a flex or grid container.", "default": "None"}, {"name": "order", "type": "int | None", "description": "The layout order for the element within a flex or grid container.", "default": "None"}, {"name": "grid_area", "type": "str | None", "description": "When used in a grid layout, specifies the named grid area that the element should be placed in within the grid.", "default": "None"}, {"name": "grid_row", "type": "str | None", "description": "When used in a grid layout, specifies the row the element should be placed in within the grid.", "default": "None"}, {"name": "grid_column", "type": "str | None", "description": "When used in a grid layout, specifies the column the element should be placed in within the grid.", "default": "None"}, {"name": "grid_row_start", "type": "str | None", "description": "When used in a grid layout, specifies the starting row to span within the grid.", "default": "None"}, {"name": "grid_row_end", "type": "str | None", "description": "When used in a grid layout, specifies the ending row to span within the grid.", "default": "None"}, {"name": "grid_column_start", "type": "str | None", "description": "When used in a grid layout, specifies the starting column to span within the grid.", "default": "None"}, {"name": "grid_column_end", "type": "str | None", "description": "When used in a grid layout, specifies the ending column to span within the grid", "default": "None"}, {"name": "margin", "type": "str | float | None", "description": "The margin for all four sides of the element.", "default": "None"}, {"name": "margin_top", "type": "str | float | None", "description": "The margin for the top side of the element.", "default": "None"}, {"name": "margin_bottom", "type": "str | float | None", "description": "The margin for the bottom side of the element.", "default": "None"}, {"name": "margin_start", "type": "str | float | None", "description": "The margin for the logical start side of the element, depending on layout direction.", "default": "None"}, {"name": "margin_end", "type": "str | float | None", "description": "The margin for the logical end side of the element, depending on layout direction.", "default": "None"}, {"name": "margin_x", "type": "str | float | None", "description": "The margin for the left and right sides of the element.", "default": "None"}, {"name": "margin_y", "type": "str | float | None", "description": "The margin for the top and bottom sides of the element.", "default": "None"}, {"name": "width", "type": "str | float | None", "description": "The width of the element.", "default": "None"}, {"name": "min_width", "type": "str | float | None", "description": "The minimum width of the element.", "default": "None"}, {"name": "max_width", "type": "str | float | None", "description": "The maximum width of the element.", "default": "None"}, {"name": "height", "type": "str | float | None", "description": "The height of the element.", "default": "None"}, {"name": "min_height", "type": "str | float | None", "description": "The minimum height of the element.", "default": "None"}, {"name": "max_height", "type": "str | float | None", "description": "The maximum height of the element", "default": "None"}, {"name": "position", "type": "Literal['static', 'relative', 'absolute', 'fixed', 'sticky'] | None", "description": "The position of the element.", "default": "None"}, {"name": "top", "type": "str | float | None", "description": "The distance from the top of the containing element.", "default": "None"}, {"name": "bottom", "type": "str | float | None", "description": "The distance from the bottom of the containing element.", "default": "None"}, {"name": "left", "type": "str | float | None", "description": "The distance from the left of the containing element.", "default": "None"}, {"name": "right", "type": "str | float | None", "description": "The distance from the right of the containing element.", "default": "None"}, {"name": "start", "type": "str | float | None", "description": "The distance from the start of the containing element, depending on layout direction.", "default": "None"}, {"name": "end", "type": "str | float | None", "description": "The distance from the end of the containing element, depending on layout direction.", "default": "None"}, {"name": "z_index", "type": "int | None", "description": "The stack order of the element.", "default": "None"}, {"name": "is_hidden", "type": "bool | None", "description": "Whether the element is hidden.", "default": "None"}, {"name": "id", "type": "str | None", "description": "The unique identifier of the element.", "default": "None"}, {"name": "UNSAFE_class_name", "type": "str | None", "description": "A CSS class to apply to the element.", "default": "None"}, {"name": "UNSAFE_style", "type": "Dict[str, Any] | None", "description": "A CSS style to apply to the element.", "default": "None"}, {"name": "key", "type": "str | None", "description": "A unique identifier used by React to render elements in a list.", "default": "None"}]}} />
