Layout Overview
When using deephaven.ui
to build complex workflows with multiple components, it is important to arrange these components to create a user-friendly and intuitive interface. deephaven.ui
offers various layouts that allow you to define the arrangement of components in terms of order, size, and spacing.
In deephaven.ui
, you will have a dashboard
that contains panels
. The panels
contain components
which are arranged by various layouts.
Dashboard
dashboard
is a full page top level container comprised of panels and stacks of panels, which the user can re-arrange. Dashboards cannot nest within other dashboards or panels.panel
is a container that is presented as individual tabs in adashboard
that can be moved to different positions by dragging the tabs. Apanel
contains components and arranges them using layouts. Panels cannot nest within other panels.
The dashboard
component allows you to create a page layout containing a collection of components. The user can move and resize panels within the dashboard.
Dashboard rules
- Dashboards must be a child of the root script and not nested inside a
@ui.component
. Otherwise, the application cannot correctly determine the type of the component. - Dashboards must have one and only one child, typically a row or column.
- Height and width of panels are summed to 100% within a row or column.
Dashboard key components
Four main children make up a dashboard: row, column, stack, and panels.
- Row: A container used to group elements horizontally. Each element is placed to the right of the previous one.
- Column: A container used to group elements vertically. Each element is placed below the previous one.
- Stack: A container used to group elements into a stack of tabs. Each element gets its own tab, with only one element visible at a time.
- Panel: A container used to group and label elements.
from deephaven import ui
dashboard_example = ui.dashboard(
ui.column(
ui.panel("Header", title="Header"),
ui.row(
ui.panel("Left Sidebar", title="Left Sidebar"),
ui.stack(
ui.panel("Main Content", title="Main Content"),
ui.panel("Sub Content", title="Sub Content"),
width=70,
),
ui.panel("Right Sidebar", title="Right Sidebar"),
),
ui.panel("Footer", title="Footer"),
)
)
Panel
The panel
component is a container designed to group and organize elements within a dashboard. It contains a flex layout by default. Panels are presented as individual tabs that can be moved to different positions by dragging the tabs around. By default, the top-level return of a @ui.component
is automatically wrapped in a panel, so you only need to define a panel explicitly if you want to customize it or nest panels in a dashboard. Customizations can include setting a custom tab title, background color or customizing the flex layout.
from deephaven import ui
my_nested_panel = ui.dashboard(
[
ui.panel(ui.heading("A"), ui.text_field(), title="A"),
ui.panel(ui.heading("B"), ui.text_field(), title="B", direction="row"),
]
)
Layouts
The following layouts can be returned by a component and used inside a panel
to layout components:
flex
is a flexbox-based layout container that arranges components in either a row or column.grid
is a CSS grid layout container that arranges components in a two-dimensional structure of rows and columns.view
is a general purpose container that can be used for custom styling purposes.
Default layout
The top-level return of a @ui.component
is automatically wrapped in a panel
with a flex
layout. Returning a single component or a list of components will have this default layout.
from deephaven import ui
@ui.component
def single_component():
return ui.text("hello")
@ui.component
def list_of_components():
return [ui.heading("hello"), ui.text("good bye"), ui.button("button")]
single_example = single_component()
list_example = list_of_components()
Flex
The flex
layout follows the same rules as the CSS flexbox layout. The flex
layout container can specify the following:
- The
direction
prop determines the direction in which the flex items are laid out such as “row” or “column”. - When enabled, the
wrap
prop causes items that overflow to wrap into the next row. Resize your browser window to see the items reflow. - The
justify_content
prop is used to align items along the main axis. When thedirection
is set to “column”, it controls the vertical alignment, and when the direction is set to “row”, it controls the horizontal alignment. - The
align_items
prop aligns items along the cross-axis. When the direction is set to “column”, it controls horizontal alignment, and when it is set to “row”, it controls vertical alignment.
In addition, flex
layouts can be nested to create more complex layouts.
from deephaven import ui
@ui.component
def ui_flex_nesting():
return [
ui.flex(
ui.view(1, background_color="red", height="size-800"),
ui.flex(
ui.view(
2, background_color="green", height="size-800", width="size-800"
),
ui.view(
3, background_color="blue", height="size-800", width="size-800"
),
justify_content="right",
wrap=True,
),
direction="column",
),
]
my_flex_nesting = ui_flex_nesting()
Grid
The grid
component can be used to layout its children in two dimensions with CSS 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 auto_columns
, auto_rows
, and helper functions like repeat
.
Similar to flex
, a grid can justify and align items.
Explicit grid
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", "size-3000", "size-1000"],
height="size-6000",
gap="size-100",
)
explicit_grid_example = explicit_grid()
Implicit grid
from deephaven import ui
colors = []
for i in range(100, 901, 100):
colors.append(f"gray-{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()
View
The view
component is a general purpose container with no specific semantics that can be used for custom styling purposes. It supports Deephaven UI style props to ensure consistency with other components and is analogous to an HTML <div>
.
from deephaven import ui
view = ui.view(
ui.text_field(label="Name"),
border_width="thin",
border_color="accent-400",
background_color="seafoam-500",
border_radius="medium",
padding="size-250",
)
view_overflow = ui.view(
[ui.text_field(label=f"{i}", width="size-3000") for i in range(50)],
border_width="thin",
border_color="accent-400",
background_color="seafoam-500",
border_radius="medium",
padding="size-250",
overflow=True,
)