Skip to main content
View as Markdown

Layout Components

Layout components arrange the page. They define the visual skeleton — heroes, centered containers, flex and grid tracks, cards, sidebars, modals — and host other components as children. Positioning is expressed as Tailwind classes in props.className; these components add structure, not styling opinions.

app.yaml
components:
  - type: hero
    content: Ship internal tools from config
    props: { className: 'bg-primary text-white py-24' }
  - type: container
    element: section
    props: { className: 'max-w-4xl mx-auto px-6' }
    children:
      - type: grid
        props: { className: 'grid-cols-3 gap-6' }
        children:
          - { type: card, children: [{ type: text, content: 'Fast' }] }

hero

A full-width banner, typically the first block on a landing page. Renders content as its headline and accepts children for calls to action.

Accepts content, children, props, interactions, responsive, visibility and i18n.

container

A generic block-level wrapper — the workhorse for constraining width, applying padding, and grouping children. It is also the only layout component that accepts a dataSource, which makes it the usual way to bind a whole region to a record.

Property Description
element Rendered HTML element: div (default), section, main, aside, nav, header, footer, article.
children Nested component definitions.
content Inline content rendered when no children are present.
dataSource Table binding exposing $record.* to descendants.

flex

A flexbox container. Direction, gap, alignment and wrapping all come from props.classNameflex flex-col, gap-4, items-center, justify-between. Accepts children, props, responsive and visibility.

grid

A CSS grid container with fixed column tracks, again driven by props.className: grid grid-cols-3, gap-6, auto-rows-fr. Children flow into the cells.

responsive-grid

A grid whose layout is declared through the responsive module instead of breakpoint-prefixed classes. Prefer it when the column count is the thing changing across breakpoints.

app.yaml
- type: responsive-grid
  props: { className: 'gap-6' }
  responsive:
    md: { props: { className: 'grid-cols-2 gap-6' } }
    lg: { props: { className: 'grid-cols-3 gap-8' } }
  children:
    - { type: card }

card

A bordered, padded surface for grouping related content — prestyled with background, border, radius, shadow and padding. A props.className you supply is appended last, so it wins the Tailwind cascade and can tighten the defaults. Accepts children, props, interactions, responsive and visibility.

A vertical navigation panel, usually paired with a container main region to form an app shell. Compose it statically from children, or bind entries to a table through the page's layout.sidebar block.

Accepts children, props, responsive and visibility.

A dialog overlay holding the panel body. Give it an id through props.id, then open it from a trigger's interactions.click.modal. For confirmation-style overlays, use dialog / alert-dialog instead.

app.yaml
- { type: button, content: Edit, interactions: { click: { modal: edit-panel } } }
- type: modal
  props: { id: edit-panel, className: 'max-w-lg' }
  children:
    - { type: text, element: h2, content: 'Edit task' }

split-pane

Two resizable regions separated by a draggable divider. The first two children become the panes.

Property Description
orientation horizontal (side by side, default) or vertical (stacked).
defaultRatio Fraction of the container the first pane starts at, between 0 and 1. Default 0.5.
minSize Smallest the first pane may be dragged to, in pixels.
maxSize Largest the first pane may be dragged to, in pixels.

tab-panel

One panel inside a tabs container. Its content is a structured object, not a string — the trigger text and the panel text are separate fields so the renderer never has to split one string into two.

content property Description
label Required. Text on the tab trigger button.
body Text shown in the panel. Omit when the panel renders children.
app.yaml
- type: tabs
  children:
    - { type: tab-panel, content: { label: Overview, body: 'The summary.' } }
    - type: tab-panel
      content: { label: Activity }
      children:
        - { type: data-table, dataSource: { table: events } }

Last updated August 11, 2026

This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.

Built with Sovrium