A scrollable stack of repeated row cards (each built from one shared grid template), with optional row selection and a pagination footer.
- Browse many records as custom row cards — each row is a grid layout you design, not fixed columns.
- Build a selectable list that drives a detail panel, form, or chart from
elements.<listId>.selected. - Show compact work queues, catalogs, or pickers where a freeform row layout beats a dense table.
Requires a Data Source view/query name. Set Identifier Name whenever selection or per-row actions must address a specific record. Build the visual layout inside the single row → default_grid template.
List-shaped views with one row per business record and a stable id column.
Rows that benefit from a custom card layout (mixed field types, icons, buttons) rather than a spreadsheet grid.
Foreign-key columns that should display names via References +
props.referencesin the row template.A valid source view/query is required before the list can load rows and before References, Sort, and Filter by can offer field names.
Set dataSource.identifierName to a stable unique column so selection keys and row metadata stay consistent across pages.
Place one default_grid in the list’s row slot and put field/display/button elements inside that grid. Edit the template once; every data row mirrors it.
If source rows contain foreign IDs, define References so row-template expressions can show readable names via props.references.
- A product catalog of cards (image, title, price) with single-row selection opening a detail form.
- An approval inbox of stacked cards showing status, assignee, and a link button per row.
- A modal picker list where the user selects one row and a Confirm button reads
selected.identifier. - A side panel list of related records filtered by a parent form’s identifier via Filter by.
- Do not use List when users need column sorting clicks, a search box, or an advanced filter dialog — use Table.
- Do not leave the
rowslot empty; without adefault_gridtemplate the list has nothing to render. - Do not enable row selection unless another element consumes
selected. - Do not skip Identifier Name when selection or row actions must target a stable primary key.
- Do not point the list at a connector source — List is view/query only; use Table for connectors.
Use instead
- Table — Prefer Table for dense multi-column browsing with search, user filters, column sort clicks, create button, and row action columns.
- Form — Prefer a Form when the page focuses on one record (create/edit/detail) rather than scanning many rows.
- Data Display — Prefer Data Display for a few KPI values, not a browsable set of records.
Pairs well with
- Grid — Required row template: exactly one grid in the list’s row slot defines the layout repeated for every record.
- Text Field — Common cell inside the row grid, bound with expressions such as props.data[“name”].
- Internal Link Button — Per-row navigation (details/edit) placed inside the row template.
- Form — Typical consumer of elements.
.selected for master–detail layouts.
Configure these in the Application Designer property panel. Group headings mirror the editor where possible. Data Source is where the element gets its rows or field binding (a view/query, a connector operation, or a parent form field). References appear only for view-backed sources and map foreign-key ID columns to readable labels from another view.
Backing view/query and the fields used for row identity and workflow state. Most other options depend on a chosen view.
- Database view that supplies rows or form data.Default: none
- Primary-key field used to load a single record (edit/detail).Default: none
- Optional workflow/state column. When set, per-row metadata (permissions/state) is resolved from metadata.rows[stateValue].Default: none
Maps foreign-key columns on the source view to another view so row-template expressions can resolve readable values.
- Map of source foreign-key field → { viewName, identifierName }. Loaded reference rows are exposed to the row template as props.references.Good to know
- Key each entry by the foreign-key column name on the list’s source view.
- The reference loads the related row; the display field is chosen in the row template expression.
Avoid- Do not expect References alone to pick the label column — bind props.references[“airline_id”][“airline_name”] (or similar) in the row grid.
Example{ "airline_id": { "viewName": "v_airline", "identifierName": "airline_id" } }Default: none
Whether rows are selectable, whether the first row is selected after load, and single vs multi select.
- Allows the user to select a single table row.Good to know
- Enable only when another element or action reads the selection.
Default: none - After each load, selects the first row when selection is enabled so a detail panel always has a current record.Good to know
- Only active when canSelectRow is true.
Avoid- Avoid on destructive workflows where an implicit selection may surprise the user.
Default: none - Allows multi-row selection in the table.Good to know
- Only active when canSelectRow is true.
Avoid- Do not enable multi-select if consumers only understand a single current row.
Default: none
Initial page size and the page-size choices shown in the list footer.
- Initial page size used when the list loads (footer page-size control).Avoid
- Avoid very large defaults for heavy views or narrow layouts.
Default: none - Page-size options offered in the list footer. Defaults to [10, 25, 50, 100, 1000] when omitted.Example
[10, 25, 50, 100, 1000]Default: none
Initial sort applied when the list loads. List has no clickable column headers — this is the main way to control order.
- Initial sort clauses (fieldName + asc). Earlier entries win; later entries break ties. List has no interactive column headers, so this largely defines order.Good to know
- Pick business-meaningful fields so the first page is predictable.
Avoid- Do not rely on undefined database order for important work queues.
Example[{ "fieldName": "status", "asc": true, "hidden": true }, { "fieldName": "created_at", "asc": false, "hidden": true }]Default: none
Builder-authored filters applied on every load (visual rules and/or expression). List has no end-user filter UI.
- Builder-authored filter (expression and/or structured group) applied on every data request. Configured in Filter by.Good to know
- Use to scope the list (e.g. only open items, or rows matching a parent form id).
ExamplenullDefault: none - Visual Filter-by rules stored as a flat list of field/operator/value (or selector) entries. Written by the Filter by editor together with the combinator.Default: none
- How visual Filter-by rules combine: AND or OR.Choices
AND— Every rule must match.OR— Any rule may match.
Default: none
Background refresh polling interval in seconds.
- Automatic refresh interval in seconds. 0 disables polling.Avoid
- Do not poll aggressively for static lists or expensive queries.
Default: none
Present because List shares the data-element config codec with Table. The List designer does not expose search, allowed-filter, or column-hidden editors, and the List runtime has no ToolsPanel.
- Row filter applied when loading data.Avoid
- Do not expect end users to build filters from this on a List — there is no filter dialog.
Default: {"fields":[]} - Fields that participate in a simple search box. List has no search UI; configuring this has no effect unless you add custom tooling. Prefer Table for searchable lists.Default: none
- Hides the simple search input. Relevant to Table only; List never renders that input.Default: none
- When true, simple-search values are wrapped for PostgREST full-text matching. Only meaningful with a simple search UI (Table).Default: none
- Per-column visibility expressions used by Table. List does not read this — hide content inside the row grid template instead.Default: none
Inside filter: (filter)
- Allowed filterable fields for an end-user filter UI. Unused by List (no ToolsPanel); Table owns this feature.Default: []
- Minimum size: 2 × 2 grid cells (width × height).
- Default size when dropped on a page: 4 × 4.
- The row slot should contain one default_grid template before the list is useful at runtime.
Selectable rows use radio or checkbox controls with an accessible name. Keep interactive controls inside the row template keyboard-reachable; the list body scrolls independently of the pagination footer.
- Tab moves through selection controls and focusable elements inside each row card.
- Pagination controls in the footer change page and page size.
Other parts of your app can read live values from this element in custom expressions:
elements.myList.<property>
loading
boolean
True while data is loading from the server.
elements.myList.loading
When Disable actions or show a placeholder while the list is fetching.
data
null
The records currently loaded into the list.
elements.myList.data.length
When Rows on the current page only. Useful for a count badge or a chart beside the list — not a full-table total.
references
null
Related records loaded with the main row.
elements.myList.references
params
object
Query parameters sent with the data request.
elements.myList.params
loadingParams
object
Query parameters used for the request that is currently loading.
elements.myList.loadingParams
offset
number
Index of the first row shown on the current page.
elements.myList.offset
limit
number
Maximum number of rows loaded per page.
elements.myList.limit
order
Array<object>
Active sort order as a list of columns and directions.
elements.myList.order
orderIndexed
Record<string, object>
Active sort order keyed by column name.
elements.myList.orderIndexed
error
string
Error message when the last operation failed.
elements.myList.error
When Surface a load failure in another element when the list request fails.
nextFilter
object
Filter that will be applied to the next data request.
elements.myList.nextFilter
nextPageAvailable
boolean
True when more rows can be loaded after the current page.
elements.myList.nextPageAvailable
When Know whether the footer can advance to another page.
searchInputValue
string
Current text typed into the search box.
elements.myList.searchInputValue
metadata
object
Additional server metadata for the current result set.
elements.myList.metadata.canUpdate
When Read table-level or per-state permissions (canUpdate / canDelete) when gating row actions in the template.
selected
unavailable
Currently selected item(s) in the list.
elements.myList.selected.identifier
When Drive a detail form, conditional panel, or action from the current selection. Requires Can Select Row. Use `.identifier` / `.row` for single select, or `.keys` / `.rows` for multi-select.
To use one of these, open the property you want to drive on the other element, switch it to expression mode in the Expression Editor, and enter:
| |
Replace myList with this element’s unique id. Select the element in Application Designer and copy the id chip at the top of the right-hand property panel.
This container accepts nested elements in these slots:
| slot | accepts |
|---|---|
row | Grid |
graph TD root["default_list"] root --> row["row slot"]
Drag this element into one of these containers:
- Grid (
contentslot) — Most list pages sit in a page grid. Give enough height for several cards plus the footer. - Modal Dialog (
contentslot) — Works well as a picker inside a modal — keep the row template compact and turn selection on. - Tabs (
contentslot) — Use inside tabs when the list is one section of a larger workflow. - Form (
contentslot) — Can sit beside or under a form when Filter by ties the list to the current form record.
| |