---
title: "Compose interfaces"
url: https://developers.dagio.ai/composition/
---

# Compose interfaces

   
                           
                                                                               
                   
                
          
   

## Start with the Model

A Surface interface organizes your app’s information and operations. The Model defines Fields, record profiles, Queries and Actions; composition selects the components that present them and arranges the page. Studio and AI use the same Surface catalog.

For the Clients app, start with the record: recognizable identity, information the team reads and edits, then commands and links that support the work. Occasional adjustments remain accessible in record settings.

## Choose components

| Surface component                          | Options / expected values                                                    | Description                                                                        |
| ------------------------------------------ | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `Page`, `Section`, `Stack`, `Grid`, `Card` | Titles, spacing and columns as defined by each component                     | Organize the page and group information                                            |
| `RecordLayout`                             | Required `asideWidth`: `standard` or `compact`; exactly two `Stack` children | Arranges main record content followed by its relation panel without adding a frame |
| `RecordIdentity`                           | `recordProfileKey`: key of a declared record profile                         | Presents the current record’s identity                                             |
| `RecordField`                              | `recordProfileKey` and `fieldPath`, such as `fields/notes`                   | Displays a Field placed on the Surface with its appropriate control                |
| `RecordSettings`                           | `recordProfileKey`                                                           | Opens Fields placed in settings                                                    |
| `RecordRelations`                          | `recordProfileKey` and `groupKey`: declared relation group                   | Presents objects linked to the record                                              |
| `QueryTable`                               | `binding`: reference to a declared collection or section                     | Presents a data view with its columns and Query                                    |
| `ModelAction`                              | `actionKey`, `label` and a `press` event referencing the same Action         | Offers a command defined in the Model                                              |
| `Tabs`, `TabPanel`                         | Group, ordered keys and labels, initial tab and matching panel               | Organize the record without closing its native components                          |
| `ActionGroup`                              | Optional primary Action, secondary Actions, menu and exact events            | Establishes command hierarchy without changing permissions or confirmations        |
| `HomeHeader`, `HomeLaunchers`              | Model Home declarations                                                      | Present its title, introduction, primary navigation and launch Actions             |
| `HomeLayout`                               | Child Home blocks                                                            | Arranges `main` and `aside` placements, stacked on smaller screens                 |
| `HomeSection`                              | `sectionKey` and one matching Query child                                    | Presents a bounded preview and its route to the complete collection                |
| `HomeActivity`                             | `blockKey` of a declared activity block                                      | Presents authorized events from the application journal                            |

The [Surface component reference](https://developers.dagio.ai/surface-components/) details every property, variant and event. Use keys from your Model: a visible section title does not replace a Field, Query or Action reference.

## Example: the Client record

The `client` profile presents North Studio. Arrange its record in Studio as follows:

1. Place `RecordIdentity` at the top of the record with `recordProfileKey` set to `client`.
2. Add a “Client follow-up” section containing a `RecordField` for `fields/notes` and another for `fields/status`. The first presents editable text beneath its heading; the second uses choices defined by the Field.
3. Add `RecordSettings` for information placed in the `client` profile’s settings.
4. Add quote relations from the group declared in the Model. The panel displays a few links and provides access to the complete list.
5. Place a “Prepare a quote” command referencing the corresponding Model Action.

Fields must be declared and placed in the profile before use. To add a list of quotes with columns and filters, define its Query and view first, then insert `QueryTable` with the corresponding binding. The [Fields](https://developers.dagio.ai/fields/), [tables](https://developers.dagio.ai/tables/) and [Actions](https://developers.dagio.ai/actions/) guides explain those steps.

## Arrange page identity and actions

`Header` in catalog family `0.5.15` arranges exactly two explicitly declared `Stack` children: page identity first, then actions. Keep `RecordIdentity`, or the declared heading and introduction, in the first region. Place `ActionGroup` in the second, or keep that Stack empty when the page offers no command. Both regions remain declared.

Header requires no properties, exposes no events and adds no Card or enclosing frame. Its regions adapt on smaller screens. Commands retain their own declared Actions, permissions, preparation and confirmation; displaying the header never executes them. Check the exact compatible family in the [component reference](https://developers.dagio.ai/surface-components/); a newer family does not upgrade an existing Model.

## Arrange main content and related information

Place `RecordLayout` beneath the record’s identity and commands. Declare exactly two direct `Stack` children: the main region first, then the supporting region. Their element keys remain your own; “main” and “aside” describe positions, not named slots.

Put Notes, editable Fields and the native content editor in the first Stack. Place declared quote relation groups, Tags, metrics or record settings in the second where useful. These components retain their original bindings and permissions. The layout does not infer where a relation belongs or create another editor, Form or save operation.

Choose the required `asideWidth` preset: `standard` provides a 230 px panel; `compact` provides 220 px. The gap is 21 px. Below 850 px, the supporting region follows the main content in one column. `RecordLayout` adds no border or Card; add a Card only for an intentional visual grouping, not around every region.

The [component reference](https://developers.dagio.ai/surface-components/#recordlayout) identifies the exact compatible catalog family. A Model retains the family of its selected Revision; adding a component from another family requires an explicit validated Model evolution. Surface tools handle catalog identities and compatibility. A software package version is not a component capability, and opening a record does not upgrade its Model.

## Compose the Workspace Home

For the Clients app, Home brings together team commands, work to resume and recent changes. Declare these elements in the Model first, then compose their presentation:

1. Place `HomeHeader` to display the Workspace title, introduction and primary Home destination. `HomeLaunchers` presents launch Actions with their declared labels and icons; displaying Home never starts an Action.
2. Add `HomeLayout`, then a `HomeSection` for each section to display. Its `sectionKey` references the declared section; its single Query child uses that same section and view. The Home block determines the `main` or `aside` placement.
3. Set the `maximumVisible` limit and `viewAll` destination in the block. The preview limits displayed items, not Query results. “View all” opens the collection with the same Query and view; search, filters and pagination apply to the complete list there.
4. Add `HomeActivity` with the activity block’s `blockKey`. It presents journal events rather than inferring activity from record modification dates. Deleted or inaccessible content does not acquire an invented title or opening link.

Work-resume sections present progress, blockers and next steps from Surface work facts. The number of visible cards is not progress, and completing a Task does not by itself validate business criteria. When facts are unavailable or stale, Home reports that state instead of showing zero progress or an empty journal as successfully loaded data.

## Preserve input and permissions

Data updates preserve the current draft. Concurrent changes are presented for resolution rather than silently replacing input. Field controls, content editors and views use the same Surface operations to read and save information.

A component grants no additional permissions. Reads, edits and Actions remain subject to the member’s access. Before publishing an interface change, use Model validation and preview to check references and the complete journey.

## Tabs and contextual Actions

`Tabs` organizes a record into declared tabs such as Description, Relations and Validation. Each
`TabPanel` preserves its content and your input when you switch tabs. The same Surface editor is
not duplicated across panels. Labels, ordering and the initial tab belong to the Model.

`ActionGroup` distinguishes one primary Action, secondary Actions and a menu. These controls use
the same Forms, permissions and confirmations as other entry points. Switching tabs does not
complete a step; selecting a scenario is not evidence that it passed. The Model and interface
select the exact catalogue version describing these components, without silently changing existing
applications.

In composed interfaces, `ModelAction` and `ActionGroup` remove commands that are no longer eligible.
An eligible command remains visible but temporarily disabled while an operation is in progress. A
gesture on an earlier menu choice cannot run a replacement Action or target. For keyboard focus,
prefer a `Page` or the selected `TabPanel` as an explicit return region; neither component is
mandatory. If a focused command disappears, Surface returns focus only to a surviving menu trigger
or a declared region still present in the same context, and only if no newer gesture or focus
change has occurred. It neither switches tabs nor invents a return destination where none is
declared.

<!-- surface-examples:start -->

## Applied examples : Compose a record and its relations

Two declared Stacks hold main content then relations without extra frames. The preset selects the right panel’s width.

### Configuration

Component properties `RecordLayout.props`. [Properties and accepted values](https://developers.dagio.ai/surface-components/#recordlayout).

```json
{
  "asideWidth": "standard"
}
```

### Variation and connection

Component properties `RecordLayout.props`. [Properties and accepted values](https://developers.dagio.ai/surface-components/#recordlayout).

```json
{
  "asideWidth": "compact"
}
```

### UI layout example

The illustrative layout below places this configuration in the Clients/Quotes app. Insert each fragment at the stated location, with Field, Query and Action references matching the Model declarations.

1. Client identity
2. Notes and follow-up
3. Settings
4. Linked quotes

<!-- surface-examples:end -->
