` carries none, so rows can leave the raw answers out. Its payload is `{ rowKey, key }` (the row's key and the column key); it returns `{ raw }`. |
| `importCsv` | boolean | `false` | Show an Import button in the toolbar: a CSV file (at most 50 MB and 100,000 rows) is parsed in the browser, in slices so the page stays responsive, its headers mapped to input columns (or new text columns), and the rows sent through onImport in batches of 500. |
| `summary` | boolean | `true` | Show the summary footer when `summaryRow` is set or any aggregate is in effect: a column `aggregate`, or one the view sets in `view.aggregates`. `false` hides it. |
| `summaryRow` | object \| null | - | A row the app computed, such as a report total from the request, shown in the summary footer in place of the aggregates. Each column renders it like a body row, with its `type`, `cell` and `rules`; action columns stay empty. It is not a data row: sorting, filtering, search, selection and the record count leave it out, and `exportCsv` adds it as the last line (in server mode `onExport` produces the file). Group headers keep their aggregates. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onChange` | `{ value, cause }` | Trigger when the table value changes through the table: a sort, a filter or search, a column change (resize, reorder, pin, hide, column manager), or a selection. |
| `onSelectionChange` | `{ selected, rows }` | Trigger when the row selection changes. "Select all matching" in the bulk bar (and, in server mode, the header checkbox) selects every row the view matches as `{ all: true, except, filter, search }`: every row matching that filter and search except the `except` keys, so a request can resolve it from the value alone. Changing the filter or search clears such a selection. |
| `onRowExpand` | `{ row, rowKey, expanded, needsChildren }` | Trigger when a tree row or an expandable row is expanded or collapsed. With `tree.lazy`, load the row's children here when `needsChildren` is true (skip the load action otherwise) and add them to `data`. |
| `onExport` | `{ view, filename, formatted }` | Server mode: trigger when `exportCsv` is called. The browser only holds the loaded blocks, so produce the file from the view, for example with a request and a download action. |
| `onRowClick` | `{ row, rowKey, index }` | Trigger when a row is clicked, or activated with Enter. Clicks on buttons, links, menus and `data-event` elements in a cell, and clicks that end a text selection, do not trigger it. With `rowLink`, a plain click runs onRowClick instead of following the link. |
| `onRowDoubleClick` | `{ row, rowKey, index }` | Trigger when a row is double clicked. |
| `onCellClick` | `{ row, rowKey, column, value }` | Trigger actions when a cell is clicked. Clicks on controls in the cell do not trigger it. |
| `onViewSelect` | `{ id }` | Trigger when a saved view tab is selected, after its view loads. |
| `onViewSave` | `{ view, id, title, shared }` | Trigger when the user saves the current view: Save (with the active view `id`) or Save as (no `id`, a new view), unless the block has `onViewSaveAs` actions. The app stores views; update `views` (and `activeView`) with the result. |
| `onViewSaveAs` | `{ view }` | Trigger when the user clicks Save as, in place of the built-in title and Shared popover, when the block has actions on it. Open your own dialog (for example a modal asking for a name and description), store the view, then update `views` and `activeView` as after `onViewSave`. |
| `onViewMenu` | `{ key, id }` | Trigger when the user picks a `viewMenu` item on a saved view tab, after its confirmation when the item has `confirm`. |
| `onViewDelete` | `{ id }` | Trigger when the user deletes a saved view from its tab menu (the default menu, without `viewMenu`). |
| `onCellEdit` | `{ row, rowKey, column, value, previous }` | Trigger when an edited cell commits. The cell shows the new value with a saving indicator while the event runs. When the actions fail (a Request error or a Throw), the cell reverts and shows the error message. After success the new value shows until the row changes in `data`. Without this event, edits only show in the table. |
| `onRowMove` | `{ row, rowKey, fromIndex, toIndex, beforeKey, afterKey, position, positions }` | Trigger when a row is dropped at a new place (`rowDrag`): a drag of its handle, or Alt+Shift+ArrowUp/Down. The rows reorder at once with a saving indicator on the handle while the event runs; when the actions fail the order reverts and the handle shows the error message. After success the new order shows until `data` changes. With `rowDrag.positionField`, save `position` on the moved row (`positions` holds every row whose position changed: normally just this one, all rows when the list had to be renumbered). Without it, save the order from `beforeKey` / `afterKey`. |
| `onColumnAdd` | `{ column, position }` | Trigger when a column is added: the add-column picker (`addColumn`), Duplicate or Insert left / right in a user-defined column's header menu, or "Add as column" in the cell details panel. The picker stays open, pending, while the event runs, and shows the error when the actions fail. Store the column and add it to `columns`. |
| `onColumnUpdate` | `{ column, previous }` | Trigger when a user-defined column is renamed (inline in its header) or edited (the picker). The rename or picker shows it pending while the event runs and the error when it fails. |
| `onColumnDelete` | `{ column }` | Trigger when a user-defined column is deleted from its header menu, after the confirmation. The dialog stays open, pending, while the event runs. |
| `onColumnRun` | `{ column, mode, selection }` | Trigger to run an enrichment or ai column: Run in its header menu (all rows, empty cells, errors or stale cells) or "Run selected" in the bulk bar. Enqueue the cells, for example with MongoDBEnrichmentEnqueue; their states then show in the cells. |
| `onRowRun` | `{ row, rowKey, columns }` | Trigger when a row's run button is clicked (the trailing column, shown on hover): run every enrichment and ai column of the row. |
| `onCellRun` | `{ row, rowKey, column }` | Trigger when one cell is rerun: Rerun in the cell details panel, or the rerun button of a stale cell. |
| `onRowAdd` | `{ rowKey, values }` | Trigger when a row is added with "+ New row" (`addRow`). The row shows at the end of the table, marked saving, under `rowKey` while the event runs; after it the row comes from `data` (add it there, for example by refetching). Save the row under `rowKey` (as its `_id`, or at the field the `rowKey` property names): the saved row then replaces the saving one as soon as `data` has it, even while the event still runs; a row saved under another key shows beside the saving row until the event settles. When the actions fail, the row goes and the editor shows the error with the values kept. |
| `onImport` | `{ rows, newColumns, batchIndex, batchCount, total }` | Trigger for each batch of rows a CSV import sends (`importCsv`), 500 rows at a time, each awaited before the next; a failed batch stops the import and shows its error. Insert the rows, for example with MongoDBInsertMany, and create `newColumns` once. |
| `onCellLink` | `{ link, row, value }` | Triggered when a link, avatar link or relation cell is clicked. The link navigates by itself; this event is for anything else to do. |
| `onCellButton` | `{ row, rowKey, value, button, buttonIndex }` | Documentation reference - the event fired is the `eventName` of each button in a `buttons` cell. Define any number of named events on the block, such as `onEdit`. |
| `onCellMenuItem` | `{ row, rowKey, value, item, itemIndex }` | Documentation reference - the event fired is the `eventName` of each item in a `menu` cell. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The table root element. |
| `/header` | The header row group. |
| `/row` | Every body row. |
| Slot | Description |
| --- | --- |
| `toolbarStart` | Blocks at the start of the toolbar, for example a "New deal" button. Blocks sit side by side at their content width (8px gap, wrapping); the slot's `gap`, `align` and `justify` and a block's `layout.flex` still apply. |
| `toolbarEnd` | Blocks at the end of the toolbar, side by side like `toolbarStart`. |
| `bulkActions` | Blocks in the bulk action bar, shown while rows are selected, side by side at the end of the bar like `toolbarStart`. |
| `empty` | Blocks shown instead of the empty state when there are no rows and no filter or search. |
| `emptyFiltered` | Blocks shown instead of "No matching rows" and Clear filters when a filter or search hides every row, for example "No deals match this view right now." with an Edit filter button, so the view keeps its filter. |
---
url: https://docs.lowdefy.com/md/display-blocks/tablelight.md
---
# TableLight
A light table for the odd table on a page: a few columns and tens to hundreds of rows, with typed cells (numbers, dates, tags, people, links and more), sorting by header click, row links, row buttons and menus, conditional formatting and a summary row. It renders the Ant Design Table and adds no dependencies. Its config is a subset of the Table block's, so a table that outgrows it changes `type: TableLight` to `type: Table`.
## When to use TableLight
`TableLight` is for the quick table here and there: a list of recent orders on a dashboard, the line items of an invoice, a short list of team members with an Edit button. It renders every row, so keep it to tens or hundreds of rows. In development it logs a console warning above 1,000 rows.
It has no value and keeps no state an app can read. For column filters, resizing, grouping, selection, editing, saved views, virtualisation or server-side data, use [`Table`](/Table). TableLight's config is a strict subset of Table's, so switching is a change of `type`. The [Table guide](/Table) compares TableLight, Table, TableInput and AgGrid and shows each kind of table as config. A key only Table supports stops the block with an error such as `Block "TableLight" property "columns.0.filterable" is not supported. Use Table for column filters.` The Table-only keys are `rowSelection`, `toolbar`, `views`, `activeView`, `defaultView`, `persist`, `virtual`, `headerMenu`, `reorderable`, `stickyHeader`, `rowHeight`, `maxHeight`, `rowDrag`, `tree`, `expandable`, `keyboard` and `rowVersionField` on the block; `filterable`, `resizable`, `groupable`, `editable`, `validate`, `required`, `default`, `searchable`, `flex` and `maxWidth` on columns; and `width` and `minWidth` on `defaultColumn`.
## Columns
A column is an object, or just its key:
```yaml
columns:
- name # key and field "name", title "Name"
- key: owner_name # title "Owner name"
field: owner.name
- key: amount
type: currency
cell:
currency: EUR
aggregate: sum
```
- `key` is the column id and `field` the dot path of the value in the row. Each defaults to the other.
- `title` defaults to the key in sentence case, and supports html. `headerTooltip` adds a tooltip to the header.
- `type` picks the cell type (below) and `cell` holds that type's options. The option names match the AgGrid `cell` keys, so a column moves over by lifting `cell.type` to `type`.
- `align` is `start`, `center` or `end`; number, currency and percent columns default to `end`.
- `width` and `minWidth` are in pixels. `pinned: start` or `pinned: end` keeps a column in view while the table scrolls sideways.
- Text stays on one line. `wrap: true` wraps it and `ellipsis: 2` clamps it to two lines with the full text on hover. A clamp needs a column `width`.
- `children` groups columns under a shared header.
- `hidden: true` declares a column without showing it.
## Cell types
| type | shows | options in `cell` |
| ------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `text` | the value (the default) | |
| `number`, `currency`, `percent` | formatted with `Intl.NumberFormat` | `format`, `locale`, `currency`, `decimals`, `minDecimals`, `maxDecimals`, `notation`, `useGrouping`, `negative`, `prefix`, `suffix`, `signColor`, `positiveColor`, `negativeColor`, `zeroColor`, `color`, `thresholds` + `colors` |
| `date`, `datetime` | a dayjs format, or relative time with the date on hover | `format`, `relative` |
| `boolean` | a label or an icon | `trueLabel`, `falseLabel`, `trueColor`, `falseColor`, `trueIcon`, `falseIcon` |
| `tag`, `tags`, `status` | tinted tags, or a dot and a label | `colorMap`, `colorFrom`, `default`, `max` (tags) |
| `avatar`, `people` | initials or an image; `people` overlaps several with a +N count | `nameField`, `srcField`, `idField`, `shape`, `link` (avatar), `max` (people) |
| `link` | a link that navigates by itself | `pageId`, `href`, `urlQuery`, `pathParams`, `newTab`, `home`, `back`, `input`, `labelField` |
| `email`, `phone`, `url` | `mailto:`, `tel:` and external links | `label`, `labelField`, `newTab` (url) |
| `relation` | related records as chips, linked to their page | `labelField`, `pageId`, `href`, `urlQuery`, `pathParams`, `newTab` |
| `progress`, `rating` | a bar, or stars | `max`, `suffix`, `color`, `thresholds`, `colors`, `showValue`, `nullLabel` (progress) |
| `image` | a lazy thumbnail | `width`, `height`, `shape`, `alt`, `altField` |
| `html` | a template or a field holding HTML | `template` |
| `json` | a one-line preview | |
| `buttons` | row buttons | `buttons`, `showOn` |
| `menu` | a row menu | `items`, `icon`, `title`, `placement` |
Values in `urlQuery`, `pathParams` and every `...Field` option are paths in the row. For `people` they are paths in each person, and for `relation` paths in the related record, where `urlQuery` defaults to `{ _id: _id }` when neither `urlQuery` nor `pathParams` is set.
A `url` value with a scheme other than http or https, such as `javascript:`, shows as text, not as a link.
### Options: labels and colours for enum values
`options` gives the labels and colours of `tag`, `tags` and `status` values. It takes a list, or a map from value to a label or `{ label, color, icon }`:
```yaml
- key: stage
type: status
options:
lead: Lead
qualified: { label: Qualified, color: processing }
won: { label: Won, color: success }
lost: { label: Lost, color: error }
```
Colours are the antd presets (`blue`, `green`, `gold`, ...), the status names (`success`, `processing`, `warning`, `error`) or any CSS colour. The presets and status names follow the theme and dark mode. An enum column sorts in the order its options are declared. A value without an option, in a column without `options` or colour keys, gets a colour picked from the value, so the same value always has the same colour.
### HTML templates
An `html` cell renders a [nunjucks](https://mozilla.github.io/nunjucks/) template with `value` and `row`, compiled once per column:
```yaml
- key: summary
type: html
cell:
template: '{{ row.title }} {{ value }}'
```
Values are escaped. Use `| safe` to insert HTML held in a field. The output is sanitised, and `data-event` attributes fire block events as in other HTML.
## Conditional formatting
`rules` on a column colour or style cells whose value meets a condition. `rowRules` does the same for rows:
```yaml
rowRules:
- when: { key: overdue, op: isTrue }
className: row-warning
columns:
- key: score
type: number
rules:
- when: { op: gte, value: 8 }
color: success
- when: { op: lt, value: 5 }
color: error
```
A condition is `{ key, op, value }`, or `{ and: [...] }` / `{ or: [...] }` of conditions. In a column rule, a condition without `key` tests the column's own value. Every rule that holds applies, in order.
| operators | for |
| ------------------------------------------------------------------------------------------------------ | ------------------------------ |
| `eq`, `ne`, `in`, `nin`, `empty`, `notEmpty` | every type |
| `contains`, `notContains`, `startsWith`, `endsWith` | text, links, tags and statuses |
| `gt`, `gte`, `lt`, `lte`, `between` (`value: [from, to]`) | numbers |
| `before`, `after`, `between`, `within` (`value: { last: 7, unit: day }` or `{ next: 1, unit: month }`) | dates; `eq` compares by day |
| `isTrue`, `isFalse` | booleans |
| `in` (any of), `nin` (none of), `contains` (has the value) | tags and people |
Text comparisons ignore case, and `empty` matches null, a missing value, an empty string and an empty list. To compare with the current user, use the `_user` operator in the value, for example `value: { _user: id }`.
`hidden` and `disabled` on buttons and menu items take the same conditions: `hidden: { when: { key: locked, op: isTrue } }`.
## Sorting
Clicking a header sorts ascending, then descending, then back to the data order. The column type sets the order: numbers numerically, dates by time, enums by option order and text alphabetically, ignoring case and reading numbers in text as numbers. Empty values always sort last. Set `sortable: false` on a column, or `defaultColumn: { sortable: false }` for the whole table.
## Rows, clicks and links
`rowKey` names the field that identifies a row, and defaults to `_id`, then `id`. Rows with neither get a key per row object, which does not survive a refetch.
`rowLink` makes every row a link:
```yaml
rowLink:
pageId: order
urlQuery:
_id: _id
```
For a page with a [`path`](/page-paths), give its placeholder values in `pathParams`, also as paths in the row: `rowLink: { pageId: ticket, pathParams: { space: space_id, ticket_id: _id } }`. Table links are block properties, so on a public page a link to a protected page with a path cannot be built while the user is logged out (see [`Link`](/Link)).
A plain click navigates, and a Cmd/Ctrl or middle click opens a new tab. With `onRowClick` defined as well, a plain click runs `onRowClick` (to open a drawer, say) and only a modified click follows the link.
`onRowClick` receives `{ row, rowKey, index }`, where `index` is the row's position in `data`, whatever the sort. `onCellClick` receives `{ row, rowKey, column: { key, field }, value }`. Clicks on buttons, links, menus and `data-event` elements in a cell, and a mouse drag that selects text, trigger neither.
A `link` cell navigates by itself. It also fires `onCellLink` with `{ link, row, value }`, so do not add a `Link` action to that event.
## Buttons and menus
```yaml
- key: actions
type: buttons
cell:
showOn: hover
buttons:
- eventName: onEdit
title: Edit
icon: edit
- eventName: onArchive
title: Archive
icon: Archive
hideTitle: true
- key: more
type: menu
cell:
items:
- eventName: onDelete
title: Delete
danger: true
```
Each button or menu item fires the block event named by its `eventName`, with `{ row, rowKey, value, button: { eventName, title }, buttonIndex }` or `{ row, rowKey, value, item: { eventName, title }, itemIndex }`. The button keys are the AgGrid buttons cell keys: `title` / `titleField`, `icon` / `iconField`, `hidden` / `hiddenField`, `disabled` / `disabledField`, `type`, `variant`, `color`, `size`, `shape`, `danger`, `ghost`, `hideTitle`, `tooltip` and `iconPlacement`. An icon-only button shows its title as a tooltip.
`showOn: hover` hides the buttons until the row is hovered or has focus. Touch screens always show them.
## Summary row, pagination and layout
- A column with `aggregate` adds a summary row: `sum`, `avg`, `min`, `max`, `count`, `countDistinct`, `countEmpty`, `countNotEmpty`, `percentEmpty`, `earliest` or `latest`, calculated over every row. `summary: false` hides it.
- Pages show only when there are more rows than `pageSize` (default 50). `pagination: false` shows every row; `pagination: true` always shows the pager.
- `height` fixes the body height: rows scroll under a sticky header, and the summary row stays in view.
- `size` is `compact`, `default` or `comfortable`. `bordered` and `emptyText` (default "No rows") do what they say.
## Loading states
TableLight shows loading the way [`Table`](/TableGuide#loading-states) does, so switching `type` looks the same. With no rows yet and `loading` true (the property, or Lowdefy's own while `onMount` actions run) it shows the real header over skeleton rows shaped like the cells, filling `height` (or 600px) and at most a page. With rows, a refetch keeps them on screen, even while `_request` returns null, and a thin progress bar runs under the header. The skeleton shows after 120 ms and stays at least 300 ms, so fast responses never flash it. There is no spinner overlay.
```yaml
- id: recent_orders
type: TableLight
properties:
loading:
_request_details: recent_orders.0.loading
data:
_request: recent_orders
columns: [number, customer, total]
```
A block `skeleton` config replaces the table while the block loads, as for any block.
```yaml
- id: basic_table
type: TableLight
properties:
columns:
- name
- key: email
type: email
- key: role
- key: joined
type: date
data:
- _id: 1
name: Sarah Johnson
email: sarah@example.com
role: Engineer
joined: 2023-04-12
- _id: 2
name: Alex Chen
email: alex@example.com
role: Product
joined: 2022-11-01
- _id: 3
name: Maria Garcia
email: maria@example.com
role: Design
joined: 2024-02-20
```
```yaml
- id: orders_table
type: TableLight
properties:
rowLink:
pageId: order
urlQuery:
_id: _id
columns:
- key: number
title: Order
- key: customer
type: avatar
- key: status
type: tag
options:
pending:
label: Pending
color: warning
shipped:
label: Shipped
color: processing
delivered:
label: Delivered
color: success
cancelled:
label: Cancelled
color: error
- key: total
type: currency
cell:
currency: USD
aggregate: sum
- key: placed
type: date
cell:
relative: true
data:
- _id: o1
number: ORD-1042
customer: Sarah Johnson
status: delivered
total: 129.97
placed: 2026-09-20T10:15:00
- _id: o2
number: ORD-1043
customer: Alex Chen
status: shipped
total: 54.5
placed: 2026-09-24T16:40:00
- _id: o3
number: ORD-1044
customer: Maria Garcia
status: pending
total: 310
placed: 2026-09-27T08:05:00
- _id: o4
number: ORD-1045
customer: Jordan Rivera
status: cancelled
total: 18.99
placed: 2026-09-27T12:30:00
```
```yaml
- id: cell_types_table
type: TableLight
properties:
columns:
- key: company
type: relation
cell:
labelField: name
- key: owners
type: people
- key: stage
type: status
options:
- value: lead
label: Lead
color: default
- value: qualified
label: Qualified
color: processing
- value: won
label: Won
color: success
- key: labels
type: tags
cell:
max: 2
- key: probability
type: percent
- key: health
type: progress
- key: rating
type: rating
- key: active
type: boolean
- key: website
type: url
- key: phone
type: phone
data:
- _id: d1
company:
_id: c1
name: Acme Ltd
owners:
- name: Ann Lee
- name: Bob Stone
- name: Cy Dunn
- name: Di Park
stage: won
labels:
- enterprise
- renewal
- priority
probability: 0.9
health: 82
rating: 4
active: true
website: acme.example.com
phone: +1 555 010 2000
- _id: d2
company:
_id: c2
name: Globex
owners:
- name: Bob Stone
stage: qualified
labels:
- smb
probability: 0.4
health: 35
rating: 3
active: false
website: https://globex.example.com
phone: +1 555 010 3000
```
```yaml
- id: rules_table
type: TableLight
properties:
size: compact
bordered: true
rowRules:
- when:
key: overdue
op: isTrue
style:
fontStyle: italic
columns:
- key: task
- key: score
type: number
rules:
- when:
op: gte
value: 8
color: success
- when:
op: lt
value: 5
color: error
- key: summary
type: html
ellipsis: 2
width: 260
cell:
template: "{{ row.task }} : {{ value }}"
- key: overdue
type: boolean
cell:
trueLabel: Overdue
falseLabel: On time
trueColor: error
data:
- _id: t1
task: Onboarding
score: 9
summary: Welcome pack sent and first call booked.
overdue: false
- _id: t2
task: Renewal
score: 4
summary: Waiting on the signed order form from procurement.
overdue: true
- _id: t3
task: Upsell
score: 6
summary: Demo scheduled for next week.
overdue: false
```
```yaml
- id: actions_table
type: TableLight
properties:
columns:
- key: name
- key: email
type: email
- key: actions
type: buttons
align: end
cell:
showOn: hover
buttons:
- eventName: onEdit
title: Edit
icon: edit
- eventName: onArchive
title: Archive
icon: Archive
hideTitle: true
hidden:
when:
key: archived
op: isTrue
- key: more
title: ""
type: menu
width: 48
cell:
items:
- eventName: onDuplicate
title: Duplicate
- eventName: onDelete
title: Delete
danger: true
data:
- _id: u1
name: Sarah Johnson
email: sarah@example.com
archived: false
- _id: u2
name: Alex Chen
email: alex@example.com
archived: true
events:
onEdit:
- id: edit_message
type: DisplayMessage
params:
content:
_string.concat:
- "Edit "
- _event: row.name
```
```yaml
- id: grouped_table
type: TableLight
properties:
height: 200
pagination: false
columns:
- key: region
pinned: start
width: 140
- title: Q1
children:
- key: jan
type: currency
aggregate: sum
width: 120
- key: feb
type: currency
aggregate: sum
width: 120
- key: mar
type: currency
aggregate: sum
width: 120
- title: Q2
children:
- key: apr
type: currency
aggregate: sum
width: 120
- key: may
type: currency
aggregate: sum
width: 120
- key: jun
type: currency
aggregate: sum
width: 120
data:
- _id: 1
region: North
jan: 12000
feb: 13500
mar: 14100
apr: 12900
may: 15200
jun: 16000
- _id: 2
region: South
jan: 9800
feb: 10100
mar: 9900
apr: 11200
may: 11800
jun: 12500
- _id: 3
region: East
jan: 15300
feb: 14900
mar: 16200
apr: 17100
may: 16800
jun: 18200
- _id: 4
region: West
jan: 8700
feb: 9200
mar: 9800
apr: 10400
may: 10900
jun: 11300
- _id: 5
region: Central
jan: 11100
feb: 11600
mar: 12000
apr: 12500
may: 13100
jun: 13400
- _id: 6
region: Islands
jan: 4300
feb: 4100
mar: 4600
apr: 4900
may: 5200
jun: 5600
```
```yaml
- id: empty_table
type: TableLight
properties:
emptyText: No orders yet.
columns:
- number
- key: total
type: currency
data: []
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `data` | array \| null | - | The rows to show. |
| `rowKey` | string | - | The row field that identifies each row. Defaults to `_id`, then `id`. Rows with neither get a key per row object, which does not survive a refetch. |
| `columns` | array \| null | - | The columns, in order. |
| `defaultColumn` | object | - | Defaults applied to every column. |
| `defaultColumn.sortable` | boolean | `true` | Sort by clicking a header. |
| `defaultColumn.wrap` | boolean | `false` | Wrap long text. |
| `defaultColumn.ellipsis` | integer | - | Clamp text to this many lines. |
| `user` | object | - | The user object for `$user` values in `rules`, `rowRules` and button `hidden`/`disabled` conditions, usually `{ _user: true }`. Blocks do not see the session, so conditions read `$user` from this property. |
| `rowLink` | object | - | Make rows links. A plain click navigates, Cmd/Ctrl or middle click opens a new tab. Values in `urlQuery` and `pathParams` are row paths. |
| `rowLink.pageId` | string | - | The page to open. |
| `rowLink.href` | string | - | A URL to open instead of a page. |
| `rowLink.urlQuery` | object | - | Query parameters; each value is a path in the row, like `{ _id: _id }`. |
| `rowLink.pathParams` | object | - | Values for the page path's placeholders; each value is a path in the row, like `{ ticket_id: _id }`. |
| `rowLink.input` | object | - | Input for the page. |
| `rowLink.newTab` | boolean | - | Always open in a new tab. |
| `rowRules` | array | - | Conditional row formatting: `[{ when, className, style, color }]`, where `when` conditions name columns by `key`. |
| `size` | string | `"default"` | Row density. Enum: `compact`, `default`, `comfortable`. |
| `bordered` | boolean | `false` | Draw borders around cells. |
| `height` | number \| string | - | A fixed body height; the rows scroll under a sticky header and the summary row stays in view. |
| `emptyText` | string | - | What to show when there are no rows - supports html. Defaults to "No rows". |
| `loading` | boolean | `false` | Show the loading state: skeleton rows while there are no rows yet, a progress bar under the header while rows are shown. The rows stay while `data` is null during a refetch. Lowdefy sets loading while onMount actions run. |
| `pagination` | boolean | - | Pages are shown only when there are more rows than `pageSize`. `false` shows every row on one page; `true` always shows the pager. |
| `pageSize` | integer | `50` | Rows per page. |
| `summary` | boolean | `true` | Show the summary row when a column declares an `aggregate`. `false` hides it. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onRowClick` | `{ row, rowKey, index }` | Trigger actions when a row is clicked. Clicks on buttons, links, menus and `data-event` elements in a cell, and clicks that end a text selection, do not trigger it. With `rowLink`, a plain click runs onRowClick instead of following the link. |
| `onCellClick` | `{ row, rowKey, column, value }` | Trigger actions when a cell is clicked. Clicks on controls in the cell do not trigger it. |
| `onCellLink` | `{ link, row, value }` | Triggered when a link, avatar link or relation cell is clicked. The link navigates by itself; this event is for anything else to do. |
| `onCellButton` | `{ row, rowKey, value, button, buttonIndex }` | Documentation reference - the event fired is the `eventName` of each button in a `buttons` cell. Define any number of named events on the block, such as `onEdit`. |
| `onCellMenuItem` | `{ row, rowKey, value, item, itemIndex }` | Documentation reference - the event fired is the `eventName` of each item in a `menu` cell. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The TableLight element. |
No slots defined.
---
url: https://docs.lowdefy.com/md/display-blocks/tag.md
---
# Tag
Tag with preset and custom colors, icons, and closable option.
```yaml
- id: title_simple
type: Tag
layout:
flex: 0 0 auto
properties:
title: Feature
- id: title_html_bold
type: Tag
layout:
flex: 0 0 auto
properties:
title: Important Update
- id: title_html_styled
type: Tag
layout:
flex: 0 0 auto
properties:
title: 'NEW '
- id: title_fallback
type: Tag
layout:
flex: 0 0 auto
```
```yaml
- id: color_status_row
type: Box
layout:
gap: 8
blocks:
- id: color_success
type: Tag
layout:
flex: 0 0 auto
properties:
title: success
color: success
- id: color_processing
type: Tag
layout:
flex: 0 0 auto
properties:
title: processing
color: processing
- id: color_error
type: Tag
layout:
flex: 0 0 auto
properties:
title: error
color: error
- id: color_warning
type: Tag
layout:
flex: 0 0 auto
properties:
title: warning
color: warning
- id: color_default
type: Tag
layout:
flex: 0 0 auto
properties:
title: default
color: default
- id: color_named_row
type: Box
layout:
gap: 8
blocks:
- id: color_blue
type: Tag
layout:
flex: 0 0 auto
properties:
title: blue
color: blue
- id: color_green
type: Tag
layout:
flex: 0 0 auto
properties:
title: green
color: green
- id: color_gold
type: Tag
layout:
flex: 0 0 auto
properties:
title: gold
color: gold
- id: color_purple
type: Tag
layout:
flex: 0 0 auto
properties:
title: purple
color: purple
- id: color_volcano
type: Tag
layout:
flex: 0 0 auto
properties:
title: volcano
color: volcano
```
```yaml
- id: variant_filled
type: Tag
layout:
flex: 0 0 auto
properties:
title: Filled
color: blue
- id: variant_outlined
type: Tag
layout:
flex: 0 0 auto
properties:
title: Outlined
color: blue
variant: outlined
- id: variant_solid
type: Tag
layout:
flex: 0 0 auto
properties:
title: Solid
color: blue
variant: solid
- id: variant_solid_success
type: Tag
layout:
flex: 0 0 auto
properties:
title: Paid
color: success
variant: solid
```
```yaml
- id: hex_coral
type: Tag
layout:
flex: 0 0 auto
properties:
title: Coral
color: "#ff6b6b"
- id: hex_teal
type: Tag
layout:
flex: 0 0 auto
properties:
title: Teal
color: "#20c997"
- id: hex_indigo
type: Tag
layout:
flex: 0 0 auto
properties:
title: Indigo
color: "#4c6ef5"
- id: hex_navy
type: Tag
layout:
flex: 0 0 auto
properties:
title: Navy
color: "#1864ab"
```
```yaml
- id: icon_string
type: Tag
layout:
flex: 0 0 auto
properties:
title: Approved
icon: check
color: success
- id: icon_warning
type: Tag
layout:
flex: 0 0 auto
properties:
title: Warning
icon: warning
color: warning
- id: icon_star
type: Tag
layout:
flex: 0 0 auto
properties:
title: Featured
icon: star
color: gold
- id: icon_object_color
type: Tag
layout:
flex: 0 0 auto
properties:
title: Custom Icon
icon:
name: Crown
color: "#faad14"
color: gold
- id: icon_object_style
type: Tag
layout:
flex: 0 0 auto
properties:
title: Large Icon
icon:
name: Rocket
style:
fontSize: 16
color: purple
```
```yaml
- id: closable_default
type: Tag
layout:
flex: 0 0 auto
properties:
title: Removable
closable: true
- id: closable_colored
type: Tag
layout:
flex: 0 0 auto
properties:
title: Done
closable: true
color: success
- id: closable_with_icon
type: Tag
layout:
flex: 0 0 auto
properties:
title: Starred
closable: true
icon: star
- id: closable_custom_icon
type: Tag
layout:
flex: 0 0 auto
properties:
title: Custom close icon
closable: true
closeIcon: close-circle
color: gold
- id: closable_with_event
type: Tag
layout:
flex: 0 0 auto
properties:
title: Close me
closable: true
color: processing
events:
onClose:
- id: closable_event_msg
type: DisplayMessage
params:
content: Tag closed!
status: info
```
```yaml
- id: link_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Open the docs
icon: external-link
href: https://docs.lowdefy.com
target: _blank
- id: disabled_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Archived
disabled: true
```
```yaml
- id: click_basic
type: Tag
layout:
flex: 0 0 auto
properties:
title: Click me
color: blue
events:
onClick:
- id: click_basic_msg
type: DisplayMessage
params:
content: Tag clicked!
status: info
- id: click_with_icon
type: Tag
layout:
flex: 0 0 auto
properties:
title: View Details
icon: view
color: geekblue
events:
onClick:
- id: click_icon_msg
type: DisplayMessage
params:
content: Opening details...
status: info
- id: click_set_state
type: Tag
layout:
flex: 0 0 auto
properties:
title: Select Category
color: purple
events:
onClick:
- id: click_set_state_action
type: SetState
params:
selectedCategory: design
```
```yaml
- id: shortcut_filter
type: Tag
layout:
flex: 0 0 auto
properties:
title: Toggle Filter
icon: filter
color: blue
events:
onClick:
shortcut: mod+f
try:
- id: filter_msg
type: DisplayMessage
params:
content: Filter toggled
status: info
```
```yaml
- id: css_shadow
type: Tag
layout:
flex: 0 0 auto
class: shadow-md
properties:
title: Shadow
color: blue
- id: css_rounded
type: Tag
layout:
flex: 0 0 auto
class: rounded-full
properties:
title: Pill Shape
color: green
- id: css_uppercase
type: Tag
layout:
flex: 0 0 auto
class: uppercase tracking-wider
properties:
title: Uppercase
color: purple
- id: style_inline_bold
type: Tag
layout:
flex: 0 0 auto
properties:
title: Bold Text
color: volcano
style:
.element:
fontWeight: bold
fontSize: 14px
- id: style_inline_padding
type: Tag
layout:
flex: 0 0 auto
properties:
title: Extra Padding
color: cyan
style:
.element:
padding: 4px 16px
borderWidth: 2px
```
```yaml
- id: theme_light_blue
type: Tag
layout:
flex: 0 0 auto
properties:
title: Light Blue
theme:
defaultColor: "#1677ff"
- id: theme_dark
type: Tag
layout:
flex: 0 0 auto
properties:
title: Dark Tag
theme:
defaultBg: "#141414"
defaultColor: "#ffffff"
- id: theme_warm
type: Tag
layout:
flex: 0 0 auto
properties:
title: Warm Tone
theme:
defaultColor: "#d46b08"
- id: theme_solid_text
type: Tag
layout:
flex: 0 0 auto
properties:
title: Custom Solid
color: "#7c3aed"
theme:
solidTextColor: "#fde68a"
```
When a user enters an email without a domain, the login page throws an unhandled exception and shows a blank screen.
```yaml
- id: issue_card
type: Card
properties:
title: "BUG-1042: Login page crashes on invalid email"
size: small
blocks:
- id: issue_description
type: Markdown
properties:
content: When a user enters an email without a domain, the login page throws an
unhandled exception and shows a blank screen.
- id: issue_tags_row
type: Box
layout:
gap: 8
blocks:
- id: issue_status
type: Tag
layout:
flex: 0 0 auto
properties:
title: In Progress
icon: RefreshCw
color: processing
- id: issue_priority
type: Tag
layout:
flex: 0 0 auto
properties:
title: High Priority
icon: arrow-up
color: error
style:
.element:
fontWeight: bold
- id: issue_label_bug
type: Tag
layout:
flex: 0 0 auto
properties:
title: bug
color: red
closable: true
events:
onClose:
- id: issue_remove_label
type: DisplayMessage
params:
content: Label removed
status: info
- id: issue_label_auth
type: Tag
layout:
flex: 0 0 auto
properties:
title: authentication
color: geekblue
closable: true
events:
onClose:
- id: issue_remove_auth_label
type: DisplayMessage
params:
content: Label removed
status: info
- id: issue_actions_row
type: Box
layout:
gap: 8
justify: flex-end
blocks:
- id: issue_assign_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Assign
icon: user
color: default
variant: outlined
size: small
events:
onClick:
- id: issue_assign_msg
type: DisplayMessage
params:
content: Assignee updated
status: success
- id: issue_resolve_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Resolve
icon: check
color: primary
variant: solid
size: small
events:
onClick:
- id: issue_resolve_msg
type: DisplayMessage
params:
content: Issue marked as resolved
status: success
```
Premium over-ear headphones with active noise cancellation, 30-hour battery life, and Bluetooth 5.3 connectivity.
**$249.99**
```yaml
- id: catalog_card
type: Card
properties:
title: Wireless Noise-Cancelling Headphones
size: small
blocks:
- id: catalog_tags_row
type: Box
layout:
gap: 8
blocks:
- id: catalog_new
type: Tag
layout:
flex: 0 0 auto
properties:
title: NEW
color: "#52c41a"
style:
.element:
fontWeight: bold
letterSpacing: 1px
- id: catalog_category
type: Tag
layout:
flex: 0 0 auto
properties:
title: Electronics
icon: Zap
color: blue
events:
onClick:
- id: catalog_cat_click
type: Link
params:
pageId: introduction
- id: catalog_stock
type: Tag
layout:
flex: 0 0 auto
properties:
title: In Stock
icon: check
color: success
- id: catalog_rating
type: Tag
layout:
flex: 0 0 auto
properties:
title: 4.8 Stars
icon: star
color: gold
- id: catalog_description
type: Markdown
properties:
content: Premium over-ear headphones with active noise cancellation, 30-hour
battery life, and Bluetooth 5.3 connectivity.
- id: catalog_price_row
type: Box
layout:
gap: 8
align: center
blocks:
- id: catalog_price
type: Markdown
layout:
flex: 0 0 auto
properties:
content: "**$249.99**"
- id: catalog_discount
type: Tag
layout:
flex: 0 0 auto
properties:
title: 20% OFF
color: red
style:
.element:
fontWeight: bold
- id: catalog_add_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Add to Cart
icon: ShoppingCart
color: primary
variant: solid
size: small
events:
onClick:
- id: catalog_add_msg
type: DisplayMessage
params:
content: Added to cart!
status: success
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `closable` | boolean | `false` | Allow tag to be closed. |
| `closeIcon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize the close icon of a closable tag. |
| `closeIcon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `closeIcon.color` | string | - | Icon color. |
| `closeIcon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `closeIcon.rotate` | number | - | Number of degrees to rotate the icon. |
| `closeIcon.spin` | boolean | - | Continuously spin the icon with animation. |
| `closeIcon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `closeIcon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `closeIcon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `closeIcon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `color` | string | - | Color of the Tag. Preset options are success, processing, error, warning, default, blue, cyan, geekblue, gold, green, lime, magenta, orange, purple, red, volcano, or alternatively any hex color. |
| `disabled` | boolean | `false` | Disable the tag. A disabled tag cannot be clicked or closed. |
| `href` | string | - | Render the tag as a link to this URL. |
| `target` | string | - | Where to open the href link, like `_blank` for a new tab. |
| `title` | string | - | Content title of tag - supports html. |
| `variant` | string | `"filled"` | Tag style variant. `filled` shows a tinted background, `outlined` adds a border and `solid` fills the tag with its color. Enum: `filled`, `solid`, `outlined`. |
| `icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize tag icon. |
| `icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `icon.color` | string | - | Icon color. |
| `icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design tag tokens](https://ant.design/components/tag#design-token). |
| `theme.defaultBg` | string | `"#fafafa"` | Default background color of the tag. |
| `theme.defaultColor` | string | `"rgba(0, 0, 0, 0.88)"` | Default text color of the tag. |
| `theme.solidTextColor` | string | `"#fff"` | Text color for solid (filled) tags, determined by background brightness. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onClick` | \- | Called when Tag is clicked. Renders a shortcut badge when a shortcut is configured. |
| `onClose` | \- | Called when Tag close icon is clicked. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Tag element. |
| `/icon` | The icon in the Tag. |
| `/closeIcon` | The close icon of a closable Tag. |
No slots defined.
---
url: https://docs.lowdefy.com/md/display-blocks/title.md
---
# Title
Heading title with levels, copyable, ellipsis, and text styles.
h1. Heading Level 1
h2. Heading Level 2
h3. Heading Level 3
h4. Heading Level 4
h5. Heading Level 5
```yaml
- id: level_h1
type: Title
properties:
content: h1. Heading Level 1
level: 1
- id: level_h2
type: Title
properties:
content: h2. Heading Level 2
level: 2
- id: level_h3
type: Title
properties:
content: h3. Heading Level 3
level: 3
- id: level_h4
type: Title
properties:
content: h4. Heading Level 4
level: 4
- id: level_h5
type: Title
properties:
content: h5. Heading Level 5
level: 5
```
Default Title
Secondary Title
Success Title
Warning Title
Danger Title
```yaml
- id: type_default
type: Title
properties:
content: Default Title
level: 4
- id: type_secondary
type: Title
properties:
content: Secondary Title
level: 4
type: secondary
- id: type_success
type: Title
properties:
content: Success Title
level: 4
type: success
- id: type_warning
type: Title
properties:
content: Warning Title
level: 4
type: warning
- id: type_danger
type: Title
properties:
content: Danger Title
level: 4
type: danger
```
Blue Title
Green Title
Purple Title
Coral Title
```yaml
- id: color_blue
type: Title
properties:
content: Blue Title
level: 4
color: "#1677ff"
- id: color_green
type: Title
properties:
content: Green Title
level: 4
color: "#52c41a"
- id: color_purple
type: Title
properties:
content: Purple Title
level: 4
color: "#722ed1"
- id: color_coral
type: Title
properties:
content: Coral Title
level: 3
color: "#ff6b6b"
```
Code Heading Level 3
const config = lowdefy.init()
npm install lowdefy
```yaml
- id: code_h3
type: Title
properties:
content: Code Heading Level 3
level: 3
code: true
- id: code_h4
type: Title
properties:
content: const config = lowdefy.init()
level: 4
code: true
- id: code_h5
type: Title
properties:
content: npm install lowdefy
level: 5
code: true
```
Italic Title
Underlined Title
Highlighted Title
Deleted Title
Italic & Underlined
Esc
```yaml
- id: deco_italic
type: Title
properties:
content: Italic Title
level: 4
italic: true
- id: deco_underline
type: Title
properties:
content: Underlined Title
level: 4
underline: true
- id: deco_mark
type: Title
properties:
content: Highlighted Title
level: 4
mark: true
- id: deco_delete
type: Title
properties:
content: Deleted Title
level: 4
delete: true
- id: deco_combined
type: Title
properties:
content: Italic & Underlined
level: 4
italic: true
underline: true
- id: deco_keyboard
type: Title
properties:
content: Esc
level: 4
keyboard: true
```
Disabled Section Heading
Disabled Subsection
Disabled Caption
```yaml
- id: disabled_h3
type: Title
properties:
content: Disabled Section Heading
level: 3
disabled: true
- id: disabled_h4
type: Title
properties:
content: Disabled Subsection
level: 4
disabled: true
- id: disabled_h5
type: Title
properties:
content: Disabled Caption
level: 5
disabled: true
```
Title with bold and italic words
Visit the Lowdefy website
Status: Online / Offline
```yaml
- id: html_bold_italic
type: Title
properties:
content: Title with bold and italic words
level: 4
- id: html_link
type: Title
properties:
content: Visit the Lowdefy website
level: 4
- id: html_colored_spans
type: Title
properties:
content: 'Status: Online / Offline '
level: 4
```
Copy this title
Title with custom copy text
Hover the copy icon
Custom copy icon
Two-state copy icons
```yaml
- id: copyable_simple
type: Title
properties:
content: Copy this title
level: 4
copyable: true
- id: copyable_custom_text
type: Title
properties:
content: Title with custom copy text
level: 4
copyable:
text: This custom text is copied instead of the visible title.
- id: copyable_tooltips
type: Title
properties:
content: Hover the copy icon
level: 4
copyable:
tooltips:
- Click to copy
- Copied!
- id: copyable_custom_icon
type: Title
properties:
content: Custom copy icon
level: 4
copyable:
icon: Files
- id: copyable_two_icons
type: Title
properties:
content: Two-state copy icons
level: 4
copyable:
icon:
- copy
- check
tooltips:
- Copy text
- Done!
```
This is a very long title that should be truncated with an ellipsis when it overflows the available space in a single line of the container.
This is an extremely long title that demonstrates multi-row ellipsis truncation. When the content exceeds the specified number of rows, it will be truncated and show an ellipsis indicator at the end of the visible text area.
This long title can be expanded by clicking the expand control. It demonstrates how ellipsis with expandable works to let users reveal the full heading when needed.
This title has a custom suffix appended after the ellipsis truncation point so readers know more content exists.
This long title can be expanded and collapsed again. The expand and collapse buttons use custom text set with the symbol option.
Hover this truncated title to see the full heading in a tooltip, which helps when titles come from user data.
```yaml
- id: ellipsis_single
type: Title
properties:
content: This is a very long title that should be truncated with an ellipsis
when it overflows the available space in a single line of the container.
level: 4
ellipsis: true
- id: ellipsis_rows_2
type: Title
properties:
content: This is an extremely long title that demonstrates multi-row ellipsis
truncation. When the content exceeds the specified number of rows, it will
be truncated and show an ellipsis indicator at the end of the visible text
area.
level: 5
ellipsis:
rows: 2
- id: ellipsis_expandable
type: Title
properties:
content: This long title can be expanded by clicking the expand control. It
demonstrates how ellipsis with expandable works to let users reveal the
full heading when needed.
level: 5
ellipsis:
rows: 1
expandable: true
- id: ellipsis_suffix
type: Title
properties:
content: This title has a custom suffix appended after the ellipsis truncation
point so readers know more content exists.
level: 4
ellipsis:
rows: 1
suffix: " /Read More"
- id: ellipsis_collapsible
type: Title
properties:
content: This long title can be expanded and collapsed again. The expand and
collapse buttons use custom text set with the symbol option.
level: 5
ellipsis:
rows: 1
expandable: collapsible
symbol:
- more
- less
- id: ellipsis_tooltip
type: Title
properties:
content: Hover this truncated title to see the full heading in a tooltip, which
helps when titles come from user data.
level: 4
ellipsis:
tooltip: true
```
Tailwind Background
Tailwind Left Border
Uppercase Tracking
Inline Border Bottom
Inline Text Shadow
```yaml
- id: css_tailwind_bg
type: Title
class: bg-bg-layout px-4 py-2 rounded-lg
properties:
content: Tailwind Background
level: 4
- id: css_tailwind_border
type: Title
class: border-l-4 border-blue-500 pl-3
properties:
content: Tailwind Left Border
level: 4
- id: css_tailwind_uppercase
type: Title
class: uppercase tracking-widest
properties:
content: Uppercase Tracking
level: 5
- id: css_inline_border_bottom
type: Title
properties:
content: Inline Border Bottom
level: 4
style:
.element:
borderBottom: "2px solid #1677ff"
paddingBottom: 8px
- id: css_inline_shadow
type: Title
properties:
content: Inline Text Shadow
level: 3
color: "#1677ff"
style:
.element:
textShadow: 2px 2px 4px rgba(22, 119, 255, 0.3)
```
Large H4 Title
Light Weight Title
Teal Success Title
Extra Margin Title
```yaml
- id: theme_large_h4
type: Title
properties:
content: Large H4 Title
level: 4
theme:
fontSizeHeading4: 28
- id: theme_light_weight
type: Title
properties:
content: Light Weight Title
level: 3
theme:
fontWeightStrong: 300
- id: theme_custom_success
type: Title
properties:
content: Teal Success Title
level: 4
type: success
theme:
colorSuccess: "#13c2c2"
- id: theme_spacing
type: Title
properties:
content: Extra Margin Title
level: 4
theme:
titleMarginTop: 0
titleMarginBottom: 0
```
Engineering
Building Config-Driven Web Applications
Learn how Lowdefy simplifies complex application development by replacing boilerplate code with declarative YAML configuration.
```yaml
- id: article_card
type: Card
properties:
size: small
blocks:
- id: article_category
type: Title
properties:
content: Engineering
level: 5
type: secondary
- id: article_headline
type: Title
properties:
content: Building Config-Driven Web Applications
level: 2
- id: article_subtitle
type: Paragraph
properties:
content: Learn how Lowdefy simplifies complex application development by
replacing boilerplate code with declarative YAML configuration.
type: secondary
- id: article_meta
type: Box
layout:
gap: 12
blocks:
- id: article_author
type: Button
layout:
flex: 0 0 auto
properties:
title: By Jane Smith
icon: user
color: default
variant: text
size: small
- id: article_date
type: Button
layout:
flex: 0 0 auto
properties:
title: March 12, 2026
icon: calendar
color: default
variant: text
size: small
```
Dashboard Overview
Monitor your application performance and key metrics.
Active Users
12,847
Error Rate
0.12%
Requests / min
3,204
Recent Activity
```yaml
- id: dashboard_header
type: Box
layout:
gap: 0
blocks:
- id: dashboard_title
type: Title
properties:
content: Dashboard Overview
level: 2
- id: dashboard_desc
type: Paragraph
properties:
content: Monitor your application performance and key metrics.
type: secondary
- id: dashboard_cards
type: Box
layout:
gap: 12
blocks:
- id: dashboard_stat_users
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: stat_users_label
type: Title
properties:
content: Active Users
level: 5
type: secondary
- id: stat_users_value
type: Title
properties:
content: 12,847
level: 2
type: success
- id: dashboard_stat_errors
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: stat_errors_label
type: Title
properties:
content: Error Rate
level: 5
type: secondary
- id: stat_errors_value
type: Title
properties:
content: 0.12%
level: 2
type: danger
- id: dashboard_stat_requests
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: stat_requests_label
type: Title
properties:
content: Requests / min
level: 5
type: secondary
- id: stat_requests_value
type: Title
properties:
content: 3,204
level: 2
- id: dashboard_section_title
type: Title
properties:
content: Recent Activity
level: 4
copyable: true
events:
onCopy:
- id: copy_msg
type: DisplayMessage
params:
content: Section title copied.
status: info
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `actions` | object | - | Configure the bar of action buttons, such as copy and expand. |
| `actions.placement` | string | `"end"` | Place the action buttons before or after the text. Enum: `start`, `end`. |
| `code` | boolean | `false` | Apply code style. |
| `color` | string | - | Title color. |
| `content` | string | - | Title text content - supports html. |
| `copyable` | boolean \| object | `false` | Provide copy text button. |
| `copyable.text` | string | - | Paragraph text to copy when clicked. |
| `copyable.icon` | string \| object \| array | - | Copy icon, can be an array or two icons for before and after clicked. |
| `copyable.tooltips` | string \| array | - | Tooltip text, can be an array or two strings for before and after clicked. |
| `delete` | boolean | `false` | Apply deleted (strikethrough) style. |
| `disabled` | boolean | `false` | Apply disabled style. |
| `ellipsis` | boolean \| object | `false` | Display ellipsis when text overflows a single line. |
| `ellipsis.rows` | number | - | Max rows of content. |
| `ellipsis.expandable` | boolean \| string | - | Show a button that expands the hidden content. Set to 'collapsible' to also allow collapsing it again. Enum: `true`, `false`, `collapsible`. |
| `ellipsis.defaultExpanded` | boolean | `false` | Start with the content expanded. |
| `ellipsis.suffix` | string | - | Suffix of ellipses content. |
| `ellipsis.symbol` | string \| array | - | Text of the expand button, or an array of two strings for the expand and collapse buttons. |
| `ellipsis.tooltip` | boolean \| string | - | Show a tooltip when the text is truncated. true shows the full text, a string shows that text. |
| `italic` | boolean | `false` | Apply italic style. |
| `keyboard` | boolean | `false` | Apply keyboard key style. |
| `level` | number | `1` | Set title type. Matches with h1, h2, h3 and h4. Enum: `1`, `2`, `3`, `4`, `5`. |
| `mark` | boolean | `false` | Apply marked (highlighted) style. |
| `type` | string | `"default"` | Additional types. Don't specify for default. Enum: `default`, `secondary`, `warning`, `danger`, `success`. |
| `underline` | boolean | `false` | Apply underline style. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design typography tokens](https://ant.design/components/typography#design-token). |
| `theme.titleMarginBottom` | string \| number | `"0.5em"` | Margin bottom of title, as a CSS length or a number of pixels. |
| `theme.titleMarginTop` | string \| number | `"1.2em"` | Margin top of title, as a CSS length or a number of pixels. |
| `theme.fontSizeHeading1` | number | `38` | Font size of h1 heading. |
| `theme.fontSizeHeading2` | number | `30` | Font size of h2 heading. |
| `theme.fontSizeHeading3` | number | `24` | Font size of h3 heading. |
| `theme.fontSizeHeading4` | number | `20` | Font size of h4 heading. |
| `theme.fontSizeHeading5` | number | `16` | Font size of h5 heading. |
| `theme.lineHeightHeading1` | number | `1.2105` | Line height of h1 heading. |
| `theme.lineHeightHeading2` | number | `1.2667` | Line height of h2 heading. |
| `theme.lineHeightHeading3` | number | `1.3333` | Line height of h3 heading. |
| `theme.lineHeightHeading4` | number | `1.4` | Line height of h4 heading. |
| `theme.lineHeightHeading5` | number | `1.5` | Line height of h5 heading. |
| `theme.fontWeightStrong` | number | `600` | Font weight for strong text. |
| `theme.fontFamilyCode` | string | - | Font family for code style text. |
| `theme.colorText` | string | - | Default text color. |
| `theme.colorTextSecondary` | string | - | Secondary text color. |
| `theme.colorSuccess` | string | - | Success text color. |
| `theme.colorWarning` | string | - | Warning text color. |
| `theme.colorError` | string | - | Danger/error text color. |
| `theme.colorTextDisabled` | string | - | Disabled text color. |
| `theme.colorLink` | string | - | Link color. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onExpand` | `{ expanded }` | Trigger action when the ellipsis expand or collapse button is clicked. |
| `onCopy` | \- | Trigger action when copy text is clicked. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Title element. |
| `/copyableIcon` | The copyable icon in the Title. |
| `/actions` | The bar of action buttons, such as copy and expand, next to the text. |
No slots defined.
---
url: https://docs.lowdefy.com/md/display-blocks/tour.md
---
# Tour
Guided tour with steps, masks, and keyboard navigation.
```yaml
- id: basic_btns_row
type: Box
layout:
gap: 8
blocks:
- id: basic_steps_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: 3 Steps
color: primary
variant: outlined
size: small
events:
onClick:
- id: basic_steps_start
type: SetState
params:
basic_steps_tour_open: true
- id: basic_single_step_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Single Step
color: primary
variant: outlined
size: small
events:
onClick:
- id: basic_single_step_start
type: SetState
params:
basic_single_step_tour_open: true
- id: basic_detailed_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: 5 Steps
color: primary
variant: outlined
size: small
events:
onClick:
- id: basic_detailed_start
type: SetState
params:
basic_detailed_tour_open: true
- id: basic_steps_tour
type: Tour
properties:
open:
_state: basic_steps_tour_open
steps:
- title: Welcome
description: This is the first step of the tour.
- title: Explore Features
description: Discover the key features available in the dashboard.
- title: Get Started
description: You are all set to begin using the application.
events:
onClose:
- id: basic_steps_tour_close
type: SetState
params:
basic_steps_tour_open: false
onFinish:
- id: basic_steps_tour_finish
type: SetState
params:
basic_steps_tour_open: false
- id: basic_single_step_tour
type: Tour
properties:
open:
_state: basic_single_step_tour_open
steps:
- title: Quick Tip
description: A single-step tour works well for brief announcements.
events:
onClose:
- id: basic_single_step_tour_close
type: SetState
params:
basic_single_step_tour_open: false
onFinish:
- id: basic_single_step_tour_finish
type: SetState
params:
basic_single_step_tour_open: false
- id: basic_detailed_tour
type: Tour
properties:
open:
_state: basic_detailed_tour_open
steps:
- title: Step 1 of 5
description: Tours support many steps for longer walkthroughs.
- title: Step 2 of 5
description: Each step can have its own title and description.
- title: Step 3 of 5
description: Users navigate with Next and Previous buttons.
- title: Step 4 of 5
description: Steps are zero-indexed internally.
- title: Step 5 of 5
description: The last step shows a Finish button instead of Next.
events:
onClose:
- id: basic_detailed_tour_close
type: SetState
params:
basic_detailed_tour_open: false
onFinish:
- id: basic_detailed_tour_finish
type: SetState
params:
basic_detailed_tour_open: false
```
```yaml
- id: type_btns_row
type: Box
layout:
gap: 8
blocks:
- id: type_default_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Default
color: primary
variant: outlined
size: small
events:
onClick:
- id: type_default_start
type: SetState
params:
type_default_tour_open: true
- id: type_primary_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Primary
color: primary
variant: outlined
size: small
events:
onClick:
- id: type_primary_start
type: SetState
params:
type_primary_tour_open: true
- id: type_per_step_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Per Step
color: primary
variant: outlined
size: small
events:
onClick:
- id: type_per_step_start
type: SetState
params:
type_per_step_tour_open: true
- id: type_default_tour
type: Tour
properties:
open:
_state: type_default_tour_open
type: default
steps:
- title: Default Type
description: Light background with dark text. Blends naturally with light-themed
interfaces.
- title: Subtle Guidance
description: The default type is understated, ideal for non-intrusive tours.
events:
onClose:
- id: type_default_tour_close
type: SetState
params:
type_default_tour_open: false
onFinish:
- id: type_default_tour_finish
type: SetState
params:
type_default_tour_open: false
- id: type_primary_tour
type: Tour
properties:
open:
_state: type_primary_tour_open
type: primary
steps:
- title: Primary Type
description: Bold colored background using the theme primary color.
- title: High Visibility
description: Primary tours draw attention and suit critical onboarding flows.
events:
onClose:
- id: type_primary_tour_close
type: SetState
params:
type_primary_tour_open: false
onFinish:
- id: type_primary_tour_finish
type: SetState
params:
type_primary_tour_open: false
- id: type_per_step_row
type: Box
layout:
gap: 16
blocks:
- id: type_per_step_btn_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Introduction
color: default
variant: outlined
- id: type_per_step_btn_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Key Feature
color: primary
variant: solid
- id: type_per_step_tour
type: Tour
properties:
open:
_state: type_per_step_tour_open
type: default
steps:
- title: Introduction
description: This step inherits the default type from the tour.
target: type_per_step_btn_1
type: default
- title: Key Feature
description: This step overrides to primary to draw extra attention.
target: type_per_step_btn_2
type: primary
events:
onClose:
- id: type_per_step_tour_close
type: SetState
params:
type_per_step_tour_open: false
onFinish:
- id: type_per_step_tour_finish
type: SetState
params:
type_per_step_tour_open: false
```
```yaml
- id: target_btns_row
type: Box
layout:
gap: 8
blocks:
- id: target_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Button Targets
color: primary
variant: outlined
size: small
events:
onClick:
- id: target_tour_start
type: SetState
params:
target_tour_open: true
- id: target_mixed_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Mixed Targets
color: primary
variant: outlined
size: small
events:
onClick:
- id: target_mixed_tour_start
type: SetState
params:
target_mixed_tour_open: true
- id: target_row
type: Box
layout:
gap: 16
blocks:
- id: target_upload_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Upload
color: primary
variant: solid
icon: upload
- id: target_save_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Save Draft
color: green
variant: outlined
icon: save
- id: target_share_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Share
color: purple
variant: solid
icon: share
- id: target_tour
type: Tour
properties:
open:
_state: target_tour_open
steps:
- title: Upload Files
description: Click here to upload documents or images to the workspace.
target: target_upload_btn
- title: Save Progress
description: Save your current work as a draft to continue later.
target: target_save_btn
- title: Share with Team
description: Share your work with team members via link or invitation.
target: target_share_btn
events:
onClose:
- id: target_tour_close
type: SetState
params:
target_tour_open: false
onFinish:
- id: target_tour_finish
type: SetState
params:
target_tour_open: false
- id: target_mixed_row
type: Box
layout:
gap: 16
align: center
blocks:
- id: target_mixed_input
type: TextInput
layout:
flex: 0 0 240px
properties:
label:
disabled: true
placeholder: Search...
- id: target_mixed_switch
type: Switch
layout:
flex: 0 0 auto
properties:
label:
disabled: true
- id: target_mixed_tour
type: Tour
properties:
open:
_state: target_mixed_tour_open
steps:
- title: Search Bar
description: Use the search bar to quickly find items.
target: target_mixed_input
- title: Toggle Setting
description: Toggle this switch to enable or disable notifications.
target: target_mixed_switch
events:
onClose:
- id: target_mixed_tour_close
type: SetState
params:
target_mixed_tour_open: false
onFinish:
- id: target_mixed_tour_finish
type: SetState
params:
target_mixed_tour_open: false
```
```yaml
- id: placement_btns_row
type: Box
layout:
gap: 8
blocks:
- id: placement_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cardinal
color: primary
variant: outlined
size: small
events:
onClick:
- id: placement_tour_start
type: SetState
params:
placement_tour_open: true
- id: placement_fine_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Fine Placement
color: primary
variant: outlined
size: small
events:
onClick:
- id: placement_fine_start
type: SetState
params:
placement_fine_tour_open: true
- id: placement_level_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Tour-Level
color: primary
variant: outlined
size: small
events:
onClick:
- id: placement_level_start
type: SetState
params:
placement_tour_level_open: true
- id: placement_row
type: Box
layout:
gap: 16
justify: center
blocks:
- id: placement_top_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Top
color: primary
variant: outlined
- id: placement_right_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Right
color: green
variant: outlined
- id: placement_bottom_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Bottom
color: purple
variant: outlined
- id: placement_left_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Left
color: orange
variant: outlined
- id: placement_tour
type: Tour
properties:
open:
_state: placement_tour_open
steps:
- title: Top Placement
description: Guide card appears above the target element.
target: placement_top_btn
placement: top
- title: Right Placement
description: Guide card appears to the right of the target.
target: placement_right_btn
placement: right
- title: Bottom Placement
description: Guide card appears below the target element.
target: placement_bottom_btn
placement: bottom
- title: Left Placement
description: Guide card appears to the left of the target.
target: placement_left_btn
placement: left
events:
onClose:
- id: placement_tour_close
type: SetState
params:
placement_tour_open: false
onFinish:
- id: placement_tour_finish
type: SetState
params:
placement_tour_open: false
- id: placement_fine_tour
type: Tour
properties:
open:
_state: placement_fine_tour_open
steps:
- title: Top Left
description: Aligned to the top-left corner of the target.
placement: topLeft
- title: Bottom Right
description: Aligned to the bottom-right corner of the target.
placement: bottomRight
- title: Right Top
description: On the right side, aligned to the top.
placement: rightTop
events:
onClose:
- id: placement_fine_tour_close
type: SetState
params:
placement_fine_tour_open: false
onFinish:
- id: placement_fine_tour_finish
type: SetState
params:
placement_fine_tour_open: false
- id: placement_tour_level
type: Tour
properties:
open:
_state: placement_tour_level_open
placement: bottom
steps:
- title: Tour-Level Placement
description: Setting placement on the tour applies to all steps by default.
- title: Consistent Position
description: All steps appear below the target unless overridden at the step level.
events:
onClose:
- id: placement_tour_level_close
type: SetState
params:
placement_tour_level_open: false
onFinish:
- id: placement_tour_level_finish
type: SetState
params:
placement_tour_level_open: false
```
```yaml
- id: mask_btns_row
type: Box
layout:
gap: 8
blocks:
- id: mask_enabled_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Mask On
color: primary
variant: outlined
size: small
events:
onClick:
- id: mask_enabled_start
type: SetState
params:
mask_enabled_tour_open: true
- id: mask_disabled_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Mask Off
color: primary
variant: outlined
size: small
events:
onClick:
- id: mask_disabled_start
type: SetState
params:
mask_disabled_tour_open: true
- id: mask_custom_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom Mask
color: primary
variant: outlined
size: small
events:
onClick:
- id: mask_custom_start
type: SetState
params:
mask_custom_tour_open: true
- id: mask_per_step_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Per Step
color: primary
variant: outlined
size: small
events:
onClick:
- id: mask_per_step_start
type: SetState
params:
mask_per_step_tour_open: true
- id: mask_row
type: Box
layout:
gap: 16
blocks:
- id: mask_target_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Masked Target
color: primary
variant: solid
- id: mask_enabled_tour
type: Tour
properties:
open:
_state: mask_enabled_tour_open
mask: true
steps:
- title: Mask Enabled
description: The background is dimmed, drawing focus to the tour card.
target: mask_target_btn
events:
onClose:
- id: mask_enabled_tour_close
type: SetState
params:
mask_enabled_tour_open: false
onFinish:
- id: mask_enabled_tour_finish
type: SetState
params:
mask_enabled_tour_open: false
- id: mask_disabled_tour
type: Tour
properties:
open:
_state: mask_disabled_tour_open
mask: false
steps:
- title: Mask Disabled
description: No overlay is shown. The page remains fully visible and interactive.
events:
onClose:
- id: mask_disabled_tour_close
type: SetState
params:
mask_disabled_tour_open: false
onFinish:
- id: mask_disabled_tour_finish
type: SetState
params:
mask_disabled_tour_open: false
- id: mask_custom_tour
type: Tour
style:
.mask:
boxShadow: "inset 0 0 15px #333"
properties:
open:
_state: mask_custom_tour_open
mask:
color: rgba(80, 0, 130, 0.5)
steps:
- title: Custom Mask
description: A purple-tinted overlay with an inner shadow effect.
target: mask_target_btn
events:
onClose:
- id: mask_custom_tour_close
type: SetState
params:
mask_custom_tour_open: false
onFinish:
- id: mask_custom_tour_finish
type: SetState
params:
mask_custom_tour_open: false
- id: mask_per_step_row
type: Box
layout:
gap: 16
blocks:
- id: mask_per_step_btn_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Masked Step
color: primary
variant: solid
- id: mask_per_step_btn_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Unmasked Step
color: default
variant: outlined
- id: mask_per_step_tour
type: Tour
properties:
open:
_state: mask_per_step_tour_open
mask: true
steps:
- title: Masked
description: This step shows the mask overlay.
target: mask_per_step_btn_1
mask: true
- title: Unmasked
description: This step hides the mask for a clear view.
target: mask_per_step_btn_2
mask: false
events:
onClose:
- id: mask_per_step_tour_close
type: SetState
params:
mask_per_step_tour_open: false
onFinish:
- id: mask_per_step_tour_finish
type: SetState
params:
mask_per_step_tour_open: false
```
```yaml
- id: arrow_btns_row
type: Box
layout:
gap: 8
blocks:
- id: arrow_enabled_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Arrow On
color: primary
variant: outlined
size: small
events:
onClick:
- id: arrow_enabled_start
type: SetState
params:
arrow_enabled_tour_open: true
- id: arrow_disabled_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Arrow Off
color: primary
variant: outlined
size: small
events:
onClick:
- id: arrow_disabled_start
type: SetState
params:
arrow_disabled_tour_open: true
- id: arrow_centered_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Centered
color: primary
variant: outlined
size: small
events:
onClick:
- id: arrow_centered_start
type: SetState
params:
arrow_centered_tour_open: true
- id: arrow_per_step_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Per Step
color: primary
variant: outlined
size: small
events:
onClick:
- id: arrow_per_step_start
type: SetState
params:
arrow_per_step_tour_open: true
- id: arrow_enabled_tour
type: Tour
properties:
open:
_state: arrow_enabled_tour_open
arrow: true
steps:
- title: Arrow Visible
description: An arrow points from the guide card toward the target element.
- title: Visual Connection
description: Arrows help users understand which element the step references.
events:
onClose:
- id: arrow_enabled_tour_close
type: SetState
params:
arrow_enabled_tour_open: false
onFinish:
- id: arrow_enabled_tour_finish
type: SetState
params:
arrow_enabled_tour_open: false
- id: arrow_disabled_tour
type: Tour
properties:
open:
_state: arrow_disabled_tour_open
arrow: false
steps:
- title: No Arrow
description: Without arrows, the guide card appears as a clean floating panel.
events:
onClose:
- id: arrow_disabled_tour_close
type: SetState
params:
arrow_disabled_tour_open: false
onFinish:
- id: arrow_disabled_tour_finish
type: SetState
params:
arrow_disabled_tour_open: false
- id: arrow_centered_tour
type: Tour
properties:
open:
_state: arrow_centered_tour_open
arrow:
pointAtCenter: true
steps:
- title: Centered Arrow
description: The arrow points precisely at the center of the target element.
events:
onClose:
- id: arrow_centered_tour_close
type: SetState
params:
arrow_centered_tour_open: false
onFinish:
- id: arrow_centered_tour_finish
type: SetState
params:
arrow_centered_tour_open: false
- id: arrow_per_step_row
type: Box
layout:
gap: 16
blocks:
- id: arrow_per_step_btn_1
type: Button
layout:
flex: 0 0 auto
properties:
title: With Arrow
color: primary
variant: solid
- id: arrow_per_step_btn_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Centered Arrow
color: green
variant: solid
- id: arrow_per_step_tour
type: Tour
properties:
open:
_state: arrow_per_step_tour_open
steps:
- title: Default Arrow
description: This step shows the default arrow.
target: arrow_per_step_btn_1
arrow: true
- title: Centered Arrow
description: This step points the arrow at the center of the target.
target: arrow_per_step_btn_2
arrow:
pointAtCenter: true
events:
onClose:
- id: arrow_per_step_tour_close
type: SetState
params:
arrow_per_step_tour_open: false
onFinish:
- id: arrow_per_step_tour_finish
type: SetState
params:
arrow_per_step_tour_open: false
```
```yaml
- id: cover_btns_row
type: Box
layout:
gap: 8
blocks:
- id: cover_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cover Tour
color: primary
variant: outlined
size: small
events:
onClick:
- id: cover_tour_start
type: SetState
params:
cover_tour_open: true
- id: cover_target_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: With Targets
color: primary
variant: outlined
size: small
events:
onClick:
- id: cover_target_tour_start
type: SetState
params:
cover_target_tour_open: true
- id: cover_tour
type: Tour
properties:
open:
_state: cover_tour_open
steps:
- title: Welcome to the Dashboard
description: Get familiar with the main interface and its key areas.
cover: https://gw.alipayobjects.com/zos/bmw-prod/e9a9b1e8-5e62-4e12-a3b7-e3695b0a5f3c.png
- title: Navigation Menu
description: Use the sidebar to navigate between different sections.
cover: https://gw.alipayobjects.com/zos/bmw-prod/ed5cf3c4-5e34-43e5-9c39-fe131c7cf88e.png
- title: All Done
description: You are ready to start using the application.
events:
onClose:
- id: cover_tour_close
type: SetState
params:
cover_tour_open: false
onFinish:
- id: cover_tour_finish
type: SetState
params:
cover_tour_open: false
- id: cover_target_row
type: Box
layout:
gap: 16
blocks:
- id: cover_target_btn_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Dashboard
color: primary
variant: solid
icon: Gauge
- id: cover_target_btn_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Settings
color: default
variant: outlined
icon: settings
- id: cover_target_tour
type: Tour
properties:
open:
_state: cover_target_tour_open
steps:
- title: Dashboard Overview
description: The dashboard shows a summary of your workspace activity.
target: cover_target_btn_1
cover: https://gw.alipayobjects.com/zos/bmw-prod/e9a9b1e8-5e62-4e12-a3b7-e3695b0a5f3c.png
- title: Configure Settings
description: Adjust preferences and integrations from the settings page.
target: cover_target_btn_2
cover: https://gw.alipayobjects.com/zos/bmw-prod/ed5cf3c4-5e34-43e5-9c39-fe131c7cf88e.png
events:
onClose:
- id: cover_target_tour_close
type: SetState
params:
cover_target_tour_open: false
onFinish:
- id: cover_target_tour_finish
type: SetState
params:
cover_target_tour_open: false
```
```yaml
- id: closable_btns_row
type: Box
layout:
gap: 8
blocks:
- id: closable_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Closable
color: primary
variant: outlined
size: small
events:
onClick:
- id: closable_tour_start
type: SetState
params:
closable_tour_open: true
- id: not_closable_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Not Closable
color: primary
variant: outlined
size: small
events:
onClick:
- id: not_closable_tour_start
type: SetState
params:
not_closable_tour_open: true
- id: closable_per_step_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Per Step
color: primary
variant: outlined
size: small
events:
onClick:
- id: closable_per_step_start
type: SetState
params:
closable_per_step_tour_open: true
- id: closable_tour
type: Tour
properties:
open:
_state: closable_tour_open
closable: true
keyboard: true
steps:
- title: Closable Tour
description: The close button (X) is visible. Press Escape to close.
- title: Keyboard Navigation
description: Use arrow keys to navigate between steps.
- title: Final Step
description: Both close button and keyboard shortcuts are available throughout.
events:
onClose:
- id: closable_tour_close
type: SetState
params:
closable_tour_open: false
onFinish:
- id: closable_tour_finish
type: SetState
params:
closable_tour_open: false
- id: not_closable_tour
type: Tour
properties:
open:
_state: not_closable_tour_open
closable: false
keyboard: false
steps:
- title: Guided Tour
description: Close button and Escape key are disabled. Use Next and Previous
buttons.
- title: Must Complete
description: Users must step through all steps to finish the tour.
events:
onClose:
- id: not_closable_tour_close
type: SetState
params:
not_closable_tour_open: false
onFinish:
- id: not_closable_tour_finish
type: SetState
params:
not_closable_tour_open: false
- id: closable_per_step_row
type: Box
layout:
gap: 16
blocks:
- id: closable_per_step_btn_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Closable
color: green
variant: outlined
- id: closable_per_step_btn_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Not Closable
color: orange
variant: outlined
- id: closable_per_step_tour
type: Tour
properties:
open:
_state: closable_per_step_tour_open
closable: true
steps:
- title: Closable Step
description: This step has the close button visible.
target: closable_per_step_btn_1
closable: true
- title: Not Closable Step
description: This step hides the close button. Navigate forward to continue.
target: closable_per_step_btn_2
closable: false
events:
onClose:
- id: closable_per_step_tour_close
type: SetState
params:
closable_per_step_tour_open: false
onFinish:
- id: closable_per_step_tour_finish
type: SetState
params:
closable_per_step_tour_open: false
```
```yaml
- id: anim_btns_row
type: Box
layout:
gap: 8
blocks:
- id: animated_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Animated
color: primary
variant: outlined
size: small
events:
onClick:
- id: animated_tour_start
type: SetState
params:
animated_tour_open: true
- id: no_animation_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No Animation
color: primary
variant: outlined
size: small
events:
onClick:
- id: no_animation_tour_start
type: SetState
params:
no_animation_tour_open: true
- id: disabled_interaction_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Disabled Interaction
color: primary
variant: outlined
size: small
events:
onClick:
- id: disabled_interaction_tour_start
type: SetState
params:
disabled_interaction_tour_open: true
- id: animated_tour
type: Tour
properties:
open:
_state: animated_tour_open
animated: true
scrollIntoViewOptions: true
steps:
- title: Animated Tour
description: Smooth transitions between steps with animation enabled.
- title: Auto Scroll
description: Target elements automatically scroll into view when a step activates.
events:
onClose:
- id: animated_tour_close
type: SetState
params:
animated_tour_open: false
onFinish:
- id: animated_tour_finish
type: SetState
params:
animated_tour_open: false
- id: no_animation_tour
type: Tour
properties:
open:
_state: no_animation_tour_open
animated: false
scrollIntoViewOptions: false
steps:
- title: No Animation
description: Instant transitions without animation. Scroll to target is also
disabled.
events:
onClose:
- id: no_animation_tour_close
type: SetState
params:
no_animation_tour_open: false
onFinish:
- id: no_animation_tour_finish
type: SetState
params:
no_animation_tour_open: false
- id: disabled_interaction_row
type: Box
layout:
gap: 16
blocks:
- id: disabled_interaction_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cannot Click During Tour
color: primary
variant: solid
icon: lock
- id: disabled_interaction_tour
type: Tour
properties:
open:
_state: disabled_interaction_tour_open
disabledInteraction: true
steps:
- title: Interaction Disabled
description: The highlighted target element cannot be clicked during this tour.
target: disabled_interaction_btn
- title: Read-Only Tour
description: Users can only navigate tour steps, not interact with highlighted
elements.
events:
onClose:
- id: disabled_interaction_tour_close
type: SetState
params:
disabled_interaction_tour_open: false
onFinish:
- id: disabled_interaction_tour_finish
type: SetState
params:
disabled_interaction_tour_open: false
```
```yaml
- id: gap_btns_row
type: Box
layout:
gap: 8
blocks:
- id: gap_default_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Default Gap
color: primary
variant: outlined
size: small
events:
onClick:
- id: gap_default_tour_start
type: SetState
params:
gap_default_tour_open: true
- id: gap_large_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Large Gap
color: primary
variant: outlined
size: small
events:
onClick:
- id: gap_large_tour_start
type: SetState
params:
gap_large_tour_open: true
- id: gap_tight_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No Gap
color: primary
variant: outlined
size: small
events:
onClick:
- id: gap_tight_tour_start
type: SetState
params:
gap_tight_tour_open: true
- id: current_step_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Start at Step 2
color: primary
variant: outlined
size: small
events:
onClick:
- id: current_step_tour_start
type: SetState
params:
current_step_tour_open: true
- id: gap_row
type: Box
layout:
gap: 16
blocks:
- id: gap_default_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Default Gap
color: primary
variant: solid
- id: gap_large_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Large Gap
color: purple
variant: solid
- id: gap_tight_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No Gap
color: orange
variant: solid
- id: gap_default_tour
type: Tour
properties:
open:
_state: gap_default_tour_open
steps:
- title: Default Gap
description: Standard spacing between the highlighted area and the target.
target: gap_default_btn
events:
onClose:
- id: gap_default_tour_close
type: SetState
params:
gap_default_tour_open: false
onFinish:
- id: gap_default_tour_finish
type: SetState
params:
gap_default_tour_open: false
- id: gap_large_tour
type: Tour
properties:
open:
_state: gap_large_tour_open
gap:
offset: 20
radius: 8
steps:
- title: Large Gap
description: Increased gap (20px) around the target for more breathing room.
target: gap_large_btn
events:
onClose:
- id: gap_large_tour_close
type: SetState
params:
gap_large_tour_open: false
onFinish:
- id: gap_large_tour_finish
type: SetState
params:
gap_large_tour_open: false
- id: gap_tight_tour
type: Tour
properties:
open:
_state: gap_tight_tour_open
gap:
offset: 0
radius: 0
steps:
- title: No Gap
description: The highlight fits tightly around the target with zero spacing.
target: gap_tight_btn
events:
onClose:
- id: gap_tight_tour_close
type: SetState
params:
gap_tight_tour_open: false
onFinish:
- id: gap_tight_tour_finish
type: SetState
params:
gap_tight_tour_open: false
- id: current_step_tour
type: Tour
properties:
open:
_state: current_step_tour_open
current: 1
steps:
- title: Step One
description: This is the first step, but the tour does not start here.
- title: Step Two (Starting Point)
description: The tour opens at this step because current is set to 1 (zero-indexed).
- title: Step Three
description: This is the third and final step.
events:
onClose:
- id: current_step_tour_close
type: SetState
params:
current_step_tour_open: false
onFinish:
- id: current_step_tour_finish
type: SetState
params:
current_step_tour_open: false
```
```yaml
- id: zindex_btns_row
type: Box
layout:
gap: 8
blocks:
- id: zindex_default_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Default (1070)
color: primary
variant: outlined
size: small
events:
onClick:
- id: zindex_default_start
type: SetState
params:
zindex_default_tour_open: true
- id: zindex_high_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: High (2000)
color: primary
variant: outlined
size: small
events:
onClick:
- id: zindex_high_start
type: SetState
params:
zindex_high_tour_open: true
- id: zindex_low_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Low (900)
color: primary
variant: outlined
size: small
events:
onClick:
- id: zindex_low_start
type: SetState
params:
zindex_low_tour_open: true
- id: zindex_default_tour
type: Tour
properties:
open:
_state: zindex_default_tour_open
steps:
- title: Default Z-Index
description: Tour uses the default stacking order (1070). Appears above most
content.
events:
onClose:
- id: zindex_default_tour_close
type: SetState
params:
zindex_default_tour_open: false
onFinish:
- id: zindex_default_tour_finish
type: SetState
params:
zindex_default_tour_open: false
- id: zindex_high_tour
type: Tour
properties:
open:
_state: zindex_high_tour_open
zIndex: 2000
steps:
- title: High Z-Index (2000)
description: Tour renders above other overlays such as modals and drawers.
events:
onClose:
- id: zindex_high_tour_close
type: SetState
params:
zindex_high_tour_open: false
onFinish:
- id: zindex_high_tour_finish
type: SetState
params:
zindex_high_tour_open: false
- id: zindex_low_tour
type: Tour
properties:
open:
_state: zindex_low_tour_open
zIndex: 900
steps:
- title: Low Z-Index (900)
description: Tour renders below some overlays. Fixed headers may appear above it.
events:
onClose:
- id: zindex_low_tour_close
type: SetState
params:
zindex_low_tour_open: false
onFinish:
- id: zindex_low_tour_finish
type: SetState
params:
zindex_low_tour_open: false
```
```yaml
- id: events_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Start Events Tour
color: primary
variant: outlined
size: small
events:
onClick:
- id: events_tour_start
type: SetState
params:
events_tour_open: true
- id: events_row
type: Box
layout:
gap: 16
blocks:
- id: events_btn_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Step 1 Target
color: primary
variant: solid
- id: events_btn_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Step 2 Target
color: green
variant: solid
- id: events_tour
type: Tour
properties:
open:
_state: events_tour_open
steps:
- title: First Step
description: Navigate forward to trigger the onChange event.
target: events_btn_1
- title: Second Step
description: Close the tour or finish to trigger onClose or onFinish.
target: events_btn_2
events:
onChange:
- id: events_on_change
type: DisplayMessage
params:
content: Step changed!
status: info
onClose:
- id: events_tour_close
type: SetState
params:
events_tour_open: false
- id: events_on_close
type: DisplayMessage
params:
content: Tour closed.
status: warning
onFinish:
- id: events_tour_finish
type: SetState
params:
events_tour_open: false
- id: events_on_finish
type: DisplayMessage
params:
content: Tour completed!
status: success
```
```yaml
- id: css_btns_row
type: Box
layout:
gap: 8
blocks:
- id: css_tailwind_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Shadow
color: primary
variant: outlined
size: small
events:
onClick:
- id: css_tailwind_start
type: SetState
params:
css_tailwind_tour_open: true
- id: css_rounded_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Rounded
color: primary
variant: outlined
size: small
events:
onClick:
- id: css_rounded_start
type: SetState
params:
css_rounded_tour_open: true
- id: css_inline_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Inline Style
color: primary
variant: outlined
size: small
events:
onClick:
- id: css_inline_start
type: SetState
params:
css_inline_tour_open: true
- id: css_dark_tour_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Dark Background
color: primary
variant: outlined
size: small
events:
onClick:
- id: css_dark_tour_start
type: SetState
params:
css_dark_tour_open: true
- id: css_tailwind_tour
type: Tour
class: shadow-2xl
properties:
open:
_state: css_tailwind_tour_open
steps:
- title: Tailwind Shadow
description: Tailwind utility classes can be applied via the class property.
events:
onClose:
- id: css_tailwind_tour_close
type: SetState
params:
css_tailwind_tour_open: false
onFinish:
- id: css_tailwind_tour_finish
type: SetState
params:
css_tailwind_tour_open: false
- id: css_rounded_tour
type: Tour
class: rounded-2xl
properties:
open:
_state: css_rounded_tour_open
steps:
- title: Tailwind Rounded
description: Additional border radius applied via Tailwind class.
events:
onClose:
- id: css_rounded_tour_close
type: SetState
params:
css_rounded_tour_open: false
onFinish:
- id: css_rounded_tour_finish
type: SetState
params:
css_rounded_tour_open: false
- id: css_inline_tour
type: Tour
properties:
open:
_state: css_inline_tour_open
steps:
- title: Inline Style
description: The element style key controls the tour card appearance.
style:
.element:
maxWidth: 320px
events:
onClose:
- id: css_inline_tour_close
type: SetState
params:
css_inline_tour_open: false
onFinish:
- id: css_inline_tour_finish
type: SetState
params:
css_inline_tour_open: false
- id: css_dark_bg
type: Box
class: bg-gradient-to-r from-slate-900 to-slate-700 p-4 rounded-lg
layout:
gap: 8
blocks:
- id: css_dark_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Target on Dark Background
ghost: true
color: primary
variant: outlined
- id: css_dark_tour
type: Tour
properties:
open:
_state: css_dark_tour_open
steps:
- title: Dark Background Context
description: Tour cards remain visible against dark page backgrounds.
target: css_dark_btn
events:
onClose:
- id: css_dark_tour_close
type: SetState
params:
css_dark_tour_open: false
onFinish:
- id: css_dark_tour_finish
type: SetState
params:
css_dark_tour_open: false
```
```yaml
- id: theme_btns_row
type: Box
layout:
gap: 8
blocks:
- id: theme_purple_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Purple Primary
color: primary
variant: outlined
size: small
events:
onClick:
- id: theme_purple_start
type: SetState
params:
theme_purple_tour_open: true
- id: theme_rounded_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Rounded Card
color: primary
variant: outlined
size: small
events:
onClick:
- id: theme_rounded_start
type: SetState
params:
theme_rounded_tour_open: true
- id: theme_large_font_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Large Text
color: primary
variant: outlined
size: small
events:
onClick:
- id: theme_large_font_start
type: SetState
params:
theme_large_font_tour_open: true
- id: theme_combined_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Combined
color: primary
variant: outlined
size: small
events:
onClick:
- id: theme_combined_start
type: SetState
params:
theme_combined_tour_open: true
- id: theme_purple_tour
type: Tour
properties:
open:
_state: theme_purple_tour_open
type: primary
theme:
colorPrimary: "#722ed1"
steps:
- title: Purple Primary
description: Custom purple colorPrimary changes background and button colors.
- title: Brand Alignment
description: Theme tokens align the tour with your brand palette.
events:
onClose:
- id: theme_purple_tour_close
type: SetState
params:
theme_purple_tour_open: false
onFinish:
- id: theme_purple_tour_finish
type: SetState
params:
theme_purple_tour_open: false
- id: theme_rounded_tour
type: Tour
properties:
open:
_state: theme_rounded_tour_open
theme:
borderRadiusLG: 20
padding: 24
steps:
- title: Rounded Card
description: Increased border radius (20px) and padding (24px) for a softer look.
events:
onClose:
- id: theme_rounded_tour_close
type: SetState
params:
theme_rounded_tour_open: false
onFinish:
- id: theme_rounded_tour_finish
type: SetState
params:
theme_rounded_tour_open: false
- id: theme_large_font_tour
type: Tour
properties:
open:
_state: theme_large_font_tour_open
theme:
fontSize: 16
fontSizeLG: 20
steps:
- title: Large Text
description: Increased font sizes improve readability and accessibility.
events:
onClose:
- id: theme_large_font_tour_close
type: SetState
params:
theme_large_font_tour_open: false
onFinish:
- id: theme_large_font_tour_finish
type: SetState
params:
theme_large_font_tour_open: false
- id: theme_combined_tour
type: Tour
properties:
open:
_state: theme_combined_tour_open
type: primary
theme:
colorPrimary: "#fa541c"
borderRadiusLG: 12
primaryPrevBtnBg: rgba(255, 255, 255, 0.35)
arrowOffsetHorizontal: 16
steps:
- title: Combined Tokens
description: Multiple tokens create a cohesive warm-themed tour.
- title: Previous Button
description: The primaryPrevBtnBg token makes the Previous button more visible.
events:
onClose:
- id: theme_combined_tour_close
type: SetState
params:
theme_combined_tour_open: false
onFinish:
- id: theme_combined_tour_finish
type: SetState
params:
theme_combined_tour_open: false
```
Welcome to the application. Click the button below to take a guided tour of the interface.
```yaml
- id: onboard_card
type: Card
properties:
title: My Application
size: small
blocks:
- id: onboard_header_row
type: Box
layout:
gap: 16
align: center
blocks:
- id: onboard_search
type: TextInput
layout:
flex: 1 1 auto
properties:
label:
disabled: true
placeholder: Search anything...
- id: onboard_create_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Create New
color: primary
variant: solid
icon: add
- id: onboard_profile_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Profile
color: default
variant: text
icon: user
- id: onboard_settings_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Settings
color: default
variant: text
icon: settings
- id: onboard_content
type: Markdown
properties:
content: >
Welcome to the application. Click the button below to take a guided
tour of the interface.
- id: onboard_start_row
type: Box
layout:
gap: 8
justify: flex-end
blocks:
- id: onboard_start_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Take the Tour
color: primary
variant: solid
icon: help
events:
onClick:
- id: onboard_start_tour
type: SetState
params:
show_onboard_tour: true
- id: onboard_tour
type: Tour
properties:
open:
_state: show_onboard_tour
type: default
mask: true
animated: true
steps:
- title: Welcome
description: Let us take a quick tour to get you started.
cover: https://gw.alipayobjects.com/zos/bmw-prod/e9a9b1e8-5e62-4e12-a3b7-e3695b0a5f3c.png
- title: Search
description: Use the search bar to quickly find documents, users, or settings.
target: onboard_search
placement: bottom
- title: Create Content
description: Click here to create a new document, project, or workspace item.
target: onboard_create_btn
placement: bottom
- title: Your Profile
description: Access your profile to update personal information and preferences.
target: onboard_profile_btn
placement: bottomRight
- title: Settings
description: Configure application settings, integrations, and notifications.
target: onboard_settings_btn
placement: bottomRight
events:
onClose:
- id: onboard_close
type: SetState
params:
show_onboard_tour: false
onFinish:
- id: onboard_finish_state
type: SetState
params:
show_onboard_tour: false
- id: onboard_finish_msg
type: DisplayMessage
params:
content: Tour complete! You are ready to get started.
status: success
```
```yaml
- id: feature_card
type: Card
properties:
title: Document Editor
size: small
blocks:
- id: feature_toolbar
type: Box
layout:
gap: 8
align: center
blocks:
- id: feature_bold_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: default
variant: outlined
size: small
- id: feature_italic_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: I
color: default
variant: outlined
size: small
- id: feature_save_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Save
color: primary
variant: solid
size: small
icon: save
- id: feature_export_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Export
color: default
variant: outlined
size: small
icon: SquareArrowOutUpRight
- id: feature_editor
type: TextArea
properties:
label:
disabled: true
placeholder: Start typing your document here...
rows: 4
- id: feature_actions
type: Box
layout:
gap: 8
justify: flex-end
blocks:
- id: feature_tour_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Learn Editor Features
color: primary
variant: outlined
icon: Lightbulb
events:
onClick:
- id: feature_start_tour
type: SetState
params:
show_feature_tour: true
- id: feature_tour
type: Tour
properties:
open:
_state: show_feature_tour
type: primary
mask: true
animated: true
closable: true
steps:
- title: Formatting Tools
description: Use Bold and Italic buttons to format your text.
target: feature_bold_btn
placement: bottom
type: default
- title: Save Your Work
description: Click Save to store your document. Your work is automatically
backed up every 5 minutes.
target: feature_save_btn
placement: bottom
type: primary
- title: Export Options
description: Export your document as PDF, Word, or plain text for sharing.
target: feature_export_btn
placement: bottom
type: default
events:
onClose:
- id: feature_close
type: SetState
params:
show_feature_tour: false
onFinish:
- id: feature_finish_state
type: SetState
params:
show_feature_tour: false
- id: feature_finish_msg
type: DisplayMessage
params:
content: You are now familiar with the editor features!
status: success
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `animated` | boolean | `true` | Whether to enable animation. |
| `arrow` | boolean \| object | `true` | Whether to show the arrow. |
| `closable` | boolean | `true` | Whether the close button is visible. |
| `current` | integer | - | Current step index. |
| `disabledInteraction` | boolean | `false` | Whether to disable interaction with the page while the tour is active. |
| `gap` | object | - | Gap between the highlighted area and the target element, and its radius. |
| `gap.offset` | number \| array | `6` | Gap in pixels around the target, or a [horizontal, vertical] pair of gaps. |
| `gap.radius` | number | `2` | Border radius of the highlighted area in pixels. |
| `gap.x` | number | - | Horizontal gap offset. Same as the first value of `offset`. |
| `gap.y` | number | - | Vertical gap offset. Same as the second value of `offset`. |
| `keyboard` | boolean | `true` | Whether to enable keyboard navigation. |
| `mask` | boolean \| object | `true` | Whether to enable mask. |
| `open` | boolean | `false` | Whether to show the tour. |
| `placement` | string | `"bottom"` | Position of the guide card relative to the target element: center, left, leftTop, leftBottom, right, rightTop, rightBottom, top, topLeft, topRight, bottom, bottomLeft or bottomRight. |
| `scrollIntoViewOptions` | boolean \| object | `true` | Whether to scroll the step target element into view, or scrollIntoView options such as `{ block: center }`. |
| `steps` | array | - | Tour steps. Each step has title, description, target (blockId string), placement, etc. |
| `steps.$.arrow` | boolean \| object | - | Whether to show the arrow for this step, or object with pointAtCenter. |
| `steps.$.closable` | boolean | - | Whether the close button is visible for this step. |
| `steps.$.cover` | string | - | Cover image URL for the step. |
| `steps.$.description` | string | - | Description of the step. |
| `steps.$.mask` | boolean \| object | - | Whether to enable mask for this step, or object with style and color properties. |
| `steps.$.nextButtonProps` | object | - | Next button settings for this step. |
| `steps.$.nextButtonProps.children` | string | - | Text of the next button, for example "Got it". |
| `steps.$.prevButtonProps` | object | - | Previous button settings for this step. |
| `steps.$.prevButtonProps.children` | string | - | Text of the previous button. |
| `steps.$.placement` | string | - | Position of the guide card relative to the target element. |
| `steps.$.target` | string | - | The blockId of the target element for this step. |
| `steps.$.title` | string | - | Title of the step. |
| `steps.$.type` | string | - | Type style for this step, overrides tour-level type. Enum: `default`, `primary`. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design tour tokens](https://ant.design/components/tour#design-token). |
| `theme.zIndexPopup` | number | `1070` | Z-index of the tour popup. |
| `theme.closeBtnSize` | number | - | Size of the close button. Calculated from fontSize and lineHeight. |
| `theme.primaryPrevBtnBg` | string | `"rgba(255, 255, 255, 0.15)"` | Background color of the previous button in primary type tour. |
| `theme.primaryNextBtnHoverBg` | string | - | Hover background color of the next button in primary type tour. Derived from colorBgTextHover. |
| `theme.arrowOffsetHorizontal` | number | `12` | Horizontal offset of the arrow. |
| `theme.arrowOffsetVertical` | number | `8` | Vertical offset of the arrow. |
| `theme.colorPrimary` | string | - | Primary color override for the tour. |
| `theme.colorBgContainer` | string | - | Background color of the tour card. |
| `theme.colorText` | string | - | Text color in the tour card. |
| `theme.colorTextDescription` | string | - | Description text color in the tour card. |
| `theme.borderRadiusLG` | number | `8` | Border radius of the tour card. |
| `theme.fontSize` | number | `14` | Font size for tour content. |
| `theme.fontSizeLG` | number | `16` | Font size for tour title. |
| `theme.padding` | number | `16` | Padding of the tour card content. |
| `type` | string | `"default"` | Type of the tour. Enum: `default`, `primary`. |
| `zIndex` | integer | - | Z-index of the tour. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onChange` | `{ current }` | Triggered when the current step changes. |
| `onClose` | `{ current }` | Triggered when the tour is closed. |
| `onFinish` | \- | Triggered when the tour is finished. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Tour element. |
| `/mask` | The Tour mask. |
| `/title` | The title of the step card. |
| `/description` | The description of the step card. |
| `/cover` | The cover image area of the step card. |
| `/footer` | The footer of the step card with the indicators and buttons. |
No slots defined.
---
url: https://docs.lowdefy.com/md/container-blocks/alert.md
---
# Alert
Alert banner with type, description, icon, and closable options.
> Operation completed successfully
> This is an informational message
> Please review before proceeding
> An error occurred during processing
```yaml
- id: type_success
type: Alert
properties:
message: Operation completed successfully
type: success
- id: type_info
type: Alert
properties:
message: This is an informational message
type: info
- id: type_warning
type: Alert
properties:
message: Please review before proceeding
type: warning
- id: type_error
type: Alert
properties:
message: An error occurred during processing
type: error
```
> Backup completed
> Two invoices are overdue
```yaml
- id: filled_success
type: Alert
properties:
message: Backup completed
type: success
variant: filled
- id: filled_warning
type: Alert
properties:
message: Two invoices are overdue
description: Send a reminder to the customer or mark the invoices as paid.
type: warning
variant: filled
```
> Payment Received
> Scheduled Maintenance
> Storage Almost Full
> Connection Failed
```yaml
- id: desc_success
type: Alert
properties:
message: Payment Received
description: Your payment of $49.99 has been processed. A confirmation email has
been sent to your inbox.
type: success
- id: desc_info
type: Alert
properties:
message: Scheduled Maintenance
description: The system will undergo maintenance on Saturday from 2:00 AM to
6:00 AM UTC. Please save your work beforehand.
type: info
- id: desc_warning
type: Alert
properties:
message: Storage Almost Full
description: You have used 90% of your available storage. Consider upgrading
your plan or removing unused files.
type: warning
- id: desc_error
type: Alert
properties:
message: Connection Failed
description: Unable to connect to the database server. Please check your network
settings and try again.
type: error
```
> All systems operational
> Your session will expire in 30 minutes
> Unsaved changes will be lost
> Invalid credentials provided
```yaml
- id: msg_only_success
type: Alert
properties:
message: All systems operational
type: success
- id: msg_only_info
type: Alert
properties:
message: Your session will expire in 30 minutes
type: info
- id: msg_only_warning
type: Alert
properties:
message: Unsaved changes will be lost
type: warning
- id: msg_only_error
type: Alert
properties:
message: Invalid credentials provided
type: error
```
> Changes saved
> New version available
> Session expires in 5 minutes
> Request timed out
> Notice
```yaml
- id: noicon_success
type: Alert
properties:
message: Changes saved
type: success
showIcon: false
- id: noicon_info
type: Alert
properties:
message: New version available
type: info
showIcon: false
- id: noicon_warning
type: Alert
properties:
message: Session expires in 5 minutes
type: warning
showIcon: false
- id: noicon_error
type: Alert
properties:
message: Request timed out
type: error
showIcon: false
- id: noicon_desc
type: Alert
properties:
message: Notice
description: This alert has a description but no icon. The showIcon property is
set to false, giving a cleaner text-only appearance.
type: info
showIcon: false
```
> You can dismiss this notification
> Profile updated successfully
> Your trial period ends in 3 days
> Failed to sync data
```yaml
- id: closable_info
type: Alert
properties:
message: You can dismiss this notification
type: info
closable: true
- id: closable_success
type: Alert
properties:
message: Profile updated successfully
type: success
closable: true
- id: closable_warning
type: Alert
properties:
message: Your trial period ends in 3 days
description: Upgrade to a paid plan to keep access to all features.
type: warning
closable: true
- id: closable_error
type: Alert
properties:
message: Failed to sync data
description: The last synchronization attempt failed. Your local changes have
been preserved. Please check your connection and try again.
type: error
closable: true
```
> Your session will expire in 5 minutes
```yaml
- id: close_icon_circle
type: Alert
properties:
message: Your session will expire in 5 minutes
type: warning
closable: true
closeIcon: close-circle
```
> Cookie consent notice
> New features available
> Reminder to complete your profile
> Browser update recommended
```yaml
- id: close_text_dismiss
type: Alert
properties:
message: Cookie consent notice
description: We use cookies to improve your experience. By continuing to use
this site, you agree to our cookie policy.
type: info
closable: true
closeText: Dismiss
- id: close_text_gotit
type: Alert
properties:
message: New features available
description: We have added dark mode support and keyboard shortcuts. Check the
settings page for details.
type: success
closable: true
closeText: Got it
- id: close_text_close
type: Alert
properties:
message: Reminder to complete your profile
type: warning
closable: true
closeText: Close
- id: close_text_later
type: Alert
properties:
message: Browser update recommended
description: You are using an older browser version. Some features may not work
as expected.
type: warning
closable: true
closeText: Later
```
> All tests passed
> You have 3 new notifications
> Your session has been locked for security
> Bug detected in module
> Deployment in progress
> You earned a new achievement
> Custom styled icon
> Security scan complete
```yaml
- id: custom_icon_check
type: Alert
properties:
message: All tests passed
type: success
icon: check-circle
- id: custom_icon_bell
type: Alert
properties:
message: You have 3 new notifications
type: info
icon: bell
- id: custom_icon_lock
type: Alert
properties:
message: Your session has been locked for security
type: warning
icon: lock
- id: custom_icon_bug
type: Alert
properties:
message: Bug detected in module
type: error
icon: Bug
- id: custom_icon_rocket
type: Alert
properties:
message: Deployment in progress
description: Your application is being deployed to the production environment.
This usually takes 2-3 minutes.
type: info
icon: Rocket
- id: custom_icon_star
type: Alert
properties:
message: You earned a new achievement
description: Congratulations on completing your first project!
type: success
icon: star
- id: custom_icon_object
type: Alert
properties:
message: Custom styled icon
type: info
icon:
name: Zap
color: "#faad14"
- id: custom_icon_colored_obj
type: Alert
properties:
message: Security scan complete
description: No vulnerabilities were detected in your dependencies.
type: success
icon:
name: Shield
color: "#52c41a"
```
> Deployment completed successfully across all regions
> Welcome to the new dashboard experience
> Your account requires verification to continue
> Service disruption detected in the EU region
> This banner can be dismissed by the user
> System Update Scheduled
```yaml
- id: banner_success
type: Alert
properties:
message: Deployment completed successfully across all regions
type: success
banner: true
- id: banner_info
type: Alert
properties:
message: Welcome to the new dashboard experience
type: info
banner: true
- id: banner_warning
type: Alert
properties:
message: Your account requires verification to continue
type: warning
banner: true
- id: banner_error
type: Alert
properties:
message: Service disruption detected in the EU region
type: error
banner: true
- id: banner_closable
type: Alert
properties:
message: This banner can be dismissed by the user
type: info
banner: true
closable: true
- id: banner_desc
type: Alert
properties:
message: System Update Scheduled
description: A major update is scheduled for this weekend. All services will be
briefly unavailable during the migration window from 01:00 to 03:00 UTC on
Sunday.
type: warning
banner: true
```
> Important: Your password expires in 7 days
> Click here to learn more about Lowdefy
> Release Notes v4.2.0
> Account Status: Active
> Configuration Error
> Data Migration Complete
```yaml
- id: html_bold_message
type: Alert
properties:
message: Important: Your password expires in 7 days
type: warning
- id: html_link_message
type: Alert
properties:
message: Click here to learn
more about Lowdefy
type: info
- id: html_rich_description
type: Alert
properties:
message: Release Notes v4.2.0
description: New: Dark mode supportFixed: Login
timeout issueImproved: Dashboard loading speed by
40%
type: success
- id: html_styled_message
type: Alert
properties:
message: 'Account Status: Active '
type: info
showIcon: false
- id: html_code_description
type: Alert
properties:
message: Configuration Error
description: The field database.host is required but was not
provided. Please update your .env file and restart the
server.
type: error
- id: html_emphasis_description
type: Alert
properties:
message: Data Migration Complete
description: All 15,432 records have been migrated to the new schema.
No data loss detected. Please verify the results in the
admin panel.
type: success
```
> A new software update is available
> Your subscription is about to expire
> Payment processing failed
> Merge conflict detected
> Export completed
```yaml
- id: action_button_info
type: Alert
properties:
message: A new software update is available
description: Version 2.5.0 includes bug fixes and performance improvements.
type: info
slots:
action:
blocks:
- id: action_button_info_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Update Now
color: primary
variant: solid
size: small
- id: action_button_warning
type: Alert
properties:
message: Your subscription is about to expire
description: Renew before March 15 to keep your current pricing.
type: warning
slots:
action:
blocks:
- id: action_button_warning_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Renew
color: primary
variant: outlined
size: small
- id: action_button_error
type: Alert
properties:
message: Payment processing failed
description: Your credit card was declined. Please update your payment method to
avoid service interruption.
type: error
slots:
action:
blocks:
- id: action_button_error_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Update Payment
color: danger
variant: solid
size: small
- id: action_multiple_buttons
type: Alert
properties:
message: Merge conflict detected
description: The branch feature/auth has conflicts with main that need to be
resolved manually.
type: warning
slots:
action:
blocks:
- id: action_multi_row
type: Box
layout:
gap: 8
blocks:
- id: action_multi_resolve
type: Button
layout:
flex: 0 0 auto
properties:
title: Resolve
color: primary
variant: solid
size: small
- id: action_multi_dismiss
type: Button
layout:
flex: 0 0 auto
properties:
title: Dismiss
color: default
variant: outlined
size: small
- id: action_link_success
type: Alert
properties:
message: Export completed
description: Your data export is ready for download.
type: success
slots:
action:
blocks:
- id: action_link_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Download
icon: download
color: green
variant: solid
size: small
```
> Backup Completed
> API Rate Limit Warning
> Critical Security Alert
> Welcome to the beta program! We appreciate your feedback.
> Terms of Service Updated
```yaml
- id: combo_full_success
type: Alert
properties:
message: Backup Completed
description: All 248 files have been backed up to cloud storage. Total size 1.2 GB.
type: success
closable: true
closeText: OK
icon: CloudUpload
- id: combo_full_warning
type: Alert
properties:
message: API Rate Limit Warning
description: You have used 85% of your daily API quota (8,500 / 10,000
requests). Consider implementing request caching.
type: warning
closable: true
icon: Plug
- id: combo_full_error
type: Alert
properties:
message: Critical Security Alert
description: Unauthorized access attempt detected from IP
192.168.1.45 at 14:32 UTC. The account has been temporarily
locked.
type: error
closable: true
icon: warning
- id: combo_banner_closable_icon
type: Alert
properties:
message: Welcome to the beta program! We appreciate your feedback.
type: info
banner: true
closable: true
icon: FlaskConical
- id: combo_noicon_closable_desc
type: Alert
properties:
message: Terms of Service Updated
description: Our terms of service have been updated effective March 1, 2026. By
continuing to use the platform, you agree to the new terms.
type: info
showIcon: false
closable: true
closeText: I Agree
```
> Rounded with shadow
> Left border accent
> Elevated success
> Alert on dark background
> Warning on dark background
> Compact alert with smaller text
> Wider border radius
```yaml
- id: css_rounded
type: Alert
class: rounded-xl shadow-md
properties:
message: Rounded with shadow
description: This alert uses Tailwind classes for rounded corners and a shadow effect.
type: info
- id: css_border_accent
type: Alert
class: border-l-4 border-l-blue-500
properties:
message: Left border accent
description: A thicker left border creates a visual accent effect, drawing
attention to the alert content.
type: info
showIcon: false
- id: css_shadow_success
type: Alert
class: shadow-lg rounded-lg
properties:
message: Elevated success
description: Shadow and border radius create a card-like elevated appearance for
this success alert.
type: success
- id: css_dark_bg
type: Box
class: bg-bg-layout p-6 rounded-xl
blocks:
- id: css_on_dark_info
type: Alert
class: shadow-xl
properties:
message: Alert on dark background
description: Alerts with shadows stand out well against darker container
backgrounds.
type: info
- id: css_on_dark_warning
type: Alert
class: shadow-xl
properties:
message: Warning on dark background
type: warning
- id: css_compact
type: Alert
class: text-xs
properties:
message: Compact alert with smaller text
type: info
showIcon: false
- id: css_wide_border
type: Alert
class: border-2 rounded-2xl
properties:
message: Wider border radius
description: Extra border width and larger radius for a softer appearance.
type: success
```
> Large border radius
> Larger font size
> Extra padding
> Sharp corners (no radius)
> Larger description icon
> Fully customized alert
```yaml
- id: theme_custom_radius
type: Alert
properties:
message: Large border radius
description: This alert uses a 16px border radius override via the theme property.
type: info
theme:
borderRadius: 16
- id: theme_custom_font
type: Alert
properties:
message: Larger font size
description: The base font size is increased to 16px for improved readability.
type: success
theme:
fontSize: 16
- id: theme_custom_padding
type: Alert
properties:
message: Extra padding
description: Custom padding makes the alert feel more spacious and prominent on
the page.
type: warning
theme:
defaultPadding: 16px 24px
withDescriptionPadding: 28px 32px
- id: theme_no_radius
type: Alert
properties:
message: Sharp corners (no radius)
description: Setting borderRadius to 0 creates a sharp-edged industrial look.
type: info
theme:
borderRadius: 0
- id: theme_large_icon
type: Alert
properties:
message: Larger description icon
description: The icon size for alerts with descriptions is increased to 32px,
making it more prominent.
type: success
theme:
withDescriptionIconSize: 32
- id: theme_combined
type: Alert
properties:
message: Fully customized alert
description: This alert combines multiple theme token overrides including
padding, radius, font size, and icon size for a completely custom
appearance.
type: info
theme:
borderRadius: 12
fontSize: 15
withDescriptionPadding: 24px 28px
withDescriptionIconSize: 28
```
> Please fix the following errors
> Welcome to your workspace!
> API v1 Deprecation Notice
> Scheduled Downtime
> Deployment Successful
> Resource Quota Warning
> Access Denied
> Beta Feature Enabled
```yaml
- id: real_form_validation
type: Alert
properties:
message: Please fix the following errors
description: Email address is required Password must be at least
8 characters Please agree to the terms of service
type: error
icon: CircleAlert
- id: real_onboarding
type: Alert
properties:
message: Welcome to your workspace!
description: Get started by creating your first project. You can invite team
members from the Settings page.
type: info
closable: true
icon: FaceSlightlySmiling
slots:
action:
blocks:
- id: real_onboarding_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Create Project
color: primary
variant: solid
size: small
icon: add
- id: real_deprecation
type: Alert
properties:
message: API v1 Deprecation Notice
description: API v1 will be sunset on June 30, 2026 . Please migrate to
API v2 before this date. See the migration guide for
instructions.
type: warning
closable: true
closeText: Acknowledged
icon: clock
- id: real_maintenance
type: Alert
properties:
message: Scheduled Downtime
description: Services will be unavailable on Sunday, March 15 from 02:00 to
04:00 UTC for database migration. No action is required on your part.
type: info
banner: true
closable: true
- id: real_success_deploy
type: Alert
properties:
message: Deployment Successful
description: "Application my-app has been deployed to
production environment. Build #1847 completed in 2m 34s."
type: success
icon: check-circle
slots:
action:
blocks:
- id: real_deploy_actions
type: Box
layout:
gap: 8
blocks:
- id: real_deploy_view
type: Button
layout:
flex: 0 0 auto
properties:
title: View Logs
color: default
variant: outlined
size: small
- id: real_deploy_open
type: Button
layout:
flex: 0 0 auto
properties:
title: Open App
color: green
variant: solid
size: small
icon: link
- id: real_quota_warning
type: Alert
properties:
message: Resource Quota Warning
description: "Your project has used 92% of allocated compute resources.
Current usage: 18.4 / 20 vCPUs. Consider scaling your plan or optimizing
workloads."
type: warning
icon: Gauge
slots:
action:
blocks:
- id: real_quota_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Upgrade Plan
color: primary
variant: solid
size: small
- id: real_permission_error
type: Alert
properties:
message: Access Denied
description: You do not have permission to view this resource. Contact your
administrator to request access to the Analytics dashboard.
type: error
icon: Ban
closable: true
- id: real_feature_flag
type: Alert
properties:
message: Beta Feature Enabled
description: You are using an experimental feature. Some functionality may be
unstable. Please report any issues you encounter.
type: info
closable: true
closeText: Understood
icon: FlaskConical
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `banner` | boolean | `false` | Style as banner at top of application window. |
| `closable` | boolean | `false` | Allow alert to be closed. |
| `closeIcon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize the close icon of a closable alert. |
| `closeIcon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `closeIcon.color` | string | - | Icon color. |
| `closeIcon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `closeIcon.rotate` | number | - | Number of degrees to rotate the icon. |
| `closeIcon.spin` | boolean | - | Continuously spin the icon with animation. |
| `closeIcon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `closeIcon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `closeIcon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `closeIcon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `closeText` | string | - | Close text to show instead of the close icon. Makes the alert closable. |
| `description` | string | - | Content description of alert - supports html. |
| `icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize alert icon. |
| `icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `icon.color` | string | - | Icon color. |
| `icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `message` | string | - | Content message of alert - supports html. |
| `showIcon` | boolean | `true` | Show type default icon. |
| `type` | string | `"info"` | Alert style type. Enum: `success`, `info`, `warning`, `error`. |
| `variant` | string | `"outlined"` | Alert style variant. `filled` hides the border and keeps the background tint. Enum: `outlined`, `filled`. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design alert tokens](https://ant.design/components/alert#design-token). |
| `theme.defaultPadding` | string | `"8px 12px"` | Default padding for the alert without description. |
| `theme.withDescriptionPadding` | string | `"20px 24px"` | Padding for the alert when a description is present. |
| `theme.withDescriptionIconSize` | number | `24` | Icon size when the alert has a description. |
| `theme.colorText` | string | - | Text color of the alert message. |
| `theme.colorTextHeading` | string | - | Heading text color when the alert has a description. |
| `theme.colorIcon` | string | - | Icon color override. |
| `theme.colorIconHover` | string | - | Icon hover color for the close button. |
| `theme.fontSize` | number | `14` | Font size of the alert text. |
| `theme.fontSizeLG` | number | `16` | Font size of the alert message when a description is present. |
| `theme.lineHeight` | number | `1.5714` | Line height of the alert text. |
| `theme.borderRadius` | number | `8` | Border radius of the alert container. |
| `theme.borderRadiusLG` | number | `8` | Border radius for large alerts. |
| `theme.colorSuccessBg` | string | - | Background color for success alerts. |
| `theme.colorSuccessBorder` | string | - | Border color for success alerts. |
| `theme.colorInfoBg` | string | - | Background color for info alerts. |
| `theme.colorInfoBorder` | string | - | Border color for info alerts. |
| `theme.colorWarningBg` | string | - | Background color for warning alerts. |
| `theme.colorWarningBorder` | string | - | Border color for warning alerts. |
| `theme.colorErrorBg` | string | - | Background color for error alerts. |
| `theme.colorErrorBorder` | string | - | Border color for error alerts. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onClose` | \- | Called when Alert close button is clicked. |
| `afterClose` | \- | Called after Alert has been closed. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Alert element. |
| `/icon` | The icon in the Alert. |
| `/message` | The Alert message. |
| `/description` | The Alert description. |
| `/action` | The Alert action. |
| `/closeIcon` | The Alert close icon. |
| Slot | Description |
| --- | --- |
| `action` | Action area content. |
---
url: https://docs.lowdefy.com/md/container-blocks/affix.md
---
# Affix
An Affix block makes its content stick to the viewport when scrolling.
```yaml
- id: affix_basic_top
type: Affix
properties:
offsetTop: 10
blocks:
- id: affix_basic_top_btn
type: Button
properties:
title: Affix Top (10px)
color: primary
variant: solid
```
```yaml
- id: affix_offset_top_0
type: Affix
layout:
flex: 0 0 auto
properties:
offsetTop: 0
blocks:
- id: affix_offset_top_0_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Offset 0px
color: primary
variant: solid
size: small
- id: affix_offset_top_20
type: Affix
layout:
flex: 0 0 auto
properties:
offsetTop: 20
blocks:
- id: affix_offset_top_20_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Offset 20px
color: primary
variant: outlined
size: small
- id: affix_offset_top_80
type: Affix
layout:
flex: 0 0 auto
properties:
offsetTop: 80
blocks:
- id: affix_offset_top_80_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Offset 80px
color: primary
variant: dashed
size: small
```
Scroll this panel. The toolbar sticks to the top of the panel instead of the page, because `target` names the panel's id. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
```yaml
- id: affix_panel
type: Box
class:
.element: h-48 overflow-y-auto rounded border border-gray-200 p-3
blocks:
- id: affix_panel_toolbar
type: Affix
properties:
offsetTop: 0
target: affix_panel
blocks:
- id: affix_panel_toolbar_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Save changes
icon: save
size: small
- id: affix_panel_text
type: Paragraph
properties:
content: Scroll this panel. The toolbar sticks to the top of the panel instead
of the page, because `target` names the panel's id. Lorem ipsum dolor
sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
```
```yaml
- id: affix_offset_bottom_0
type: Affix
layout:
flex: 0 0 auto
properties:
offsetBottom: 0
blocks:
- id: affix_offset_bottom_0_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Bottom 0px
color: primary
variant: solid
size: small
- id: affix_offset_bottom_30
type: Affix
layout:
flex: 0 0 auto
properties:
offsetBottom: 30
blocks:
- id: affix_offset_bottom_30_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Bottom 30px
color: primary
variant: outlined
size: small
- id: affix_offset_bottom_60
type: Affix
layout:
flex: 0 0 auto
properties:
offsetBottom: 60
blocks:
- id: affix_offset_bottom_60_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Bottom 60px
color: primary
variant: dashed
size: small
```
```yaml
- id: affix_on_change
type: Affix
properties:
offsetTop: 10
events:
onChange:
- id: affix_on_change_message
type: DisplayMessage
params:
content:
_if:
test:
_eq:
- _event: affixed
- true
then: Affix is now fixed to the viewport.
else: Affix returned to its original position.
duration: 3
blocks:
- id: affix_on_change_btn
type: Button
properties:
title: Scroll to trigger onChange
color: primary
variant: solid
```
```yaml
- id: affix_theme_default_z
type: Affix
layout:
flex: 0 0 auto
properties:
offsetTop: 10
theme:
zIndexPopup: 10
blocks:
- id: affix_theme_default_z_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Default z-index (10)
color: default
variant: outlined
size: small
- id: affix_theme_high_z
type: Affix
layout:
flex: 0 0 auto
properties:
offsetTop: 10
theme:
zIndexPopup: 100
blocks:
- id: affix_theme_high_z_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: High z-index (100)
color: primary
variant: solid
size: small
- id: affix_theme_low_z
type: Affix
layout:
flex: 0 0 auto
properties:
offsetTop: 10
theme:
zIndexPopup: 1
blocks:
- id: affix_theme_low_z_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Low z-index (1)
color: default
variant: dashed
size: small
```
```yaml
- id: affix_css_shadow
type: Affix
layout:
flex: 0 0 auto
class:
.element: shadow-lg rounded-lg
properties:
offsetTop: 10
blocks:
- id: affix_css_shadow_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Shadow + Rounded
color: primary
variant: solid
size: small
- id: affix_css_ring
type: Affix
layout:
flex: 0 0 auto
class:
.element: ring-2 ring-green-400 rounded-lg
properties:
offsetTop: 10
blocks:
- id: affix_css_ring_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Ring Border
color: default
variant: outlined
size: small
```
```yaml
- id: affix_style_zindex
type: Affix
properties:
offsetTop: 10
style:
.element:
zIndex: 200
boxShadow: 0 4px 12px rgba(0, 0, 0, 0.15)
blocks:
- id: affix_style_zindex_btn
type: Button
properties:
title: Custom z-index (200) + Shadow
color: primary
variant: solid
```
Edit Employee Record
```yaml
- id: affix_form_toolbar
type: Affix
properties:
offsetTop: 0
blocks:
- id: affix_form_toolbar_card
type: Card
properties:
size: small
bordered: true
blocks:
- id: affix_form_toolbar_row
type: Box
layout:
gap: 8
justify: space-between
align: center
blocks:
- id: affix_form_toolbar_title
type: Title
layout:
flex: 0 0 auto
properties:
content: Edit Employee Record
level: 5
- id: affix_form_toolbar_actions
type: Box
layout:
flex: 0 0 auto
gap: 8
blocks:
- id: affix_form_toolbar_discard
type: Button
layout:
flex: 0 0 auto
properties:
title: Discard
color: default
variant: outlined
size: small
events:
onClick:
- id: affix_form_toolbar_discard_msg
type: DisplayMessage
params:
content: Changes discarded.
status: warning
- id: affix_form_toolbar_save
type: Button
layout:
flex: 0 0 auto
properties:
title: Save Changes
icon: save
color: primary
variant: solid
size: small
events:
onClick:
- id: affix_form_toolbar_save_msg
type: DisplayMessage
params:
content: Employee record saved successfully.
status: success
```
3 items selected
```yaml
- id: affix_bottom_bar
type: Affix
properties:
offsetBottom: 0
blocks:
- id: affix_bottom_bar_card
type: Card
class: shadow-lg
properties:
size: small
blocks:
- id: affix_bottom_bar_row
type: Box
layout:
gap: 12
justify: flex-end
align: center
blocks:
- id: affix_bottom_bar_status
type: Paragraph
layout:
flex: 1 1 0
properties:
content: 3 items selected
- id: affix_bottom_bar_delete
type: Button
layout:
flex: 0 0 auto
properties:
title: Delete
icon: delete
color: danger
variant: outlined
size: small
events:
onClick:
- id: affix_bottom_bar_delete_msg
type: DisplayMessage
params:
content: Items deleted.
status: error
- id: affix_bottom_bar_export
type: Button
layout:
flex: 0 0 auto
properties:
title: Export
icon: download
color: primary
variant: solid
size: small
events:
onClick:
- id: affix_bottom_bar_export_msg
type: DisplayMessage
params:
content: Export started.
status: success
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `offsetBottom` | number | - | Offset from the bottom of the viewport (in pixels). |
| `offsetTop` | number | `0` | Offset from the top of the viewport (in pixels). |
| `target` | string | - | Id of the scrollable element the content sticks to, for example a scrolling panel. Defaults to the page window. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design affix tokens](https://ant.design/components/affix#design-token). |
| `theme.zIndexPopup` | number | `10` | Z-index of the affix element when fixed. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onChange` | `{ affixed }` | Triggered when container affix status changes. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Affix element. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks wrapped by the Affix. |
---
url: https://docs.lowdefy.com/md/container-blocks/badge.md
---
# Badge
Badge with count, dot, status, color, and overflow.
U
U
U
```yaml
- id: basic_count_5
type: Badge
layout:
flex: 0 0 auto
properties:
count: 5
blocks:
- id: basic_count_5_child
type: Avatar
properties:
shape: square
content: U
- id: basic_count_25
type: Badge
layout:
flex: 0 0 auto
properties:
count: 25
blocks:
- id: basic_count_25_child
type: Avatar
properties:
shape: square
content: U
- id: basic_count_100
type: Badge
layout:
flex: 0 0 auto
properties:
count: 100
blocks:
- id: basic_count_100_child
type: Avatar
properties:
shape: square
content: U
```
U
U
```yaml
- id: zero_hidden
type: Badge
layout:
flex: 0 0 auto
properties:
count: 0
blocks:
- id: zero_hidden_child
type: Avatar
properties:
shape: square
content: U
- id: zero_shown
type: Badge
layout:
flex: 0 0 auto
properties:
count: 0
showZero: true
blocks:
- id: zero_shown_child
type: Avatar
properties:
shape: square
content: U
```
U
```yaml
- id: dot_on_avatar
type: Badge
layout:
flex: 0 0 auto
properties:
dot: true
blocks:
- id: dot_on_avatar_child
type: Avatar
properties:
shape: square
content: U
- id: dot_on_icon_avatar
type: Badge
layout:
flex: 0 0 auto
properties:
dot: true
blocks:
- id: dot_on_icon_avatar_child
type: Avatar
properties:
icon: bell
shape: square
- id: dot_on_button
type: Badge
layout:
flex: 0 0 auto
properties:
dot: true
blocks:
- id: dot_on_button_child
type: Button
properties:
title: Notifications
color: primary
variant: outlined
```
```yaml
- id: standalone_count
type: Badge
layout:
flex: 0 0 auto
properties:
count: 25
- id: standalone_dot
type: Badge
layout:
flex: 0 0 auto
properties:
dot: true
- id: standalone_text
type: Badge
layout:
flex: 0 0 auto
properties:
count: New
```
U
U
U
U
```yaml
- id: size_def
type: Badge
layout:
flex: 0 0 auto
properties:
count: 11
size: default
blocks:
- id: size_def_child
type: Avatar
properties:
shape: square
content: U
- id: size_sm
type: Badge
layout:
flex: 0 0 auto
properties:
count: 11
size: small
blocks:
- id: size_sm_child
type: Avatar
properties:
shape: square
content: U
- id: size_def_large_count
type: Badge
layout:
flex: 0 0 auto
properties:
count: 999
overflowCount: 999
size: default
blocks:
- id: size_def_large_count_child
type: Avatar
properties:
shape: square
content: U
- id: size_sm_large_count
type: Badge
layout:
flex: 0 0 auto
properties:
count: 999
overflowCount: 999
size: small
blocks:
- id: size_sm_large_count_child
type: Avatar
properties:
shape: square
content: U
```
U
U
U
```yaml
- id: overflow_default
type: Badge
layout:
flex: 0 0 auto
properties:
count: 150
blocks:
- id: overflow_default_child
type: Avatar
properties:
shape: square
content: U
- id: overflow_10
type: Badge
layout:
flex: 0 0 auto
properties:
count: 150
overflowCount: 10
blocks:
- id: overflow_10_child
type: Avatar
properties:
shape: square
content: U
- id: overflow_999
type: Badge
layout:
flex: 0 0 auto
properties:
count: 2000
overflowCount: 999
blocks:
- id: overflow_999_child
type: Avatar
properties:
shape: square
content: U
```
A
B
C
D
```yaml
- id: preset_blue
type: Badge
layout:
flex: 0 0 auto
properties:
color: blue
count: 5
blocks:
- id: preset_blue_child
type: Avatar
properties:
shape: square
content: A
- id: preset_green
type: Badge
layout:
flex: 0 0 auto
properties:
color: green
count: 5
blocks:
- id: preset_green_child
type: Avatar
properties:
shape: square
content: B
- id: preset_purple
type: Badge
layout:
flex: 0 0 auto
properties:
color: purple
count: 5
blocks:
- id: preset_purple_child
type: Avatar
properties:
shape: square
content: C
- id: preset_gold
type: Badge
layout:
flex: 0 0 auto
properties:
color: gold
count: 5
blocks:
- id: preset_gold_child
type: Avatar
properties:
shape: square
content: D
```
A
B
C
```yaml
- id: hex_coral
type: Badge
layout:
flex: 0 0 auto
properties:
color: "#ff6b6b"
count: 3
blocks:
- id: hex_coral_child
type: Avatar
properties:
shape: square
content: A
- id: hex_teal
type: Badge
layout:
flex: 0 0 auto
properties:
color: "#20c997"
count: 7
blocks:
- id: hex_teal_child
type: Avatar
properties:
shape: square
content: B
- id: hex_indigo
type: Badge
layout:
flex: 0 0 auto
properties:
color: "#4c6ef5"
count: 12
blocks:
- id: hex_indigo_child
type: Avatar
properties:
shape: square
content: C
```
U
U
U
```yaml
- id: text_new
type: Badge
layout:
flex: 0 0 auto
properties:
count: New
blocks:
- id: text_new_child
type: Avatar
properties:
shape: square
content: U
- id: text_hot
type: Badge
layout:
flex: 0 0 auto
properties:
count: Hot
color: red
blocks:
- id: text_hot_child
type: Avatar
properties:
shape: square
content: U
- id: text_beta
type: Badge
layout:
flex: 0 0 auto
properties:
count: Beta
color: blue
blocks:
- id: text_beta_child
type: Avatar
properties:
shape: square
content: U
```
```yaml
- id: status_success
type: Badge
layout:
flex: 0 0 auto
properties:
status: success
text: Success
- id: status_processing
type: Badge
layout:
flex: 0 0 auto
properties:
status: processing
text: Processing
- id: status_default
type: Badge
layout:
flex: 0 0 auto
properties:
status: default
text: Default
- id: status_error
type: Badge
layout:
flex: 0 0 auto
properties:
status: error
text: Error
- id: status_warning
type: Badge
layout:
flex: 0 0 auto
properties:
status: warning
text: Warning
```
```yaml
- id: status_dot_success
type: Badge
layout:
flex: 0 0 auto
properties:
status: success
- id: status_dot_processing
type: Badge
layout:
flex: 0 0 auto
properties:
status: processing
- id: status_dot_error
type: Badge
layout:
flex: 0 0 auto
properties:
status: error
```
U
U
U
```yaml
- id: icon_bell
type: Badge
layout:
flex: 0 0 auto
properties:
icon: bell
blocks:
- id: icon_bell_child
type: Avatar
properties:
shape: square
content: U
- id: icon_clock
type: Badge
layout:
flex: 0 0 auto
properties:
icon:
name: clock
color: "#1677ff"
blocks:
- id: icon_clock_child
type: Avatar
properties:
shape: square
content: U
- id: icon_exclamation
type: Badge
layout:
flex: 0 0 auto
properties:
icon:
name: CircleAlert
color: "#faad14"
blocks:
- id: icon_exclamation_child
type: Avatar
properties:
shape: square
content: U
```
U
U
U
```yaml
- id: offset_none
type: Badge
layout:
flex: 0 0 auto
properties:
count: 5
blocks:
- id: offset_none_child
type: Avatar
properties:
shape: square
content: U
- id: offset_right
type: Badge
layout:
flex: 0 0 auto
properties:
count: 5
offset:
- 10
- 0
blocks:
- id: offset_right_child
type: Avatar
properties:
shape: square
content: U
- id: offset_both
type: Badge
layout:
flex: 0 0 auto
properties:
count: 5
offset:
- -5
- 10
blocks:
- id: offset_both_child
type: Avatar
properties:
shape: square
content: U
```
U
N
```yaml
- id: title_tooltip
type: Badge
layout:
flex: 0 0 auto
properties:
count: 5
title: You have 5 unread messages
blocks:
- id: title_tooltip_child
type: Avatar
properties:
shape: square
content: U
- id: title_tooltip_custom
type: Badge
layout:
flex: 0 0 auto
properties:
count: 99
title: 99 pending tasks
blocks:
- id: title_tooltip_custom_child
type: Avatar
properties:
shape: square
icon: user
- id: title_tooltip_off
type: Badge
layout:
flex: 0 0 auto
properties:
count: 3
title: false
blocks:
- id: title_tooltip_off_child
type: Avatar
properties:
shape: square
content: N
```
JD
```yaml
- id: wrap_avatar_circle
type: Badge
layout:
flex: 0 0 auto
properties:
count: 3
blocks:
- id: wrap_avatar_circle_child
type: Avatar
properties:
content: JD
color: "#1677ff"
- id: wrap_button_solid
type: Badge
layout:
flex: 0 0 auto
properties:
count: 5
blocks:
- id: wrap_button_solid_child
type: Button
properties:
title: Messages
color: primary
variant: solid
- id: wrap_icon_bell
type: Badge
layout:
flex: 0 0 auto
properties:
count: 12
blocks:
- id: wrap_icon_bell_child
type: Icon
properties:
name: bell
size: 24
- id: wrap_icon_mail
type: Badge
layout:
flex: 0 0 auto
properties:
dot: true
blocks:
- id: wrap_icon_mail_child
type: Icon
properties:
name: mail
size: 24
```
Up to 20 members, shared workspaces and priority support.
Pay yearly and save on every seat.
```yaml
- id: ribbon_row
type: Box
layout:
gap: 24
blocks:
- id: ribbon_recommended
type: Badge
layout:
span: 12
properties:
ribbon:
text: Recommended
blocks:
- id: ribbon_recommended_card
type: Card
properties:
title: Team plan
blocks:
- id: ribbon_recommended_text
type: Paragraph
properties:
content: Up to 20 members, shared workspaces and priority support.
- id: ribbon_sale
type: Badge
layout:
span: 12
properties:
ribbon:
text: 20% off
color: volcano
placement: start
blocks:
- id: ribbon_sale_card
type: Card
properties:
title: Annual billing
blocks:
- id: ribbon_sale_text
type: Paragraph
properties:
content: Pay yearly and save on every seat.
```
U
U
U
```yaml
- id: css_indicator_shadow
type: Badge
layout:
flex: 0 0 auto
properties:
count: 5
style:
.indicator:
boxShadow: "0 0 0 2px #1677ff"
blocks:
- id: css_indicator_shadow_child
type: Avatar
properties:
shape: square
content: U
- id: css_indicator_green
type: Badge
layout:
flex: 0 0 auto
properties:
count: 5
style:
.indicator:
backgroundColor: "#52c41a"
blocks:
- id: css_indicator_green_child
type: Avatar
properties:
shape: square
content: U
- id: css_indicator_bold
type: Badge
layout:
flex: 0 0 auto
properties:
count: 42
style:
.indicator:
fontWeight: bold
fontSize: 14px
blocks:
- id: css_indicator_bold_child
type: Avatar
properties:
shape: square
content: U
size: large
```
A
B
Inbox
```yaml
- id: tw_element_margin
type: Badge
class:
.element: mr-8
layout:
flex: 0 0 auto
properties:
count: 3
blocks:
- id: tw_element_margin_child
type: Avatar
properties:
shape: square
content: A
- id: tw_indicator_animate
type: Badge
class:
.indicator: animate-bounce
layout:
flex: 0 0 auto
properties:
count: 7
blocks:
- id: tw_indicator_animate_child
type: Avatar
properties:
shape: square
content: B
- id: tw_badge_in_box
type: Badge
class:
.element: p-1
layout:
flex: 0 0 auto
properties:
count: 3
blocks:
- id: tw_badge_in_box_child
type: Box
class: bg-bg-layout rounded-lg p-4
blocks:
- id: tw_badge_in_box_text
type: Paragraph
properties:
content: Inbox
```
U
U
U
U
U
```yaml
- id: theme_large_indicator
type: Badge
layout:
flex: 0 0 auto
properties:
count: 8
theme:
indicatorHeight: 28
textFontSize: 16
textFontWeight: bold
blocks:
- id: theme_large_indicator_child
type: Avatar
properties:
shape: square
content: U
size: large
- id: theme_small_indicator
type: Badge
layout:
flex: 0 0 auto
properties:
count: 3
size: small
theme:
indicatorHeightSM: 18
textFontSizeSM: 10
blocks:
- id: theme_small_indicator_child
type: Avatar
properties:
shape: square
content: U
- id: theme_large_dot
type: Badge
layout:
flex: 0 0 auto
properties:
dot: true
theme:
dotSize: 12
blocks:
- id: theme_large_dot_child
type: Avatar
properties:
shape: square
content: U
- id: theme_blue_badge
type: Badge
layout:
flex: 0 0 auto
properties:
count: 15
theme:
colorError: "#1677ff"
colorErrorHover: "#4096ff"
blocks:
- id: theme_blue_badge_child
type: Avatar
properties:
shape: square
content: U
- id: theme_large_status
type: Badge
layout:
flex: 0 0 auto
properties:
status: processing
text: Processing
theme:
statusSize: 10
- id: theme_combined
type: Badge
layout:
flex: 0 0 auto
properties:
count: 42
theme:
indicatorHeight: 26
textFontSize: 14
textFontWeight: bold
textLineHeight: 26
colorError: "#722ed1"
colorErrorHover: "#9254de"
indicatorZIndex: 10
blocks:
- id: theme_combined_child
type: Avatar
properties:
shape: square
content: U
size: large
```
JD
```yaml
- id: rw_notif_header
type: Box
layout:
gap: 24
align: center
justify: end
class: bg-bg-container p-4 rounded-lg shadow-sm border border-border
blocks:
- id: rw_notif_search
type: TextInput
layout:
flex: 1 1 0
properties:
placeholder: Search...
prefixIcon: search
- id: rw_notif_badge_mail
type: Badge
layout:
flex: 0 0 auto
properties:
count: 4
size: small
blocks:
- id: rw_notif_mail_btn
type: Button
properties:
icon: mail
color: default
variant: text
hideTitle: true
events:
onClick:
- id: rw_notif_mail_action
type: DisplayMessage
params:
content: You have 4 unread messages.
status: info
- id: rw_notif_badge_bell
type: Badge
layout:
flex: 0 0 auto
properties:
dot: true
blocks:
- id: rw_notif_bell_btn
type: Button
properties:
icon: bell
color: default
variant: text
hideTitle: true
events:
onClick:
- id: rw_notif_bell_action
type: DisplayMessage
params:
content: You have new notifications.
status: info
- id: rw_notif_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
content: JD
color: "#1677ff"
```
#ORD-1042
Sarah Johnson
#ORD-1043
Michael Chen
#ORD-1044
Emily Davis
#ORD-1045
James Wilson
```yaml
- id: rw_orders_card
type: Card
properties:
title: Recent Orders
slots:
extra:
blocks:
- id: rw_orders_extra_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: View All
color: primary
variant: link
size: small
events:
onClick:
- id: rw_orders_link_action
type: DisplayMessage
params:
content: Navigating to full orders list.
status: info
blocks:
- id: rw_order_row1
type: Box
layout:
gap: 16
align: center
class: py-3 border-b border-border
blocks:
- id: rw_order1_id
type: Paragraph
layout:
flex: 0 0 120px
properties:
content: "#ORD-1042"
- id: rw_order1_customer
type: Paragraph
layout:
flex: 1 1 0
properties:
content: Sarah Johnson
- id: rw_order1_status
type: Badge
layout:
flex: 0 0 auto
properties:
status: success
text: Delivered
- id: rw_order_row2
type: Box
layout:
gap: 16
align: center
class: py-3 border-b border-border
blocks:
- id: rw_order2_id
type: Paragraph
layout:
flex: 0 0 120px
properties:
content: "#ORD-1043"
- id: rw_order2_customer
type: Paragraph
layout:
flex: 1 1 0
properties:
content: Michael Chen
- id: rw_order2_status
type: Badge
layout:
flex: 0 0 auto
properties:
status: processing
text: Shipping
- id: rw_order_row3
type: Box
layout:
gap: 16
align: center
class: py-3 border-b border-border
blocks:
- id: rw_order3_id
type: Paragraph
layout:
flex: 0 0 120px
properties:
content: "#ORD-1044"
- id: rw_order3_customer
type: Paragraph
layout:
flex: 1 1 0
properties:
content: Emily Davis
- id: rw_order3_status
type: Badge
layout:
flex: 0 0 auto
properties:
status: warning
text: Pending Payment
- id: rw_order_row4
type: Box
layout:
gap: 16
align: center
class: py-3
blocks:
- id: rw_order4_id
type: Paragraph
layout:
flex: 0 0 120px
properties:
content: "#ORD-1045"
- id: rw_order4_customer
type: Paragraph
layout:
flex: 1 1 0
properties:
content: James Wilson
- id: rw_order4_status
type: Badge
layout:
flex: 0 0 auto
properties:
status: error
text: Cancelled
```
```yaml
- id: rw_sidebar
type: Box
layout:
direction: column
gap: 0
class: bg-bg-container rounded-lg shadow-sm border border-border p-2 max-w-xs
blocks:
- id: rw_nav_inbox_btn
type: Button
class: justify-start w-full
properties:
title: Inbox
icon: Inbox
color: primary
variant: text
events:
onClick:
- id: rw_nav_inbox_action
type: SetState
params:
selectedNav: inbox
blocks:
- id: rw_nav_inbox_badge
type: Badge
layout:
flex: 0 0 auto
properties:
count: 12
size: small
theme:
colorError: "#1677ff"
- id: rw_nav_alerts_btn
type: Button
class: justify-start w-full
properties:
title: Alerts
icon: Siren
color: default
variant: text
events:
onClick:
- id: rw_nav_alerts_action
type: SetState
params:
selectedNav: alerts
blocks:
- id: rw_nav_alerts_badge
type: Badge
layout:
flex: 0 0 auto
properties:
count: 3
size: small
color: orange
- id: rw_nav_tasks_btn
type: Button
class: justify-start w-full
properties:
title: Tasks
icon: SquareCheck
color: default
variant: text
events:
onClick:
- id: rw_nav_tasks_action
type: SetState
params:
selectedNav: tasks
blocks:
- id: rw_nav_tasks_badge
type: Badge
layout:
flex: 0 0 auto
properties:
dot: true
- id: rw_nav_settings_btn
type: Button
class: justify-start w-full
properties:
title: Settings
icon: settings
color: default
variant: text
events:
onClick:
- id: rw_nav_settings_action
type: SetState
params:
selectedNav: settings
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `color` | string | - | Customize Badge dot color. |
| `count` | number \| string | - | Text to show in badge. |
| `dot` | boolean | `false` | Whether to display a red dot instead of count. |
| `size` | string | `"default"` | Sets the size of badge if count is set. Enum: `default`, `small`. |
| `icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to use an icon in badge. |
| `icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `icon.color` | string | - | Icon color. |
| `icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `offset` | array | - | Set offset of the badge dot, array of numbers for x and y offset ([x,y]). |
| `overflowCount` | number | `99` | Max count to show |
| `showZero` | boolean | `false` | Whether to show badge when count is zero. |
| `status` | string | `null` | Set Badge as a status dot. Enum: `success`, `processing`, `default`, `error`, `warning`. |
| `text` | string | - | If status is set, text sets the display text of the status dot. |
| `ribbon` | object | - | Render a ribbon on the corner of the content area instead of a count badge. Count, dot and status properties are ignored when ribbon is set. |
| `ribbon.text` | string | - | Text inside the ribbon. |
| `ribbon.color` | string | - | Ribbon color. A preset color name or any css color. |
| `ribbon.placement` | string | `"end"` | Corner of the content the ribbon is placed on. `start` and `end` follow the text direction. Enum: `start`, `end`. |
| `title` | string \| boolean | - | Text to show when hovering over the badge. Set to false to remove the native tooltip. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design badge tokens](https://ant.design/components/badge#design-token). |
| `theme.indicatorHeight` | number | `20` | Height of the badge indicator. |
| `theme.indicatorHeightSM` | number | `14` | Height of the badge indicator in small size. |
| `theme.dotSize` | number | `6` | Size of the dot badge. |
| `theme.textFontSize` | number | `12` | Font size for badge count text. |
| `theme.textFontSizeSM` | number | `12` | Font size for badge count text in small size. |
| `theme.textFontWeight` | string | `"normal"` | Font weight for badge count text. |
| `theme.paddingInline` | number \| string | `8` | Inline padding of a badge count with several characters. |
| `theme.textLineHeight` | number | - | Line height for badge count text. |
| `theme.statusSize` | number | `6` | Size of the status dot. |
| `theme.indicatorZIndex` | number \| string | `"auto"` | Z-index of the badge indicator. |
| `theme.colorBorderBg` | string | - | Background color of the badge border (gap between badge and wrapped element). |
| `theme.colorError` | string | - | Color of the badge indicator (default red). |
| `theme.colorErrorHover` | string | - | Hover color of the badge indicator. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Badge element, or the ribbon wrapper when ribbon is set. |
| `/icon` | The icon in the Badge. |
| `/indicator` | The Badge count or dot indicator, or the ribbon when ribbon is set. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks wrapped by the Badge. |
---
url: https://docs.lowdefy.com/md/container-blocks/box.md
---
# Box
Basic block-level container for layout.
```yaml
- id: box_basic
type: Box
blocks:
- id: box_basic_text
type: Html
properties:
html: 'A basic Box renders a div and contains child
blocks.
'
```
A Box can render a simple string using the content property.
Bold and italic text via the content property.
This content property overrides the content area below.
```yaml
- id: box_content_string
type: Box
properties:
content: A Box can render a simple string using the content property.
- id: box_content_html
type: Box
properties:
content: Bold and italic text via the content property.
- id: box_content_override
type: Box
properties:
content: This content property overrides the content area below.
blocks:
- id: box_content_override_child
type: Html
properties:
html: 'This child block is hidden because the content
property takes priority.
'
```
```yaml
- id: box_onclick
type: Box
style:
.element:
background: rgba(22, 119, 255, 0.08)
border: 1px solid rgba(22, 119, 255, 0.3)
padding: 16
borderRadius: 8
cursor: pointer
events:
onClick:
- id: box_onclick_message
type: DisplayMessage
params:
content: Box clicked!
status: info
blocks:
- id: box_onclick_text
type: Html
properties:
html: 'Click this box to trigger a
DisplayMessage action.
'
- id: box_onclick_setstate
type: Box
style:
.element:
background: rgba(82, 196, 26, 0.08)
border: 1px solid rgba(82, 196, 26, 0.3)
padding: 16
borderRadius: 8
cursor: pointer
events:
onClick:
- id: box_onclick_set
type: SetState
params:
box_click_count:
_sum:
- _state: box_click_count
- 1
blocks:
- id: box_onclick_counter_text
type: Html
properties:
html: 'Click this box to increment a
counter with SetState.
'
- id: box_onclick_link
type: Box
style:
.element:
background: rgba(250, 140, 22, 0.08)
border: 1px solid rgba(250, 140, 22, 0.3)
padding: 16
borderRadius: 8
cursor: pointer
events:
onClick:
- id: box_onclick_link_action
type: Link
params:
url: /
blocks:
- id: box_onclick_link_text
type: Html
properties:
html: 'Click this box to navigate using
the Link action.
'
```
```yaml
- id: box_onpaste
type: Box
style:
.element:
background: rgba(47, 84, 235, 0.08)
border: 1px dashed rgba(47, 84, 235, 0.3)
padding: 16
borderRadius: 8
events:
onPaste:
- id: box_onpaste_message
type: DisplayMessage
params:
content: Content pasted into the box!
status: success
blocks:
- id: box_onpaste_text
type: Html
properties:
html: 'Focus this box and paste something
to trigger the onPaste event.
'
```
```yaml
- id: box_gap_8
type: Box
layout:
gap: 8
blocks:
- id: box_gap_8_a
type: Button
layout:
flex: 0 0 auto
properties:
title: Gap 8
color: primary
variant: solid
- id: box_gap_8_b
type: Button
layout:
flex: 0 0 auto
properties:
title: Gap 8
color: primary
variant: solid
- id: box_gap_8_c
type: Button
layout:
flex: 0 0 auto
properties:
title: Gap 8
color: primary
variant: solid
- id: box_gap_16
type: Box
layout:
gap: 16
blocks:
- id: box_gap_16_a
type: Button
layout:
flex: 0 0 auto
properties:
title: Gap 16
color: primary
variant: outlined
- id: box_gap_16_b
type: Button
layout:
flex: 0 0 auto
properties:
title: Gap 16
color: primary
variant: outlined
- id: box_gap_16_c
type: Button
layout:
flex: 0 0 auto
properties:
title: Gap 16
color: primary
variant: outlined
- id: box_gap_32
type: Box
layout:
gap: 32
blocks:
- id: box_gap_32_a
type: Button
layout:
flex: 0 0 auto
properties:
title: Gap 32
color: green
variant: solid
- id: box_gap_32_b
type: Button
layout:
flex: 0 0 auto
properties:
title: Gap 32
color: green
variant: solid
- id: box_gap_32_c
type: Button
layout:
flex: 0 0 auto
properties:
title: Gap 32
color: green
variant: solid
```
**justify: flex-start**
**justify: center**
**justify: flex-end**
**justify: space-between**
**justify: space-around**
```yaml
- id: box_justify_start_label
type: Markdown
properties:
content: "**justify: flex-start**"
- id: box_justify_start
type: Box
layout:
gap: 8
justify: flex-start
class: p-3 rounded-lg border border-gray-500/20
blocks:
- id: box_js_a
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: primary
variant: solid
- id: box_js_b
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: primary
variant: solid
- id: box_js_c
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: primary
variant: solid
- id: box_justify_center_label
type: Markdown
properties:
content: "**justify: center**"
- id: box_justify_center
type: Box
layout:
gap: 8
justify: center
class: p-3 rounded-lg border border-gray-500/20
blocks:
- id: box_jc_a
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: green
variant: solid
- id: box_jc_b
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: green
variant: solid
- id: box_jc_c
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: green
variant: solid
- id: box_justify_end_label
type: Markdown
properties:
content: "**justify: flex-end**"
- id: box_justify_end
type: Box
layout:
gap: 8
justify: flex-end
class: p-3 rounded-lg border border-gray-500/20
blocks:
- id: box_je_a
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: danger
variant: solid
- id: box_je_b
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: danger
variant: solid
- id: box_je_c
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: danger
variant: solid
- id: box_justify_between_label
type: Markdown
properties:
content: "**justify: space-between**"
- id: box_justify_between
type: Box
layout:
gap: 8
justify: space-between
class: p-3 rounded-lg border border-gray-500/20
blocks:
- id: box_jb_a
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: purple
variant: solid
- id: box_jb_b
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: purple
variant: solid
- id: box_jb_c
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: purple
variant: solid
- id: box_justify_around_label
type: Markdown
properties:
content: "**justify: space-around**"
- id: box_justify_around
type: Box
layout:
gap: 8
justify: space-around
class: p-3 rounded-lg border border-gray-500/20
blocks:
- id: box_ja_a
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: cyan
variant: solid
- id: box_ja_b
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: cyan
variant: solid
- id: box_ja_c
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: cyan
variant: solid
```
**align: flex-start**
Tall
Short
**align: center**
Tall
Short
**align: flex-end**
Tall
Short
```yaml
- id: box_align_start_label
type: Markdown
properties:
content: "**align: flex-start**"
- id: box_align_start
type: Box
layout:
gap: 8
align: flex-start
class: p-3 rounded-lg border border-gray-500/20
style:
.element:
minHeight: 100
blocks:
- id: box_as_tall
type: Box
layout:
flex: 0 0 auto
class: bg-blue-500 text-white px-4 py-2 rounded-md flex items-center
style:
.element:
height: 80
properties:
content: Tall
- id: box_as_short
type: Box
layout:
flex: 0 0 auto
class: bg-blue-500 text-white px-4 py-2 rounded-md
properties:
content: Short
- id: box_align_center_label
type: Markdown
properties:
content: "**align: center**"
- id: box_align_center
type: Box
layout:
gap: 8
align: center
class: p-3 rounded-lg border border-gray-500/20
style:
.element:
minHeight: 100
blocks:
- id: box_ac_tall
type: Box
layout:
flex: 0 0 auto
class: bg-green-500 text-white px-4 py-2 rounded-md flex items-center
style:
.element:
height: 80
properties:
content: Tall
- id: box_ac_short
type: Box
layout:
flex: 0 0 auto
class: bg-green-500 text-white px-4 py-2 rounded-md
properties:
content: Short
- id: box_align_end_label
type: Markdown
properties:
content: "**align: flex-end**"
- id: box_align_end
type: Box
layout:
gap: 8
align: flex-end
class: p-3 rounded-lg border border-gray-500/20
style:
.element:
minHeight: 100
blocks:
- id: box_ae_tall
type: Box
layout:
flex: 0 0 auto
class: bg-red-500 text-white px-4 py-2 rounded-md flex items-center
style:
.element:
height: 80
properties:
content: Tall
- id: box_ae_short
type: Box
layout:
flex: 0 0 auto
class: bg-red-500 text-white px-4 py-2 rounded-md
properties:
content: Short
```
**Row direction (default):**
Item 1
Item 2
Item 3
**Column direction (via style):**
Item 1
Item 2
Item 3
```yaml
- id: box_dir_row_label
type: Markdown
properties:
content: "**Row direction (default):**"
- id: box_dir_row
type: Box
layout:
gap: 8
class: p-3 rounded-lg border border-blue-500/20 bg-blue-500/5
blocks:
- id: box_dr_a
type: Box
layout:
flex: 0 0 auto
class: bg-blue-500 text-white px-4 py-2 rounded-md
properties:
content: Item 1
- id: box_dr_b
type: Box
layout:
flex: 0 0 auto
class: bg-blue-500 text-white px-4 py-2 rounded-md
properties:
content: Item 2
- id: box_dr_c
type: Box
layout:
flex: 0 0 auto
class: bg-blue-500 text-white px-4 py-2 rounded-md
properties:
content: Item 3
- id: box_dir_column_label
type: Markdown
properties:
content: "**Column direction (via style):**"
- id: box_dir_column
type: Box
layout:
gap: 8
class: p-3 rounded-lg border border-green-500/20 bg-green-500/5
style:
.element:
display: flex
flexDirection: column
blocks:
- id: box_dc_a
type: Box
class: bg-green-500 text-white px-4 py-2 rounded-md
properties:
content: Item 1
- id: box_dc_b
type: Box
class: bg-green-500 text-white px-4 py-2 rounded-md
properties:
content: Item 2
- id: box_dc_c
type: Box
class: bg-green-500 text-white px-4 py-2 rounded-md
properties:
content: Item 3
```
**Boxes wrap to the next line when they overflow:**
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
```yaml
- id: box_wrap_label
type: Markdown
properties:
content: "**Boxes wrap to the next line when they overflow:**"
- id: box_wrap
type: Box
layout:
gap: 8
wrap: wrap
class: p-3 rounded-lg border border-gray-500/20
blocks:
- id: box_w_a
type: Box
layout:
flex: 0 0 150px
class: bg-purple-600 text-white px-4 py-2 rounded-md text-center
properties:
content: Item 1
- id: box_w_b
type: Box
layout:
flex: 0 0 150px
class: bg-purple-600 text-white px-4 py-2 rounded-md text-center
properties:
content: Item 2
- id: box_w_c
type: Box
layout:
flex: 0 0 150px
class: bg-purple-600 text-white px-4 py-2 rounded-md text-center
properties:
content: Item 3
- id: box_w_d
type: Box
layout:
flex: 0 0 150px
class: bg-purple-600 text-white px-4 py-2 rounded-md text-center
properties:
content: Item 4
- id: box_w_e
type: Box
layout:
flex: 0 0 150px
class: bg-purple-600 text-white px-4 py-2 rounded-md text-center
properties:
content: Item 5
- id: box_w_f
type: Box
layout:
flex: 0 0 150px
class: bg-purple-600 text-white px-4 py-2 rounded-md text-center
properties:
content: Item 6
```
**Children with flex: 1 grow to fill available space:**
Fixed 100px
Grows to fill
Fixed 100px
```yaml
- id: box_flex_label
type: Markdown
properties:
content: "**Children with flex: 1 grow to fill available space:**"
- id: box_flex_grow
type: Box
layout:
gap: 8
class: p-3 rounded-lg border border-gray-500/20
blocks:
- id: box_fg_fixed
type: Box
layout:
flex: 0 0 100px
class: bg-orange-500 text-white px-4 py-2 rounded-md text-center
properties:
content: Fixed 100px
- id: box_fg_grow
type: Box
layout:
flex: 1
class: bg-blue-500 text-white px-4 py-2 rounded-md text-center
properties:
content: Grows to fill
- id: box_fg_fixed2
type: Box
layout:
flex: 0 0 100px
class: bg-orange-500 text-white px-4 py-2 rounded-md text-center
properties:
content: Fixed 100px
```
```yaml
- id: box_nested_outer
type: Box
layout:
gap: 12
class: p-4 rounded-lg border border-blue-500/20 bg-blue-500/5
blocks:
- id: box_nested_left
type: Box
layout:
flex: 1
class: p-4 rounded-md border border-gray-500/20
blocks:
- id: box_nested_left_title
type: Html
properties:
html: 'Left Panel '
- id: box_nested_left_text
type: Html
properties:
html: 'This box is nested inside the outer
box with flex: 1.
'
- id: box_nested_right
type: Box
layout:
flex: 1
class: p-4 rounded-md border border-gray-500/20
blocks:
- id: box_nested_right_title
type: Html
properties:
html: 'Right Panel '
- id: box_nested_right_text
type: Html
properties:
html: 'Both panels share equal space via
flex: 1.
'
```
```yaml
- id: box_tw_shadow
type: Box
layout:
flex: 0 0 auto
class: p-5 rounded-xl shadow-lg border border-gray-500/20
blocks:
- id: box_tw_shadow_text
type: Html
properties:
html: 'Elevated box using Tailwind shadow and rounded
classes on the element cssKey.
'
- id: box_tw_border
type: Box
layout:
flex: 0 0 auto
class: border-2 border-dashed border-blue-500 p-4 rounded-lg
blocks:
- id: box_tw_border_text
type: Html
properties:
html: 'Dashed blue border via Tailwind
utilities.
'
- id: box_tw_accent
type: Box
layout:
flex: 0 0 auto
class: border-l-4 border-l-orange-500 pl-4 py-2
blocks:
- id: box_tw_accent_text
type: Html
properties:
html: 'Left accent
border using Tailwind border utilities.
'
- id: box_tw_centered
type: Box
class: max-w-sm mx-auto text-center p-4 bg-blue-500/10 rounded-lg
blocks:
- id: box_tw_centered_text
type: Html
properties:
html: 'Centered and
constrained width with Tailwind.
'
```
```yaml
- id: box_csskey_gradient
type: Box
layout:
flex: 0 0 auto
class:
element: bg-gradient-to-br from-indigo-500 to-purple-600 text-white p-5 rounded-xl
blocks:
- id: box_csskey_gradient_text
type: Html
properties:
html: 'Gradient Box Using the element
cssKey with a Tailwind gradient background.
'
- id: box_csskey_hover
type: Box
layout:
flex: 0 0 auto
class:
element: p-5 rounded-lg border border-gray-500/20 hover:shadow-lg
hover:border-blue-400 transition-all duration-200
blocks:
- id: box_csskey_hover_text
type: Html
properties:
html: 'Hover over this box to see a shadow and border
color transition using Tailwind hover utilities.
'
```
```yaml
- id: box_style_shadow
type: Box
layout:
flex: 0 0 auto
style:
.element:
padding: 20
borderRadius: 12
boxShadow: 0 4px 12px rgba(0, 0, 0, 0.1)
background: rgba(255, 255, 255, 0.06)
blocks:
- id: box_style_shadow_text
type: Html
properties:
html: 'Elevated box with box-shadow via inline style on
the element cssKey.
'
- id: box_style_dark
type: Box
layout:
flex: 0 0 auto
style:
.element:
background: "#1a1a2e"
color: "#e0e0e0"
padding: 20
borderRadius: 8
blocks:
- id: box_style_dark_title
type: Html
properties:
html: 'Dark Box '
- id: box_style_dark_text
type: Html
properties:
html: 'Light text on dark background using
inline style.
'
- id: box_style_gradient
type: Box
layout:
flex: 0 0 auto
style:
.element:
background: linear-gradient(135deg,
color: "#ffffff"
padding: 20
borderRadius: 8
blocks:
- id: box_style_gradient_text
type: Html
properties:
html: 'Gradient Box A gradient
background using the inline style approach.
'
```
```yaml
- id: box_bg_blue
type: Box
layout:
flex: 0 0 auto
class: bg-blue-500/10 border border-blue-500/30 p-4 rounded-lg
blocks:
- id: box_bg_blue_text
type: Html
properties:
html: 'Blue info box
'
- id: box_bg_green
type: Box
layout:
flex: 0 0 auto
class: bg-green-500/10 border border-green-500/30 p-4 rounded-lg
blocks:
- id: box_bg_green_text
type: Html
properties:
html: 'Green success box
'
- id: box_bg_red
type: Box
layout:
flex: 0 0 auto
class: bg-red-500/10 border border-red-500/30 p-4 rounded-lg
blocks:
- id: box_bg_red_text
type: Html
properties:
html: 'Red error box
'
- id: box_bg_yellow
type: Box
layout:
flex: 0 0 auto
class: bg-yellow-500/10 border border-yellow-500/30 p-4 rounded-lg
blocks:
- id: box_bg_yellow_text
type: Html
properties:
html: 'Yellow warning box
'
```
```yaml
- id: box_features_row
type: Box
layout:
gap: 16
wrap: wrap
blocks:
- id: box_feature_a
type: Box
layout:
flex: 1 1 200px
class: p-5 rounded-xl border border-gray-500/20
blocks:
- id: box_feature_a_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: Rocket
size: 32
color: "#1677ff"
- id: box_feature_a_title
type: Html
properties:
html: 'Fast '
- id: box_feature_a_desc
type: Html
properties:
html: 'Optimized for performance with lazy
loading and code splitting.
'
- id: box_feature_b
type: Box
layout:
flex: 1 1 200px
class: p-5 rounded-xl border border-gray-500/20
blocks:
- id: box_feature_b_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: Shield
size: 32
color: "#52c41a"
- id: box_feature_b_title
type: Html
properties:
html: 'Secure '
- id: box_feature_b_desc
type: Html
properties:
html: 'Built-in security features with
role-based access control.
'
- id: box_feature_c
type: Box
layout:
flex: 1 1 200px
class: p-5 rounded-xl border border-gray-500/20
blocks:
- id: box_feature_c_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: Plug
size: 32
color: "#722ed1"
- id: box_feature_c_title
type: Html
properties:
html: 'Extensible '
- id: box_feature_c_desc
type: Html
properties:
html: 'Plug in your own components and
connect to any API.
'
```
```yaml
- id: box_page_layout
type: Box
style:
.element:
display: flex
flexDirection: column
minHeight: 300
borderRadius: 8
overflow: hidden
border: 1px solid rgba(128, 128, 128, 0.3)
blocks:
- id: box_page_header
type: Box
layout:
justify: space-between
align: center
class: bg-slate-900 px-5 py-3
blocks:
- id: box_page_logo
type: Html
layout:
flex: 0 0 auto
properties:
html: 'My
App '
- id: box_page_nav
type: Box
layout:
flex: 0 0 auto
gap: 16
blocks:
- id: box_page_nav_home
type: Button
layout:
flex: 0 0 auto
properties:
title: Home
color: default
variant: link
events:
onClick:
- id: box_page_nav_home_link
type: Link
params:
url: /
- id: box_page_nav_about
type: Button
layout:
flex: 0 0 auto
properties:
title: About
color: default
variant: link
events:
onClick:
- id: box_page_nav_about_link
type: Link
params:
url: /about
- id: box_page_nav_contact
type: Button
layout:
flex: 0 0 auto
properties:
title: Contact
color: default
variant: link
events:
onClick:
- id: box_page_nav_contact_link
type: Link
params:
url: /contact
- id: box_page_body
type: Box
layout:
flex: 1
class: p-6
blocks:
- id: box_page_body_text
type: Html
properties:
html: 'Main content area grows to fill
available space using flex: 1. Place page content blocks
here.
'
- id: box_page_footer
type: Box
layout:
justify: center
class: px-5 py-3 border-t border-gray-500/20
blocks:
- id: box_page_footer_text
type: Html
layout:
flex: 0 0 auto
properties:
html: '2026 My App. All rights
reserved. '
```
```yaml
- id: box_inbox_wrapper
type: Box
class: rounded-lg border border-gray-500/20 overflow-hidden
style:
.element:
display: flex
flexDirection: column
maxWidth: 480
blocks:
- id: box_inbox_header
type: Box
layout:
justify: space-between
align: center
class: px-4 py-3 border-b border-gray-500/20
blocks:
- id: box_inbox_title
type: Html
layout:
flex: 0 0 auto
properties:
html: 'Notifications '
- id: box_inbox_mark_read
type: Button
layout:
flex: 0 0 auto
properties:
title: Mark all read
color: primary
variant: link
size: small
events:
onClick:
- id: box_inbox_mark_read_action
type: DisplayMessage
params:
content: All notifications marked as read.
status: success
- id: box_inbox_item_1
type: Box
layout:
gap: 12
align: flex-start
class: px-4 py-3 border-b border-gray-500/10 bg-blue-500/10 cursor-pointer
hover:bg-blue-500/15
events:
onClick:
- id: box_inbox_item_1_click
type: DisplayMessage
params:
content: "Opened: Deployment completed"
status: info
blocks:
- id: box_inbox_item_1_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: check-circle
size: 20
color: "#52c41a"
- id: box_inbox_item_1_body
type: Box
layout:
flex: 1
direction: column
gap: 2
blocks:
- id: box_inbox_item_1_text
type: Html
properties:
html: 'Deployment completed '
- id: box_inbox_item_1_time
type: Html
properties:
html: 'Production v2.4.1 deployed
successfully - 5 minutes ago '
- id: box_inbox_item_2
type: Box
layout:
gap: 12
align: flex-start
class: px-4 py-3 border-b border-gray-500/10 bg-blue-500/10 cursor-pointer
hover:bg-blue-500/15
events:
onClick:
- id: box_inbox_item_2_click
type: DisplayMessage
params:
content: "Opened: New team member"
status: info
blocks:
- id: box_inbox_item_2_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: UserPlus
size: 20
color: "#1677ff"
- id: box_inbox_item_2_body
type: Box
layout:
flex: 1
direction: column
gap: 2
blocks:
- id: box_inbox_item_2_text
type: Html
properties:
html: 'New team member added '
- id: box_inbox_item_2_time
type: Html
properties:
html: 'Sarah joined the Design team
- 2 hours ago '
- id: box_inbox_item_3
type: Box
layout:
gap: 12
align: flex-start
class: px-4 py-3 cursor-pointer hover:bg-gray-500/10
events:
onClick:
- id: box_inbox_item_3_click
type: DisplayMessage
params:
content: "Opened: Storage warning"
status: info
blocks:
- id: box_inbox_item_3_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: warning
size: 20
color: "#faad14"
- id: box_inbox_item_3_body
type: Box
layout:
flex: 1
direction: column
gap: 2
blocks:
- id: box_inbox_item_3_text
type: Html
properties:
html: 'Storage limit approaching '
- id: box_inbox_item_3_time
type: Html
properties:
html: 'You have used 85% of your
storage quota - 1 day ago '
```
```yaml
- id: box_sidebar_layout
type: Box
layout:
gap: 0
class: rounded-lg border border-gray-500/20 overflow-hidden
style:
.element:
minHeight: 320
blocks:
- id: box_sidebar_nav
type: Box
layout:
flex: 0 0 200px
class: border-r border-gray-500/20
style:
.element:
display: flex
flexDirection: column
blocks:
- id: box_sidebar_brand
type: Html
properties:
html: 'Workspace
'
- id: box_sidebar_item_dashboard
type: Box
layout:
gap: 8
align: center
class: px-4 py-2 bg-blue-500/10 cursor-pointer
events:
onClick:
- id: box_sidebar_dashboard_action
type: SetState
params:
sidebar_active: dashboard
blocks:
- id: box_sidebar_icon_dashboard
type: Icon
layout:
flex: 0 0 auto
properties:
name: Gauge
size: 16
color: "#1677ff"
- id: box_sidebar_text_dashboard
type: Html
layout:
flex: 0 0 auto
properties:
html: 'Dashboard '
- id: box_sidebar_item_projects
type: Box
layout:
gap: 8
align: center
class: px-4 py-2 cursor-pointer hover:bg-gray-500/10
events:
onClick:
- id: box_sidebar_projects_action
type: SetState
params:
sidebar_active: projects
blocks:
- id: box_sidebar_icon_projects
type: Icon
layout:
flex: 0 0 auto
properties:
name: SquareKanban
size: 16
color: rgba(128, 128, 128, 0.7)
- id: box_sidebar_text_projects
type: Html
layout:
flex: 0 0 auto
properties:
html: 'Projects '
- id: box_sidebar_item_settings
type: Box
layout:
gap: 8
align: center
class: px-4 py-2 cursor-pointer hover:bg-gray-500/10
events:
onClick:
- id: box_sidebar_settings_action
type: SetState
params:
sidebar_active: settings
blocks:
- id: box_sidebar_icon_settings
type: Icon
layout:
flex: 0 0 auto
properties:
name: settings
size: 16
color: rgba(128, 128, 128, 0.7)
- id: box_sidebar_text_settings
type: Html
layout:
flex: 0 0 auto
properties:
html: 'Settings '
- id: box_sidebar_content
type: Box
layout:
flex: 1
class: p-6
blocks:
- id: box_sidebar_content_title
type: Html
properties:
html: 'Dashboard '
- id: box_sidebar_stats_row
type: Box
layout:
gap: 12
blocks:
- id: box_sidebar_stat_users
type: Box
layout:
flex: 1
class: p-4 rounded-lg border border-blue-500/20 bg-blue-500/5
blocks:
- id: box_sidebar_stat_users_label
type: Html
properties:
html: 'Active Users '
- id: box_sidebar_stat_users_value
type: Html
properties:
html: '1,248 '
- id: box_sidebar_stat_revenue
type: Box
layout:
flex: 1
class: p-4 rounded-lg border border-green-500/20 bg-green-500/5
blocks:
- id: box_sidebar_stat_revenue_label
type: Html
properties:
html: 'Revenue '
- id: box_sidebar_stat_revenue_value
type: Html
properties:
html: '$48,650 '
- id: box_sidebar_stat_tasks
type: Box
layout:
flex: 1
class: p-4 rounded-lg border border-orange-500/20 bg-orange-500/5
blocks:
- id: box_sidebar_stat_tasks_label
type: Html
properties:
html: 'Open Tasks '
- id: box_sidebar_stat_tasks_value
type: Html
properties:
html: '37 '
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `content` | string | - | Box content string. Overrides the "content" content area. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onClick` | \- | Trigger actions when the Box is clicked. |
| `onPaste` | \- | Trigger actions when the element is focused and a paste event is triggered. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Box element. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks in the Box. |
---
url: https://docs.lowdefy.com/md/container-blocks/card.md
---
# Card
Card container with title, extra, cover, and actions.
Cards provide a flexible and extensible content container with multiple variants. This is the default card with a simple title and body content.
You can place any blocks inside the card body using the standard blocks key.
A card without a title. The header area is completely hidden, leaving only the body content. Useful as a simple elevated content container.
```yaml
- id: basic_card
type: Card
properties:
title: Card Title
blocks:
- id: basic_card_p1
type: Paragraph
properties:
content: Cards provide a flexible and extensible content container with multiple
variants. This is the default card with a simple title and body
content.
- id: basic_card_p2
type: Paragraph
properties:
content: You can place any blocks inside the card body using the standard blocks
key.
- id: basic_no_title
type: Card
blocks:
- id: basic_no_title_content
type: Paragraph
properties:
content: A card without a title. The header area is completely hidden, leaving
only the body content. Useful as a simple elevated content container.
```
Default size card with standard padding (24px) and normal header height (56px). This is the most common card size for general content.
Small size card with compact padding (12px) and shorter header (38px). Ideal for dense layouts, dashboards, or sidebar widgets.
```yaml
- id: size_default_card
type: Card
layout:
flex: 1 1 0
properties:
title: Default Size
size: default
blocks:
- id: size_default_p
type: Paragraph
properties:
content: Default size card with standard padding (24px) and normal header height
(56px). This is the most common card size for general content.
- id: size_default_row
type: Box
layout:
gap: 8
blocks:
- id: size_default_tag1
type: Tag
properties:
title: Standard
color: blue
- id: size_default_tag2
type: Tag
properties:
title: 24px padding
color: default
- id: size_small_card
type: Card
layout:
flex: 1 1 0
properties:
title: Small Size
size: small
blocks:
- id: size_small_p
type: Paragraph
properties:
content: Small size card with compact padding (12px) and shorter header (38px).
Ideal for dense layouts, dashboards, or sidebar widgets.
- id: size_small_row
type: Box
layout:
gap: 8
blocks:
- id: size_small_tag1
type: Tag
properties:
title: Compact
color: green
- id: size_small_tag2
type: Tag
properties:
title: 12px padding
color: default
```
padding: compact tightens the body to 12px and lines the header up with it, while keeping the default header height. Use it for dense dashboards and forms.
```yaml
- id: padding_compact_card
type: Card
layout:
flex: 1 1 0
properties:
title: Compact
padding: compact
blocks:
- id: padding_compact_p
type: Paragraph
properties:
content: "padding: compact tightens the body to 12px and lines the header up
with it, while keeping the default header height. Use it for dense
dashboards and forms."
- id: padding_none_card
type: Card
layout:
flex: 1 1 0
properties:
title: Recent invoices
padding: none
blocks:
- id: padding_none_card_rows
type: Html
properties:
html: >
INV-1042 $1,280.00
INV-1041 $640.00
INV-1040 $2,115.50
INV-1039 $96.00
```
The default card has a visible border. This clearly separates the card from its surroundings.
A borderless card blends into its container. Best used on colored backgrounds where the card's white fill provides enough contrast.
```yaml
- id: border_wrapper
type: Box
class: bg-bg-layout p-6 rounded-lg
layout:
gap: 16
blocks:
- id: bordered_card
type: Card
layout:
flex: 1 1 0
properties:
title: Outlined (default)
variant: outlined
blocks:
- id: bordered_content
type: Paragraph
properties:
content: The default card has a visible border. This clearly separates the card
from its surroundings.
- id: borderless_card
type: Card
layout:
flex: 1 1 0
properties:
title: Borderless
variant: borderless
blocks:
- id: borderless_content
type: Paragraph
properties:
content: A borderless card blends into its container. Best used on colored
backgrounds where the card's white fill provides enough contrast.
```
User John updated the project settings 2 minutes ago.
User Sarah added 3 new team members 15 minutes ago.
Deployment completed successfully 1 hour ago.
The extra slot renders content in the top-right corner of the card header, next to the title. It accepts any blocks, commonly used for action buttons or links.
```yaml
- id: extra_text_card
type: Card
properties:
title: Recent Activity
slots:
extra:
blocks:
- id: extra_text_link
type: Button
layout:
flex: 0 0 auto
properties:
title: View All
color: primary
variant: link
size: small
blocks:
- id: extra_text_p1
type: Paragraph
properties:
content: User John updated the project settings 2 minutes ago.
- id: extra_text_p2
type: Paragraph
properties:
content: User Sarah added 3 new team members 15 minutes ago.
- id: extra_text_p3
type: Paragraph
properties:
content: Deployment completed successfully 1 hour ago.
- id: extra_buttons_card
type: Card
properties:
title: Project Settings
slots:
extra:
blocks:
- id: extra_btn_row
type: Box
layout:
gap: 8
blocks:
- id: extra_btn_edit
type: Button
layout:
flex: 0 0 auto
properties:
title: Edit
icon: edit
color: primary
variant: outlined
size: small
- id: extra_btn_more
type: Button
layout:
flex: 0 0 auto
properties:
icon: more
color: default
variant: text
size: small
hideTitle: true
blocks:
- id: extra_buttons_content
type: Paragraph
properties:
content: The extra slot renders content in the top-right corner of the card
header, next to the title. It accepts any blocks, commonly used for
action buttons or links.
```
The title slot lets you replace the default text title with any combination of blocks. Here we use an Avatar and Title block side by side. This overrides the properties.title string.
Custom Title Layout
Combining the title slot with the extra slot gives you full control over the entire header area.
Notifications
```yaml
- id: title_slot_card
type: Card
slots:
title:
blocks:
- id: title_slot_row
type: Box
layout:
gap: 12
align: center
blocks:
- id: title_slot_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
color: "#1677ff"
- id: title_slot_text
type: Title
layout:
flex: 0 0 auto
properties:
content: Custom Title Layout
level: 5
blocks:
- id: title_slot_content
type: Paragraph
properties:
content: The title slot lets you replace the default text title with any
combination of blocks. Here we use an Avatar and Title block side by
side. This overrides the properties.title string.
- id: title_slot_badge_card
type: Card
slots:
title:
blocks:
- id: title_badge_row
type: Box
layout:
gap: 8
align: center
blocks:
- id: title_badge_text
type: Title
layout:
flex: 0 0 auto
properties:
content: Notifications
level: 5
- id: title_badge_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: 12 new
color: red
extra:
blocks:
- id: title_badge_extra_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Mark all read
color: primary
variant: link
size: small
blocks:
- id: title_badge_content
type: Paragraph
properties:
content: Combining the title slot with the extra slot gives you full control
over the entire header area.
```
The cover slot renders content above the card body, typically used for images. It sits outside the body padding for edge-to-edge display.
Architecture Photography
A cover card without a header title. The title is placed inside the body instead, giving a magazine-style layout.
```yaml
- id: cover_card_1
type: Card
layout:
flex: 1 1 0
properties:
title: Mountain Landscape
hoverable: true
slots:
cover:
blocks:
- id: cover_img_1
type: Html
properties:
html:
blocks:
- id: cover_card_1_desc
type: Paragraph
properties:
content: The cover slot renders content above the card body, typically used for
images. It sits outside the body padding for edge-to-edge display.
- id: cover_card_2
type: Card
layout:
flex: 1 1 0
properties:
hoverable: true
slots:
cover:
blocks:
- id: cover_img_2
type: Html
properties:
html:
blocks:
- id: cover_card_2_title
type: Title
properties:
content: Architecture Photography
level: 5
- id: cover_card_2_desc
type: Paragraph
properties:
content: A cover card without a header title. The title is placed inside the
body instead, giving a magazine-style layout.
- id: cover_card_2_tags
type: Box
layout:
gap: 8
blocks:
- id: cover_card_2_tag1
type: Tag
properties:
title: Photography
color: blue
- id: cover_card_2_tag2
type: Tag
properties:
title: Featured
color: gold
```
Revenue grew 12% over the previous quarter.
```yaml
- id: actions_card
type: Card
properties:
title: Quarterly report
slots:
content:
blocks:
- id: actions_card_text
type: Paragraph
properties:
content: Revenue grew 12% over the previous quarter.
actions:
blocks:
- id: actions_card_buttons
type: Flex
properties:
justify: space-around
blocks:
- id: actions_card_view
type: Button
properties:
title: View
type: link
icon: view
- id: actions_card_share
type: Button
properties:
title: Share
type: link
icon: share
```
Shown once loading is false.
```yaml
- id: loading_card
type: Card
properties:
title: Customer details
loading: true
blocks:
- id: loading_card_text
type: Paragraph
properties:
content: Shown once loading is false.
```
Inner cards have a gray background and are designed for nesting inside a parent card. They provide visual grouping without extra border weight.
Multiple inner cards can stack within a parent to organize related sections. Each has its own title and content area.
Inner cards also support the small size variant for more compact layouts.
```yaml
- id: inner_outer
type: Card
properties:
title: Group Title
slots:
extra:
blocks:
- id: inner_outer_extra
type: Button
layout:
flex: 0 0 auto
properties:
title: More
color: primary
variant: link
size: small
blocks:
- id: inner_first
type: Card
properties:
title: Inner Card One
inner: true
blocks:
- id: inner_first_content
type: Paragraph
properties:
content: Inner cards have a gray background and are designed for nesting inside
a parent card. They provide visual grouping without extra border
weight.
- id: inner_second
type: Card
properties:
title: Inner Card Two
inner: true
blocks:
- id: inner_second_content
type: Paragraph
properties:
content: Multiple inner cards can stack within a parent to organize related
sections. Each has its own title and content area.
- id: inner_third
type: Card
properties:
title: Inner Card Three
inner: true
size: small
blocks:
- id: inner_third_content
type: Paragraph
properties:
content: Inner cards also support the small size variant for more compact
layouts.
```
Hover over any card in this section to see the elevation shadow effect. Commonly used for clickable card grids.
```yaml
- id: hover_card_1
type: Card
layout:
flex: 1 1 0
properties:
title: Dashboard
hoverable: true
slots:
extra:
blocks:
- id: hover_card_1_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: Gauge
color: "#1677ff"
size: 20
blocks:
- id: hover_card_1_stat
type: Statistic
properties:
title: Active Users
value: 1248
- id: hover_card_1_p
type: Paragraph
properties:
content: Hover over any card in this section to see the elevation shadow effect.
Commonly used for clickable card grids.
- id: hover_card_2
type: Card
layout:
flex: 1 1 0
properties:
title: Revenue
hoverable: true
slots:
extra:
blocks:
- id: hover_card_2_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: CircleDollarSign
color: "#52c41a"
size: 20
blocks:
- id: hover_card_2_stat
type: Statistic
properties:
title: Monthly Revenue
value: 48650
prefix: $
- id: hover_card_2_tag
type: Tag
properties:
title: +12.5%
color: success
- id: hover_card_3
type: Card
layout:
flex: 1 1 0
properties:
title: Tasks
hoverable: true
slots:
extra:
blocks:
- id: hover_card_3_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: check-circle
color: "#faad14"
size: 20
blocks:
- id: hover_card_3_stat
type: Statistic
properties:
title: Completed Today
value: 37
- id: hover_card_3_progress
type: Progress
properties:
percent: 74
```
Jane Cooper
Senior Product Designer
A web application for managing team workflows, project timelines, and resource allocation across departments.
Pro Plan
$29
/ month
Unlimited projects
50 GB storage
Priority support
Advanced analytics
```yaml
- id: rich_profile_card
type: Card
layout:
flex: 1 1 0
blocks:
- id: rich_profile_row
type: Box
layout:
gap: 16
align: center
blocks:
- id: rich_profile_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 64
color: "#1677ff"
- id: rich_profile_info
type: Box
layout:
flex: 1 1 0
direction: column
gap: 4
blocks:
- id: rich_profile_name
type: Title
properties:
content: Jane Cooper
level: 4
- id: rich_profile_role
type: Paragraph
properties:
content: Senior Product Designer
- id: rich_profile_divider
type: Divider
- id: rich_profile_details
type: Descriptions
properties:
size: small
column: 1
items:
- label: Email
value: jane.cooper@example.com
- label: Location
value: San Francisco, CA
- label: Team
value: Design Systems
- id: rich_project_card
type: Card
layout:
flex: 1 1 0
properties:
title: Project Alpha
slots:
extra:
blocks:
- id: rich_project_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Active
color: success
blocks:
- id: rich_project_desc
type: Paragraph
properties:
content: A web application for managing team workflows, project timelines, and
resource allocation across departments.
- id: rich_project_divider
type: Divider
- id: rich_project_meta_row
type: Box
layout:
gap: 16
blocks:
- id: rich_project_stat1
type: Statistic
layout:
flex: 1 1 0
properties:
title: Tasks
value: 42
- id: rich_project_stat2
type: Statistic
layout:
flex: 1 1 0
properties:
title: Members
value: 8
- id: rich_project_stat3
type: Statistic
layout:
flex: 1 1 0
properties:
title: Days Left
value: 14
- id: rich_project_progress
type: Progress
properties:
percent: 68
- id: rich_pricing_card
type: Card
layout:
flex: 1 1 0
properties:
hoverable: true
blocks:
- id: rich_pricing_title
type: Title
properties:
content: Pro Plan
level: 4
- id: rich_pricing_price_row
type: Box
layout:
align: baseline
gap: 4
blocks:
- id: rich_pricing_amount
type: Title
layout:
flex: 0 0 auto
properties:
content: $29
level: 2
- id: rich_pricing_period
type: Paragraph
layout:
flex: 0 0 auto
properties:
content: / month
- id: rich_pricing_divider
type: Divider
- id: rich_pricing_f1
type: Paragraph
properties:
content: Unlimited projects
- id: rich_pricing_f2
type: Paragraph
properties:
content: 50 GB storage
- id: rich_pricing_f3
type: Paragraph
properties:
content: Priority support
- id: rich_pricing_f4
type: Paragraph
properties:
content: Advanced analytics
- id: rich_pricing_btn
type: Button
properties:
title: Get Started
color: primary
variant: solid
block: true
```
Track key metrics and performance indicators across your application in real time.
Role-based access control, audit logging, and two-factor authentication for your team.
Connect with over 50 third-party services including Slack, GitHub, Jira, and more.
Shared workspaces, comments, mentions, and real-time co-editing for seamless teamwork.
```yaml
- id: grid_card_1
type: Card
layout:
flex: 1 1 280px
properties:
title: Analytics
size: small
hoverable: true
slots:
extra:
blocks:
- id: grid_card_1_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: chart
color: "#1677ff"
blocks:
- id: grid_card_1_p
type: Paragraph
properties:
content: Track key metrics and performance indicators across your application in
real time.
- id: grid_card_1_tags
type: Box
layout:
gap: 8
blocks:
- id: grid_card_1_t1
type: Tag
properties:
title: Metrics
color: blue
- id: grid_card_1_t2
type: Tag
properties:
title: Real-time
color: cyan
- id: grid_card_2
type: Card
layout:
flex: 1 1 280px
properties:
title: Security
size: small
hoverable: true
slots:
extra:
blocks:
- id: grid_card_2_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: lock
color: "#52c41a"
blocks:
- id: grid_card_2_p
type: Paragraph
properties:
content: Role-based access control, audit logging, and two-factor authentication
for your team.
- id: grid_card_2_tags
type: Box
layout:
gap: 8
blocks:
- id: grid_card_2_t1
type: Tag
properties:
title: RBAC
color: green
- id: grid_card_2_t2
type: Tag
properties:
title: 2FA
color: lime
- id: grid_card_3
type: Card
layout:
flex: 1 1 280px
properties:
title: Integrations
size: small
hoverable: true
slots:
extra:
blocks:
- id: grid_card_3_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: Plug
color: "#722ed1"
blocks:
- id: grid_card_3_p
type: Paragraph
properties:
content: Connect with over 50 third-party services including Slack, GitHub,
Jira, and more.
- id: grid_card_3_tags
type: Box
layout:
gap: 8
blocks:
- id: grid_card_3_t1
type: Tag
properties:
title: API
color: purple
- id: grid_card_3_t2
type: Tag
properties:
title: Webhooks
color: geekblue
- id: grid_card_4
type: Card
layout:
flex: 1 1 280px
properties:
title: Collaboration
size: small
hoverable: true
slots:
extra:
blocks:
- id: grid_card_4_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: users
color: "#fa8c16"
blocks:
- id: grid_card_4_p
type: Paragraph
properties:
content: Shared workspaces, comments, mentions, and real-time co-editing for
seamless teamwork.
- id: grid_card_4_tags
type: Box
layout:
gap: 8
blocks:
- id: grid_card_4_t1
type: Tag
properties:
title: Teams
color: orange
- id: grid_card_4_t2
type: Tag
properties:
title: Comments
color: gold
```
Gradient Card
Using Tailwind CSS classes to create a gradient background card. The class property on the Card applies utility classes directly to the wrapper.
A borderless card with extra-large shadow and rounded corners. The shadow-xl class creates a prominent floating effect.
A left accent border highlights important cards. Combine Tailwind border utilities with the Card component for custom accents.
```yaml
- id: styled_gradient
type: Card
layout:
flex: 1 1 0
class: bg-gradient-to-br from-primary/100 to-purple-600 text-white border-0
rounded-xl
blocks:
- id: styled_gradient_title
type: Title
class: text-white
properties:
content: Gradient Card
level: 4
- id: styled_gradient_p
type: Paragraph
class: text-blue-100
properties:
content: Using Tailwind CSS classes to create a gradient background card. The
class property on the Card applies utility classes directly to the
wrapper.
- id: styled_shadow
type: Card
layout:
flex: 1 1 0
class: shadow-xl rounded-2xl border-0
properties:
title: Elevated Card
blocks:
- id: styled_shadow_p
type: Paragraph
properties:
content: A borderless card with extra-large shadow and rounded corners. The
shadow-xl class creates a prominent floating effect.
- id: styled_accent
type: Card
layout:
flex: 1 1 0
class: border-l-4 border-l-green-500 rounded-lg
properties:
title: Accent Border
blocks:
- id: styled_accent_p
type: Paragraph
properties:
content: A left accent border highlights important cards. Combine Tailwind
border utilities with the Card component for custom accents.
```
Using style.header and style.body to apply custom CSS to the card header and body sections separately. The header has a blue tint with a matching border.
A manually styled dark card using inline styles on the header and body. For app-wide dark themes, prefer antd theme tokens or ConfigProvider.
Inline styles on the header and body can override the default padding for a more compact layout without using the small size variant.
```yaml
- id: style_header_bg
type: Card
layout:
flex: 1 1 0
properties:
title: Colored Header
style:
.header:
backgroundColor: var(--ant-color-primary-bg)
borderBottom: 1px solid var(--ant-color-primary-border)
.body:
backgroundColor: var(--ant-color-fill-quaternary)
blocks:
- id: style_header_bg_p
type: Paragraph
properties:
content: Using style.header and style.body to apply custom CSS to the card
header and body sections separately. The header has a blue tint with a
matching border.
- id: style_dark_card
type: Card
layout:
flex: 1 1 0
properties:
title: Dark Theme Card
style:
.header:
backgroundColor: "#1f1f1f"
color: "#ffffff"
borderBottom: "1px solid #333"
.body:
backgroundColor: "#2a2a2a"
blocks:
- id: style_dark_p
type: Paragraph
class: text-text-secondary
properties:
content: A manually styled dark card using inline styles on the header and body.
For app-wide dark themes, prefer antd theme tokens or ConfigProvider.
- id: style_compact_card
type: Card
layout:
flex: 1 1 0
properties:
title: Compact Custom Padding
style:
.header:
padding: 8px 16px
minHeight: 40px
.body:
padding: 12px 16px
blocks:
- id: style_compact_p
type: Paragraph
properties:
content: Inline styles on the header and body can override the default padding
for a more compact layout without using the small size variant.
```
Card supports these CSS keys: element, header, body, cover, actions, extra. Use class as an object to target each area with Tailwind classes.
Combining the hoverable property with a Tailwind hover ring transition creates an interactive highlight on mouse over.
The extra CSS key lets you style the container around the extra slot content. Here a green pill background wraps the status tag.
```yaml
- id: css_element
type: Card
layout:
flex: 1 1 0
class:
.element: shadow-lg rounded-xl
.header: bg-bg-layout
.body: bg-bg-container
properties:
title: Element + Header + Body
blocks:
- id: css_element_p
type: Paragraph
properties:
content: "Card supports these CSS keys: element, header, body, cover, actions,
extra. Use class as an object to target each area with Tailwind
classes."
- id: css_hover_ring
type: Card
layout:
flex: 1 1 0
class:
.element: hover:ring-2 hover:ring-blue-400 transition-all duration-200 rounded-lg
properties:
title: Hover Ring Effect
hoverable: true
blocks:
- id: css_hover_ring_p
type: Paragraph
properties:
content: Combining the hoverable property with a Tailwind hover ring transition
creates an interactive highlight on mouse over.
- id: css_extra_styled
type: Card
layout:
flex: 1 1 0
class:
.extra: bg-bg-layout px-3 py-1 rounded-full
properties:
title: Styled Extra Area
slots:
extra:
blocks:
- id: css_extra_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Live
color: success
blocks:
- id: css_extra_styled_p
type: Paragraph
properties:
content: The extra CSS key lets you style the container around the extra slot
content. Here a green pill background wraps the status tag.
```
Override bodyPadding and headerPadding tokens for extra spacious cards. These tokens control the internal spacing of the card.
The headerBg token changes the card header background color, and colorTextHeading changes the title text color. These apply through the antd theme system.
The borderRadiusLG token controls the card corner radius. Set a large value for a pill-like card appearance.
Combine the small size variant with custom SM tokens for an ultra-compact card. Useful for data-dense dashboards.
A warm-toned card using theme tokens to customize the background, header, text, and border colors. Theme tokens cascade correctly through the antd design system.
```yaml
- id: theme_large_padding
type: Card
layout:
flex: 1 1 0
properties:
title: Large Padding
theme:
bodyPadding: 40
headerPadding: 40
blocks:
- id: theme_large_padding_p
type: Paragraph
properties:
content: Override bodyPadding and headerPadding tokens for extra spacious cards.
These tokens control the internal spacing of the card.
- id: theme_colored_header
type: Card
layout:
flex: 1 1 0
properties:
title: Custom Header Background
theme:
colorTextHeading: "#389e0d"
blocks:
- id: theme_colored_header_p
type: Paragraph
properties:
content: The headerBg token changes the card header background color, and
colorTextHeading changes the title text color. These apply through the
antd theme system.
- id: theme_rounded
type: Card
layout:
flex: 1 1 0
properties:
title: Extra Rounded
theme:
borderRadiusLG: 20
blocks:
- id: theme_rounded_p
type: Paragraph
properties:
content: The borderRadiusLG token controls the card corner radius. Set a large
value for a pill-like card appearance.
- id: theme_dense
type: Card
layout:
flex: 1 1 0
properties:
title: Dense Card
size: small
theme:
bodyPaddingSM: 8
headerPaddingSM: 8
headerHeightSM: 32
headerFontSizeSM: 12
blocks:
- id: theme_dense_p
type: Paragraph
properties:
content: Combine the small size variant with custom SM tokens for an
ultra-compact card. Useful for data-dense dashboards.
- id: theme_custom_colors
type: Card
properties:
title: Custom Color Scheme
theme:
colorTextHeading: "#d46b08"
colorText: "#874d00"
colorBorderSecondary: "#ffd591"
blocks:
- id: theme_custom_colors_p
type: Paragraph
properties:
content: A warm-toned card using theme tokens to customize the background,
header, text, and border colors. Theme tokens cascade correctly
through the antd design system.
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `bordered` | boolean | `true` | Toggles rendering of the border around the card. `bordered: false` is the same as `variant: borderless`. |
| `hoverable` | boolean | `false` | Lift up when hovering card. |
| `loading` | boolean | `false` | Show a loading skeleton in place of the card content. |
| `inner` | boolean | `false` | Change the card style to inner. |
| `padding` | string | `"default"` | Space inside the card body. `compact` tightens the body to 12px and aligns the header with it. `none` removes the body padding so content such as a table, list or image runs edge to edge; the header keeps its padding. Enum: `default`, `compact`, `none`. |
| `size` | string | `"default"` | Size of the card. Enum: `default`, `small`. |
| `title` | string | - | Title to show in the title area - supports html. Overwritten by blocks in the title content area. |
| `variant` | string | `"outlined"` | Card style variant. Enum: `outlined`, `borderless`. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design card tokens](https://ant.design/components/card#design-token). |
| `theme.headerBg` | string | `"transparent"` | Background color of the card header. |
| `theme.headerFontSize` | number | `16` | Font size of the card header title. |
| `theme.headerFontSizeSM` | number | `14` | Font size of the card header title for small cards. |
| `theme.headerHeight` | number | `56` | Height of the card header. |
| `theme.headerHeightSM` | number | `38` | Height of the card header for small cards. |
| `theme.actionsBg` | string | `"#ffffff"` | Background color of the card actions area. |
| `theme.actionsLiMargin` | string | `"12px 0"` | Margin of each action item in the card actions area. |
| `theme.tabsMarginBottom` | number | `-17` | Bottom margin adjustment for tabs in the card. |
| `theme.extraColor` | string | `"rgba(0,0,0,0.88)"` | Text color for the extra content area in the header. |
| `theme.bodyPadding` | number \| string | `24` | Padding of the card body: a number of pixels, or a CSS padding string such as `28px 32px`. |
| `theme.bodyPaddingSM` | number \| string | `12` | Padding of the card body for small cards. |
| `theme.headerPadding` | number | `24` | Horizontal padding of the card header. |
| `theme.headerPaddingSM` | number | `12` | Horizontal padding of the card header for small cards. |
| `theme.borderRadiusLG` | number | `8` | Border radius of the card. |
| `theme.colorBorderSecondary` | string | - | Border color of the card. |
| `theme.colorBgContainer` | string | - | Background color of the card body. |
| `theme.colorText` | string | - | Text color inside the card. |
| `theme.colorTextHeading` | string | - | Color of the card header title text. |
| `theme.boxShadowTertiary` | string | - | Shadow applied to the card on hover when hoverable is true. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onClick` | \- | Trigger actions when the Card is clicked. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Card element. |
| `/header` | The Card header. |
| `/title` | The Card title. |
| `/body` | The Card body. |
| `/cover` | The Card cover. |
| `/actions` | The Card actions. |
| `/extra` | The Card extra content. |
| Slot | Description |
| --- | --- |
| `actions` | Action bar at the bottom of the card. |
| `content` | Main Card body. |
| `cover` | Image or content above the body. |
| `extra` | Extra content in the top-right header. |
| `title` | Title area. Overrides the title property. |
---
url: https://docs.lowdefy.com/md/container-blocks/carousel.md
---
# Carousel
Carousel slider with autoplay, dots, and transition effects.
Slide 1
Slide 2
Slide 3
Slide 4
```yaml
- id: basic_carousel
type: Carousel
slots:
basic_s1:
blocks:
- id: basic_s1
type: Box
style:
height: 160
background: "#364d79"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: basic_s1_text
type: Title
properties:
content: Slide 1
level: 3
style:
color: white
basic_s2:
blocks:
- id: basic_s2
type: Box
style:
height: 160
background: "#263c5a"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: basic_s2_text
type: Title
properties:
content: Slide 2
level: 3
style:
color: white
basic_s3:
blocks:
- id: basic_s3
type: Box
style:
height: 160
background: "#1a2d45"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: basic_s3_text
type: Title
properties:
content: Slide 3
level: 3
style:
color: white
basic_s4:
blocks:
- id: basic_s4
type: Box
style:
height: 160
background: "#0d1e30"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: basic_s4_text
type: Title
properties:
content: Slide 4
level: 3
style:
color: white
```
Blue
Green
Purple
Volcano
Magenta
```yaml
- id: color_carousel
type: Carousel
slots:
color_s1:
blocks:
- id: color_s1
type: Box
style:
height: 180
background: "#1677ff"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: color_s1_text
type: Title
properties:
content: Blue
level: 3
style:
color: white
color_s2:
blocks:
- id: color_s2
type: Box
style:
height: 180
background: "#52c41a"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: color_s2_text
type: Title
properties:
content: Green
level: 3
style:
color: white
color_s3:
blocks:
- id: color_s3
type: Box
style:
height: 180
background: "#722ed1"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: color_s3_text
type: Title
properties:
content: Purple
level: 3
style:
color: white
color_s4:
blocks:
- id: color_s4
type: Box
style:
height: 180
background: "#fa541c"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: color_s4_text
type: Title
properties:
content: Volcano
level: 3
style:
color: white
color_s5:
blocks:
- id: color_s5
type: Box
style:
height: 180
background: "#eb2f96"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: color_s5_text
type: Title
properties:
content: Magenta
level: 3
style:
color: white
```
Auto Slide 1
Auto Slide 2
Auto Slide 3
Auto Slide 4
```yaml
- id: auto_carousel
type: Carousel
properties:
autoplay: true
autoplaySpeed: 2000
slots:
auto_s1:
blocks:
- id: auto_s1
type: Box
style:
height: 160
background: "#13c2c2"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: auto_s1_text
type: Title
properties:
content: Auto Slide 1
level: 3
style:
color: white
auto_s2:
blocks:
- id: auto_s2
type: Box
style:
height: 160
background: "#1677ff"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: auto_s2_text
type: Title
properties:
content: Auto Slide 2
level: 3
style:
color: white
auto_s3:
blocks:
- id: auto_s3
type: Box
style:
height: 160
background: "#722ed1"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: auto_s3_text
type: Title
properties:
content: Auto Slide 3
level: 3
style:
color: white
auto_s4:
blocks:
- id: auto_s4
type: Box
style:
height: 160
background: "#eb2f96"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: auto_s4_text
type: Title
properties:
content: Auto Slide 4
level: 3
style:
color: white
```
The active dot fills until the next slide
Second slide
```yaml
- id: dot_duration_carousel
type: Carousel
properties:
autoplay:
dotDuration: true
autoplaySpeed: 4000
slots:
progress_s1:
blocks:
- id: progress_s1
type: Box
style:
height: 160
background: "#1677ff"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: progress_s1_text
type: Title
properties:
content: The active dot fills until the next slide
level: 4
style:
color: white
progress_s2:
blocks:
- id: progress_s2
type: Box
style:
height: 160
background: "#722ed1"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: progress_s2_text
type: Title
properties:
content: Second slide
level: 4
style:
color: white
```
Hover to Pause
Autoplay Resumes
On Mouse Leave
```yaml
- id: pause_carousel
type: Carousel
properties:
autoplay: true
autoplaySpeed: 1500
pauseOnHover: true
pauseOnFocus: true
slots:
pause_s1:
blocks:
- id: pause_s1
type: Box
style:
height: 160
background: "#389e0d"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: pause_s1_text
type: Title
properties:
content: Hover to Pause
level: 3
style:
color: white
pause_s2:
blocks:
- id: pause_s2
type: Box
style:
height: 160
background: "#08979c"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: pause_s2_text
type: Title
properties:
content: Autoplay Resumes
level: 3
style:
color: white
pause_s3:
blocks:
- id: pause_s3
type: Box
style:
height: 160
background: "#531dab"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: pause_s3_text
type: Title
properties:
content: On Mouse Leave
level: 3
style:
color: white
```
Dots on Top
Navigation Above
Slide Content
```yaml
- id: dot_top_carousel
type: Carousel
properties:
dotPosition: top
slots:
dot_top_s1:
blocks:
- id: dot_top_s1
type: Box
style:
height: 160
background: "#fa8c16"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: dot_top_s1_text
type: Title
properties:
content: Dots on Top
level: 3
style:
color: white
dot_top_s2:
blocks:
- id: dot_top_s2
type: Box
style:
height: 160
background: "#d46b08"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: dot_top_s2_text
type: Title
properties:
content: Navigation Above
level: 3
style:
color: white
dot_top_s3:
blocks:
- id: dot_top_s3
type: Box
style:
height: 160
background: "#ad4e00"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: dot_top_s3_text
type: Title
properties:
content: Slide Content
level: 3
style:
color: white
```
Dots on Left
Vertical Dots
Side Navigation
```yaml
- id: dot_left_carousel
type: Carousel
properties:
dotPosition: left
slots:
dot_left_s1:
blocks:
- id: dot_left_s1
type: Box
style:
height: 200
background: "#13c2c2"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: dot_left_s1_text
type: Title
properties:
content: Dots on Left
level: 3
style:
color: white
dot_left_s2:
blocks:
- id: dot_left_s2
type: Box
style:
height: 200
background: "#006d75"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: dot_left_s2_text
type: Title
properties:
content: Vertical Dots
level: 3
style:
color: white
dot_left_s3:
blocks:
- id: dot_left_s3
type: Box
style:
height: 200
background: "#00474f"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: dot_left_s3_text
type: Title
properties:
content: Side Navigation
level: 3
style:
color: white
```
Dots on Right
Right Aligned
Navigation
```yaml
- id: dot_right_carousel
type: Carousel
properties:
dotPosition: right
slots:
dot_right_s1:
blocks:
- id: dot_right_s1
type: Box
style:
height: 200
background: "#eb2f96"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: dot_right_s1_text
type: Title
properties:
content: Dots on Right
level: 3
style:
color: white
dot_right_s2:
blocks:
- id: dot_right_s2
type: Box
style:
height: 200
background: "#c41d7f"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: dot_right_s2_text
type: Title
properties:
content: Right Aligned
level: 3
style:
color: white
dot_right_s3:
blocks:
- id: dot_right_s3
type: Box
style:
height: 200
background: "#9e1068"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: dot_right_s3_text
type: Title
properties:
content: Navigation
level: 3
style:
color: white
```
Fade Transition
Smooth Crossfade
Between Slides
```yaml
- id: fade_carousel
type: Carousel
properties:
effect: fade
slots:
fade_s1:
blocks:
- id: fade_s1
type: Box
style:
height: 180
background: "#531dab"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fade_s1_text
type: Title
properties:
content: Fade Transition
level: 3
style:
color: white
fade_s2:
blocks:
- id: fade_s2
type: Box
style:
height: 180
background: "#08979c"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fade_s2_text
type: Title
properties:
content: Smooth Crossfade
level: 3
style:
color: white
fade_s3:
blocks:
- id: fade_s3
type: Box
style:
height: 180
background: "#d4380d"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fade_s3_text
type: Title
properties:
content: Between Slides
level: 3
style:
color: white
```
Gradient Violet
Gradient Pink
Gradient Cyan
Gradient Mint
```yaml
- id: fade_auto_carousel
type: Carousel
properties:
effect: fade
autoplay: true
autoplaySpeed: 2500
slots:
fade_auto_s1:
blocks:
- id: fade_auto_s1
type: Box
style:
height: 180
background: linear-gradient(135deg,
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fade_auto_s1_text
type: Title
properties:
content: Gradient Violet
level: 3
style:
color: white
fade_auto_s2:
blocks:
- id: fade_auto_s2
type: Box
style:
height: 180
background: linear-gradient(135deg,
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fade_auto_s2_text
type: Title
properties:
content: Gradient Pink
level: 3
style:
color: white
fade_auto_s3:
blocks:
- id: fade_auto_s3
type: Box
style:
height: 180
background: linear-gradient(135deg,
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fade_auto_s3_text
type: Title
properties:
content: Gradient Cyan
level: 3
style:
color: white
fade_auto_s4:
blocks:
- id: fade_auto_s4
type: Box
style:
height: 180
background: linear-gradient(135deg,
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fade_auto_s4_text
type: Title
properties:
content: Gradient Mint
level: 3
style:
color: white
```
Navigate with Arrows
Click Left or Right
To Change Slides
Arrow Navigation
```yaml
- id: arrows_carousel
type: Carousel
properties:
arrows: true
slots:
arrows_s1:
blocks:
- id: arrows_s1
type: Box
style:
height: 180
background: "#389e0d"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: arrows_s1_text
type: Title
properties:
content: Navigate with Arrows
level: 3
style:
color: white
arrows_s2:
blocks:
- id: arrows_s2
type: Box
style:
height: 180
background: "#1d39c4"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: arrows_s2_text
type: Title
properties:
content: Click Left or Right
level: 3
style:
color: white
arrows_s3:
blocks:
- id: arrows_s3
type: Box
style:
height: 180
background: "#c41d7f"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: arrows_s3_text
type: Title
properties:
content: To Change Slides
level: 3
style:
color: white
arrows_s4:
blocks:
- id: arrows_s4
type: Box
style:
height: 180
background: "#d4380d"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: arrows_s4_text
type: Title
properties:
content: Arrow Navigation
level: 3
style:
color: white
```
Arrows Only
No Dot Indicators
Clean Navigation
```yaml
- id: arrows_nodots_carousel
type: Carousel
properties:
arrows: true
dots: false
slots:
arrows_nodots_s1:
blocks:
- id: arrows_nodots_s1
type: Box
style:
height: 160
background: "#faad14"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: arrows_nodots_s1_text
type: Title
properties:
content: Arrows Only
level: 3
style:
color: white
arrows_nodots_s2:
blocks:
- id: arrows_nodots_s2
type: Box
style:
height: 160
background: "#d48806"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: arrows_nodots_s2_text
type: Title
properties:
content: No Dot Indicators
level: 3
style:
color: white
arrows_nodots_s3:
blocks:
- id: arrows_nodots_s3
type: Box
style:
height: 160
background: "#ad6800"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: arrows_nodots_s3_text
type: Title
properties:
content: Clean Navigation
level: 3
style:
color: white
```
1
2
3
4
5
6
```yaml
- id: multi_carousel
type: Carousel
properties:
slidesToShow: 3
slidesToScroll: 1
slots:
multi_s1:
blocks:
- id: multi_s1
type: Box
style:
height: 140
background: "#1677ff"
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
blocks:
- id: multi_s1_text
type: Title
properties:
content: "1"
level: 3
style:
color: white
multi_s2:
blocks:
- id: multi_s2
type: Box
style:
height: 140
background: "#4096ff"
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
blocks:
- id: multi_s2_text
type: Title
properties:
content: "2"
level: 3
style:
color: white
multi_s3:
blocks:
- id: multi_s3
type: Box
style:
height: 140
background: "#69b1ff"
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
blocks:
- id: multi_s3_text
type: Title
properties:
content: "3"
level: 3
style:
color: white
multi_s4:
blocks:
- id: multi_s4
type: Box
style:
height: 140
background: "#91caff"
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
blocks:
- id: multi_s4_text
type: Title
properties:
content: "4"
level: 3
style:
color: white
multi_s5:
blocks:
- id: multi_s5
type: Box
style:
height: 140
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
blocks:
- id: multi_s5_text
type: Title
properties:
content: "5"
level: 3
style:
color: "#1677ff"
multi_s6:
blocks:
- id: multi_s6
type: Box
style:
height: 140
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
blocks:
- id: multi_s6_text
type: Title
properties:
content: "6"
level: 3
style:
color: "#1677ff"
```
First Slide
Middle Slide
Last Slide (Stops Here)
```yaml
- id: finite_carousel
type: Carousel
properties:
infinite: false
arrows: true
slots:
finite_s1:
blocks:
- id: finite_s1
type: Box
style:
height: 160
background: "#cf1322"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: finite_s1_text
type: Title
properties:
content: First Slide
level: 3
style:
color: white
finite_s2:
blocks:
- id: finite_s2
type: Box
style:
height: 160
background: "#a8071a"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: finite_s2_text
type: Title
properties:
content: Middle Slide
level: 3
style:
color: white
finite_s3:
blocks:
- id: finite_s3
type: Box
style:
height: 160
background: "#820014"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: finite_s3_text
type: Title
properties:
content: Last Slide (Stops Here)
level: 3
style:
color: white
```
Launch Fast
Build and deploy web apps in record time with config-driven development.
Production Ready
Enterprise-grade applications with built-in auth, roles, and security.
Connect Anything
Integrate with databases, REST APIs, and GraphQL endpoints effortlessly.
```yaml
- id: rich_carousel
type: Carousel
properties:
autoplay: true
autoplaySpeed: 4000
slots:
rich_s1:
blocks:
- id: rich_s1
type: Box
style:
height: 220
background: linear-gradient(135deg,
display: flex
flexDirection: column
alignItems: center
justifyContent: center
padding: 24px
blocks:
- id: rich_s1_icon
type: Icon
properties:
name: Rocket
size: 40
color: white
- id: rich_s1_title
type: Title
properties:
content: Launch Fast
level: 3
style:
color: white
marginTop: 12
marginBottom: 0
- id: rich_s1_desc
type: Paragraph
properties:
content: Build and deploy web apps in record time with config-driven
development.
style:
color: rgba(255, 255, 255, 0.85)
textAlign: center
maxWidth: 400
rich_s2:
blocks:
- id: rich_s2
type: Box
style:
height: 220
background: linear-gradient(135deg,
display: flex
flexDirection: column
alignItems: center
justifyContent: center
padding: 24px
blocks:
- id: rich_s2_icon
type: Icon
properties:
name: check-circle
size: 40
color: white
- id: rich_s2_title
type: Title
properties:
content: Production Ready
level: 3
style:
color: white
marginTop: 12
marginBottom: 0
- id: rich_s2_desc
type: Paragraph
properties:
content: Enterprise-grade applications with built-in auth, roles, and security.
style:
color: rgba(255, 255, 255, 0.85)
textAlign: center
maxWidth: 400
rich_s3:
blocks:
- id: rich_s3
type: Box
style:
height: 220
background: linear-gradient(135deg,
display: flex
flexDirection: column
alignItems: center
justifyContent: center
padding: 24px
blocks:
- id: rich_s3_icon
type: Icon
properties:
name: Plug
size: 40
color: white
- id: rich_s3_title
type: Title
properties:
content: Connect Anything
level: 3
style:
color: white
marginTop: 12
marginBottom: 0
- id: rich_s3_desc
type: Paragraph
properties:
content: Integrate with databases, REST APIs, and GraphQL endpoints
effortlessly.
style:
color: rgba(255, 255, 255, 0.85)
textAlign: center
maxWidth: 400
```
Monitor your app metrics and KPIs at a glance with customizable widgets and real-time data.
Handle roles, permissions, and team invitations with a built-in authentication layer.
Create complex multi-step forms with validation, conditional logic, and file uploads.
Automate business processes with triggers, conditions, and multi-step action sequences.
```yaml
- id: card_carousel
type: Carousel
properties:
slidesToShow: 2
slidesToScroll: 1
arrows: true
slots:
card_s1:
blocks:
- id: card_s1
type: Box
style:
padding: 12px
blocks:
- id: card_s1_card
type: Card
properties:
title: Dashboard
bordered: true
blocks:
- id: card_s1_card_desc
type: Paragraph
properties:
content: Monitor your app metrics and KPIs at a glance with customizable widgets
and real-time data.
- id: card_s1_card_tag
type: Tag
properties:
title: Analytics
color: blue
card_s2:
blocks:
- id: card_s2
type: Box
style:
padding: 12px
blocks:
- id: card_s2_card
type: Card
properties:
title: User Management
bordered: true
blocks:
- id: card_s2_card_desc
type: Paragraph
properties:
content: Handle roles, permissions, and team invitations with a built-in
authentication layer.
- id: card_s2_card_tag
type: Tag
properties:
title: Security
color: green
card_s3:
blocks:
- id: card_s3
type: Box
style:
padding: 12px
blocks:
- id: card_s3_card
type: Card
properties:
title: Form Builder
bordered: true
blocks:
- id: card_s3_card_desc
type: Paragraph
properties:
content: Create complex multi-step forms with validation, conditional logic, and
file uploads.
- id: card_s3_card_tag
type: Tag
properties:
title: Input
color: purple
card_s4:
blocks:
- id: card_s4
type: Box
style:
padding: 12px
blocks:
- id: card_s4_card
type: Card
properties:
title: Workflow Engine
bordered: true
blocks:
- id: card_s4_card_desc
type: Paragraph
properties:
content: Automate business processes with triggers, conditions, and multi-step
action sequences.
- id: card_s4_card_tag
type: Tag
properties:
title: Automation
color: orange
```
Soft Blue
Fresh Lime
Warm Sunset
Lavender Mist
Coral Sunrise
```yaml
- id: gradient_carousel
type: Carousel
properties:
effect: fade
autoplay: true
autoplaySpeed: 3000
slots:
grad_s1:
blocks:
- id: grad_s1
type: Box
style:
height: 200
background: linear-gradient(120deg,
display: flex
alignItems: center
justifyContent: center
blocks:
- id: grad_s1_text
type: Title
properties:
content: Soft Blue
level: 2
style:
color: "#1d39c4"
grad_s2:
blocks:
- id: grad_s2
type: Box
style:
height: 200
background: linear-gradient(120deg,
display: flex
alignItems: center
justifyContent: center
blocks:
- id: grad_s2_text
type: Title
properties:
content: Fresh Lime
level: 2
style:
color: "#135200"
grad_s3:
blocks:
- id: grad_s3
type: Box
style:
height: 200
background: linear-gradient(120deg,
display: flex
alignItems: center
justifyContent: center
blocks:
- id: grad_s3_text
type: Title
properties:
content: Warm Sunset
level: 2
style:
color: "#610b00"
grad_s4:
blocks:
- id: grad_s4
type: Box
style:
height: 200
background: linear-gradient(120deg,
display: flex
alignItems: center
justifyContent: center
blocks:
- id: grad_s4_text
type: Title
properties:
content: Lavender Mist
level: 2
style:
color: "#391085"
grad_s5:
blocks:
- id: grad_s5
type: Box
style:
height: 200
background: linear-gradient(120deg,
display: flex
alignItems: center
justifyContent: center
blocks:
- id: grad_s5_text
type: Title
properties:
content: Coral Sunrise
level: 2
style:
color: white
```
Drag to Navigate
Click and Drag
On Desktop
Swipe on Mobile
```yaml
- id: drag_carousel
type: Carousel
properties:
draggable: true
swipeToSlide: true
slots:
drag_s1:
blocks:
- id: drag_s1
type: Box
style:
height: 160
background: "#2f54eb"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: drag_s1_text
type: Title
properties:
content: Drag to Navigate
level: 3
style:
color: white
drag_s2:
blocks:
- id: drag_s2
type: Box
style:
height: 160
background: "#597ef7"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: drag_s2_text
type: Title
properties:
content: Click and Drag
level: 3
style:
color: white
drag_s3:
blocks:
- id: drag_s3
type: Box
style:
height: 160
background: "#85a5ff"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: drag_s3_text
type: Title
properties:
content: On Desktop
level: 3
style:
color: white
drag_s4:
blocks:
- id: drag_s4
type: Box
style:
height: 160
display: flex
alignItems: center
justifyContent: center
blocks:
- id: drag_s4_text
type: Title
properties:
content: Swipe on Mobile
level: 3
style:
color: "#2f54eb"
```
Center Mode
Peek at Adjacent
Slide Previews
With Padding
```yaml
- id: center_carousel
type: Carousel
properties:
centerMode: true
centerPadding: 60px
slidesToShow: 1
slots:
center_s1:
blocks:
- id: center_s1
type: Box
style:
height: 160
background: "#faad14"
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
borderRadius: 8
blocks:
- id: center_s1_text
type: Title
properties:
content: Center Mode
level: 3
style:
color: white
center_s2:
blocks:
- id: center_s2
type: Box
style:
height: 160
background: "#d48806"
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
borderRadius: 8
blocks:
- id: center_s2_text
type: Title
properties:
content: Peek at Adjacent
level: 3
style:
color: white
center_s3:
blocks:
- id: center_s3
type: Box
style:
height: 160
background: "#ad6800"
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
borderRadius: 8
blocks:
- id: center_s3_text
type: Title
properties:
content: Slide Previews
level: 3
style:
color: white
center_s4:
blocks:
- id: center_s4
type: Box
style:
height: 160
background: "#874d00"
display: flex
alignItems: center
justifyContent: center
margin: 0 8px
borderRadius: 8
blocks:
- id: center_s4_text
type: Title
properties:
content: With Padding
level: 3
style:
color: white
```
Tailwind Gradients
Use Tailwind utility classes on slides
Green to Cyan
Combine class and style for full control
Rose to Orange
Beautiful color transitions
Violet to Fuchsia
Rich purple gradients
```yaml
- id: css_carousel
type: Carousel
slots:
css_s1:
blocks:
- id: css_s1
type: Box
class: bg-gradient-to-br from-primary/100 to-indigo-600
style:
height: 200
display: flex
flexDirection: column
alignItems: center
justifyContent: center
blocks:
- id: css_s1_title
type: Title
properties:
content: Tailwind Gradients
level: 2
style:
color: white
marginBottom: 0
- id: css_s1_sub
type: Paragraph
properties:
content: Use Tailwind utility classes on slides
style:
color: rgba(255, 255, 255, 0.8)
css_s2:
blocks:
- id: css_s2
type: Box
class: bg-gradient-to-br from-emerald-400 to-cyan-500
style:
height: 200
display: flex
flexDirection: column
alignItems: center
justifyContent: center
blocks:
- id: css_s2_title
type: Title
properties:
content: Green to Cyan
level: 2
style:
color: white
marginBottom: 0
- id: css_s2_sub
type: Paragraph
properties:
content: Combine class and style for full control
style:
color: rgba(255, 255, 255, 0.8)
css_s3:
blocks:
- id: css_s3
type: Box
class: bg-gradient-to-br from-rose-400 to-orange-400
style:
height: 200
display: flex
flexDirection: column
alignItems: center
justifyContent: center
blocks:
- id: css_s3_title
type: Title
properties:
content: Rose to Orange
level: 2
style:
color: white
marginBottom: 0
- id: css_s3_sub
type: Paragraph
properties:
content: Beautiful color transitions
style:
color: rgba(255, 255, 255, 0.8)
css_s4:
blocks:
- id: css_s4
type: Box
class: bg-gradient-to-br from-violet-500 to-fuchsia-500
style:
height: 200
display: flex
flexDirection: column
alignItems: center
justifyContent: center
blocks:
- id: css_s4_title
type: Title
properties:
content: Violet to Fuchsia
level: 2
style:
color: white
marginBottom: 0
- id: css_s4_sub
type: Paragraph
properties:
content: Rich purple gradients
style:
color: rgba(255, 255, 255, 0.8)
```
**Slow transition (1500ms):**
Slow and Smooth
Ease In Out
1.5 Second Slide
**Fast transition (200ms):**
Quick Snap
200ms Transition
Instant Feel
```yaml
- id: speed_label
type: Markdown
properties:
content: "**Slow transition (1500ms):**"
- id: slow_carousel
type: Carousel
properties:
speed: 1500
easing: ease-in-out
slots:
slow_s1:
blocks:
- id: slow_s1
type: Box
style:
height: 140
background: "#595959"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: slow_s1_text
type: Title
properties:
content: Slow and Smooth
level: 3
style:
color: white
slow_s2:
blocks:
- id: slow_s2
type: Box
style:
height: 140
background: "#434343"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: slow_s2_text
type: Title
properties:
content: Ease In Out
level: 3
style:
color: white
slow_s3:
blocks:
- id: slow_s3
type: Box
style:
height: 140
background: "#262626"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: slow_s3_text
type: Title
properties:
content: 1.5 Second Slide
level: 3
style:
color: white
- id: fast_label
type: Markdown
properties:
content: "**Fast transition (200ms):**"
- id: fast_carousel
type: Carousel
properties:
speed: 200
slots:
fast_s1:
blocks:
- id: fast_s1
type: Box
style:
height: 140
background: "#ff4d4f"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fast_s1_text
type: Title
properties:
content: Quick Snap
level: 3
style:
color: white
fast_s2:
blocks:
- id: fast_s2
type: Box
style:
height: 140
background: "#ff7875"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fast_s2_text
type: Title
properties:
content: 200ms Transition
level: 3
style:
color: white
fast_s3:
blocks:
- id: fast_s3
type: Box
style:
height: 140
background: "#ffa39e"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: fast_s3_text
type: Title
properties:
content: Instant Feel
level: 3
style:
color: "#cf1322"
```
Large Dots
Custom Indicators
More Visible
```yaml
- id: theme_large_dots_carousel
type: Carousel
properties:
theme:
dotWidth: 24
dotHeight: 6
dotActiveWidth: 40
slots:
theme_ld_s1:
blocks:
- id: theme_ld_s1
type: Box
style:
height: 160
background: "#1677ff"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_ld_s1_text
type: Title
properties:
content: Large Dots
level: 3
style:
color: white
theme_ld_s2:
blocks:
- id: theme_ld_s2
type: Box
style:
height: 160
background: "#4096ff"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_ld_s2_text
type: Title
properties:
content: Custom Indicators
level: 3
style:
color: white
theme_ld_s3:
blocks:
- id: theme_ld_s3
type: Box
style:
height: 160
background: "#69b1ff"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_ld_s3_text
type: Title
properties:
content: More Visible
level: 3
style:
color: white
```
Round Dots
Circular Indicators
Same Width Active
```yaml
- id: theme_round_dots_carousel
type: Carousel
properties:
theme:
dotWidth: 12
dotHeight: 12
dotActiveWidth: 12
slots:
theme_rd_s1:
blocks:
- id: theme_rd_s1
type: Box
style:
height: 160
background: "#52c41a"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_rd_s1_text
type: Title
properties:
content: Round Dots
level: 3
style:
color: white
theme_rd_s2:
blocks:
- id: theme_rd_s2
type: Box
style:
height: 160
background: "#73d13d"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_rd_s2_text
type: Title
properties:
content: Circular Indicators
level: 3
style:
color: white
theme_rd_s3:
blocks:
- id: theme_rd_s3
type: Box
style:
height: 160
background: "#95de64"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_rd_s3_text
type: Title
properties:
content: Same Width Active
level: 3
style:
color: "#135200"
```
Larger Arrows
More Prominent
Navigation Controls
```yaml
- id: theme_large_arrows_carousel
type: Carousel
properties:
arrows: true
theme:
arrowSize: 24
arrowOffset: 16
slots:
theme_la_s1:
blocks:
- id: theme_la_s1
type: Box
style:
height: 180
background: "#722ed1"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_la_s1_text
type: Title
properties:
content: Larger Arrows
level: 3
style:
color: white
theme_la_s2:
blocks:
- id: theme_la_s2
type: Box
style:
height: 180
background: "#9254de"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_la_s2_text
type: Title
properties:
content: More Prominent
level: 3
style:
color: white
theme_la_s3:
blocks:
- id: theme_la_s3
type: Box
style:
height: 180
background: "#b37feb"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_la_s3_text
type: Title
properties:
content: Navigation Controls
level: 3
style:
color: white
```
Spaced Dots
Wide Gap
More Offset
Custom Spacing
```yaml
- id: theme_spaced_dots_carousel
type: Carousel
properties:
theme:
dotGap: 12
dotOffset: 20
dotWidth: 20
dotHeight: 4
dotActiveWidth: 36
slots:
theme_sd_s1:
blocks:
- id: theme_sd_s1
type: Box
style:
height: 160
background: "#eb2f96"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_sd_s1_text
type: Title
properties:
content: Spaced Dots
level: 3
style:
color: white
theme_sd_s2:
blocks:
- id: theme_sd_s2
type: Box
style:
height: 160
background: "#f759ab"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_sd_s2_text
type: Title
properties:
content: Wide Gap
level: 3
style:
color: white
theme_sd_s3:
blocks:
- id: theme_sd_s3
type: Box
style:
height: 160
background: "#ff85c0"
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_sd_s3_text
type: Title
properties:
content: More Offset
level: 3
style:
color: white
theme_sd_s4:
blocks:
- id: theme_sd_s4
type: Box
style:
height: 160
display: flex
alignItems: center
justifyContent: center
blocks:
- id: theme_sd_s4_text
type: Title
properties:
content: Custom Spacing
level: 3
style:
color: "#c41d7f"
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `accessibility` | boolean | `true` | Enable tabbing and arrow key navigation. |
| `adaptiveHeight` | boolean | `false` | Adjust the slide's height automatically. |
| `arrows` | boolean | `false` | Whether or not to show arrows. |
| `autoplaySpeed` | integer | `3000` | Delay between each auto scroll (in milliseconds). |
| `autoplay` | boolean \| object | `false` | Toggles whether or not to scroll automatically. Set to `{ dotDuration: true }` to show the time until the next slide as a progress bar in the active dot. |
| `autoplay.dotDuration` | boolean | `false` | Show the autoplay progress in the active dot. |
| `centerMode` | boolean | `false` | Center current slide. |
| `centerPadding` | string | `"50px"` | Padding applied to center slide. |
| `dotPosition` | string | `"bottom"` | The position of the dots, which can be one of top, bottom, left or right. Left and right dots make the carousel vertical. Enum: `left`, `right`, `top`, `bottom`. |
| `dots` | boolean | `true` | Whether or not to show the dots. |
| `draggable` | boolean | `false` | Enable scrollable via dragging on desktop |
| `easing` | string | `"linear"` | Transition interpolation function name. |
| `effect` | string | `"scrollx"` | Transition effect, either scrollx or fade. |
| `focusOnSelect` | boolean | `false` | Go to slide on click. |
| `initialSlide` | integer | `0` | Index of the slide to show first. |
| `infinite` | boolean | `true` | Infinitely wrap around contents. |
| `pauseOnDotsHover` | boolean | `false` | Prevents autoplay while hovering on dot. |
| `pauseOnFocus` | boolean | `false` | Prevents autoplay while focused on slides. |
| `pauseOnHover` | boolean | `true` | Prevents autoplay while hovering on track. |
| `responsive` | array | `[]` | Customize based on breakpoints. |
| `responsive.$.breakpoint` | integer | - | Maximum screen size. |
| `responsive.$.settings` | object | - | Carousel properties. |
| `rows` | integer | `1` | Number of rows per slide in the slider, (enables grid mode). |
| `rtl` | boolean | `false` | Reverses the slide order. |
| `slides` | array | - | Optional list of slides for explicit ordering and metadata. Each entry must have a `key` matching a slot name. When omitted, every defined slot becomes a slide, ordered alphabetically by key. Each entry is passed to `afterChange` and `beforeChange` events as `event.current` and `event.next` — any extra fields on the entry (e.g. a title or analytics id) are available there. |
| `slides.$.key` | string | - | Slot key for this slide. |
| `slidesPerRow` | integer | `1` | Number of slides to display in grid mode, this is useful with rows option. |
| `slidesToScroll` | integer | `1` | How many slides to scroll at once. |
| `slidesToShow` | integer | `1` | How many slides to show in one frame. |
| `speed` | integer | `500` | Slide transition animation speed in milliseconds. |
| `swipeToSlide` | boolean | `false` | Enable drag/swipe irrespective of `slidesToScroll`. |
| `swipe` | boolean | `true` | Enable/disable swiping to change slides. |
| `vertical` | boolean | `false` | Whether or not the slides are shown in a column. |
| `waitForAnimate` | boolean | `false` | Ignore requests to change slide while a slide transition is animating. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design carousel tokens](https://ant.design/components/carousel#design-token). |
| `theme.dotWidth` | number | `16` | Width of the indicator dot. |
| `theme.dotHeight` | number | `3` | Height of the indicator dot. |
| `theme.dotGap` | number | `4` | Gap between indicator dots. |
| `theme.dotOffset` | number | `12` | Offset distance of dots from the carousel edge. |
| `theme.dotActiveWidth` | number | `24` | Width of the active indicator dot. |
| `theme.arrowSize` | number | `16` | Size of the navigation arrows. |
| `theme.arrowOffset` | number | `8` | Offset distance of arrows from the carousel edge. |
| `theme.colorBgContainer` | string | - | Background color used for indicator dots. |
| Event | Event Data | Description |
| --- | --- | --- |
| `afterChange` | \- | Trigger actions after the slide is changed. |
| `beforeChange` | \- | Trigger actions before the slide is changed. |
| `onInit` | \- | Trigger actions when the carousel is initialized. |
| `onSwipe` | `{ direction }` | Trigger actions when the user starts to swipe or drag the carousel. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Carousel element. |
Slot keys are user-defined in your config and resolved at build time — not generated at runtime. The block typically pairs slots with an array property (`tabs`, `panels`, `slides`) listed in the Properties table; see the examples above for the expected shape.
---
url: https://docs.lowdefy.com/md/container-blocks/collapse.md
---
# Collapse
Collapsible panels with accordion mode and custom icons.
A web application that enables team collaboration through shared workspaces, real-time messaging, and integrated task management across departments.
The platform supports up to 500 concurrent users with role-based access control and end-to-end encryption for all communications.
Node.js 18+, PostgreSQL 15, Redis 7 for caching, and a minimum of 4GB RAM for the development environment. Docker is recommended for local setup.
Phase 1 launches in Q2 2026 with core messaging and workspace features. Phase 2 adds analytics, reporting dashboards, and third-party integrations in Q3 2026.
```yaml
- id: basic_collapse
type: Collapse
properties:
panels:
- key: overview
title: Project Overview
- key: requirements
title: System Requirements
- key: timeline
title: Project Timeline
slots:
overview:
blocks:
- id: basic_overview_text
type: Paragraph
properties:
content: A web application that enables team collaboration through shared
workspaces, real-time messaging, and integrated task management
across departments.
- id: basic_overview_detail
type: Paragraph
properties:
content: The platform supports up to 500 concurrent users with role-based access
control and end-to-end encryption for all communications.
requirements:
blocks:
- id: basic_requirements_text
type: Paragraph
properties:
content: Node.js 18+, PostgreSQL 15, Redis 7 for caching, and a minimum of 4GB
RAM for the development environment. Docker is recommended for
local setup.
timeline:
blocks:
- id: basic_timeline_text
type: Paragraph
properties:
content: Phase 1 launches in Q2 2026 with core messaging and workspace features.
Phase 2 adds analytics, reporting dashboards, and third-party
integrations in Q3 2026.
```
Configure your display name, preferred language, and timezone. These settings apply across all devices linked to your account.
Choose which notifications you receive via email, push, or in-app messages. Set quiet hours to pause non-critical alerts.
Manage profile visibility, activity status display, and data sharing preferences. Enable two-factor authentication for added security.
Switch between light and dark themes, adjust font size, and customize the sidebar layout to match your workflow.
```yaml
- id: accordion_collapse
type: Collapse
properties:
accordion: true
panels:
- key: acc_general
title: General Settings
- key: acc_notifications
title: Notification Preferences
- key: acc_privacy
title: Privacy & Security
- key: acc_appearance
title: Appearance
slots:
acc_general:
blocks:
- id: accordion_general_text
type: Paragraph
properties:
content: Configure your display name, preferred language, and timezone. These
settings apply across all devices linked to your account.
acc_notifications:
blocks:
- id: accordion_notifications_text
type: Paragraph
properties:
content: Choose which notifications you receive via email, push, or in-app
messages. Set quiet hours to pause non-critical alerts.
acc_privacy:
blocks:
- id: accordion_privacy_text
type: Paragraph
properties:
content: Manage profile visibility, activity status display, and data sharing
preferences. Enable two-factor authentication for added security.
acc_appearance:
blocks:
- id: accordion_appearance_text
type: Paragraph
properties:
content: Switch between light and dark themes, adjust font size, and customize
the sidebar layout to match your workflow.
```
Sign up for a free account, complete the onboarding wizard, and deploy your first application in under five minutes using one of our starter templates.
We offer Free, Pro ($29/month), and Enterprise tiers. The Free plan includes unlimited development environments and up to 100 monthly active users.
Yes, the Pro plan includes a 14-day free trial with full access to all features. No credit card required to start.
Reach our support team via the in-app chat widget, email us at support@example.com, or visit the community forums for peer assistance.
```yaml
- id: default_active_collapse
type: Collapse
properties:
defaultActiveKey: da_started
panels:
- key: da_started
title: How do I get started?
- key: da_pricing
title: What are the pricing plans?
- key: da_trial
title: Is there a free trial?
- key: da_support
title: How do I contact support?
slots:
da_started:
blocks:
- id: default_active_started_text
type: Paragraph
properties:
content: Sign up for a free account, complete the onboarding wizard, and deploy
your first application in under five minutes using one of our
starter templates.
da_pricing:
blocks:
- id: default_active_pricing_text
type: Paragraph
properties:
content: We offer Free, Pro ($29/month), and Enterprise tiers. The Free plan
includes unlimited development environments and up to 100 monthly
active users.
da_trial:
blocks:
- id: default_active_trial_text
type: Paragraph
properties:
content: Yes, the Pro plan includes a 14-day free trial with full access to all
features. No credit card required to start.
da_support:
blocks:
- id: default_active_support_text
type: Paragraph
properties:
content: Reach our support team via the in-app chat widget, email us at
support@example.com, or visit the community forums for peer
assistance.
```
Founded in 2020, we build tools that make software development accessible to everyone regardless of technical background.
Our mission is to democratize application development through low-code and open-source technologies.
Founded in 2020, we build tools that make software development accessible to everyone regardless of technical background.
Our mission is to democratize application development through low-code and open-source technologies.
```yaml
- id: bordered_collapse
type: Collapse
properties:
bordered: true
panels:
- key: brd_about
title: About Us (Bordered)
- key: brd_mission
title: Our Mission
slots:
brd_about:
blocks:
- id: bordered_about_text
type: Paragraph
properties:
content: Founded in 2020, we build tools that make software development
accessible to everyone regardless of technical background.
brd_mission:
blocks:
- id: bordered_mission_text
type: Paragraph
properties:
content: Our mission is to democratize application development through low-code
and open-source technologies.
- id: borderless_collapse
type: Collapse
properties:
bordered: false
panels:
- key: bls_about
title: About Us (Borderless)
- key: bls_mission
title: Our Mission
slots:
bls_about:
blocks:
- id: borderless_about_text
type: Paragraph
properties:
content: Founded in 2020, we build tools that make software development
accessible to everyone regardless of technical background.
bls_mission:
blocks:
- id: borderless_mission_text
type: Paragraph
properties:
content: Our mission is to democratize application development through low-code
and open-source technologies.
```
Orders ship within two business days.
Unused items can be returned within 30 days.
Compact header and content padding.
Roomy header and content padding.
```yaml
- id: ghost_collapse
type: Collapse
properties:
ghost: true
panels:
- key: ghost_shipping
title: Shipping (ghost)
- key: ghost_returns
title: Returns
slots:
ghost_shipping:
blocks:
- id: ghost_shipping_text
type: Paragraph
properties:
content: Orders ship within two business days.
ghost_returns:
blocks:
- id: ghost_returns_text
type: Paragraph
properties:
content: Unused items can be returned within 30 days.
- id: small_collapse
type: Collapse
properties:
size: small
panels:
- key: small_panel
title: Small size
slots:
small_panel:
blocks:
- id: small_panel_text
type: Paragraph
properties:
content: Compact header and content padding.
- id: large_collapse
type: Collapse
properties:
size: large
panels:
- key: large_panel
title: Large size
slots:
large_panel:
blocks:
- id: large_panel_text
type: Paragraph
properties:
content: Roomy header and content padding.
```
With padding none, panel content sets its own spacing.
Tighter panel content, still aligned with the header.
```yaml
- id: padding_none_collapse
type: Collapse
properties:
padding: none
panels:
- key: padding_none_invoices
title: Invoices (padding none)
- key: padding_none_notes
title: Notes
slots:
padding_none_invoices:
blocks:
- id: padding_none_invoices_rows
type: Html
properties:
html: >
INV-1042 $1,280.00
INV-1041 $640.00
INV-1040 $2,115.50
INV-1039 $96.00
padding_none_notes:
blocks:
- id: padding_none_notes_text
type: Paragraph
class: px-4 py-2
properties:
content: With padding none, panel content sets its own spacing.
- id: padding_compact_collapse
type: Collapse
properties:
padding: compact
panels:
- key: padding_compact_panel
title: Compact padding
slots:
padding_compact_panel:
blocks:
- id: padding_compact_panel_text
type: Paragraph
properties:
content: Tighter panel content, still aligned with the header.
```
**Start (default):**
Premium wireless headphones with active noise cancellation, 30-hour battery life, and multipoint connection.
Bluetooth 5.3, 40mm custom drivers, frequency response 20Hz-40kHz, weight 250g, USB-C fast charging.
**End:**
Premium wireless headphones with active noise cancellation, 30-hour battery life, and multipoint connection.
Bluetooth 5.3, 40mm custom drivers, frequency response 20Hz-40kHz, weight 250g, USB-C fast charging.
```yaml
- id: icon_start_label
type: Markdown
properties:
content: "**Start (default):**"
- id: icon_start_collapse
type: Collapse
properties:
expandIconPlacement: start
panels:
- key: is_details
title: Product Details
- key: is_specs
title: Technical Specifications
slots:
is_details:
blocks:
- id: icon_start_details_text
type: Paragraph
properties:
content: Premium wireless headphones with active noise cancellation, 30-hour
battery life, and multipoint connection.
is_specs:
blocks:
- id: icon_start_specs_text
type: Paragraph
properties:
content: Bluetooth 5.3, 40mm custom drivers, frequency response 20Hz-40kHz,
weight 250g, USB-C fast charging.
- id: icon_end_label
type: Markdown
properties:
content: "**End:**"
- id: icon_end_collapse
type: Collapse
properties:
expandIconPlacement: end
panels:
- key: ie_details
title: Product Details
- key: ie_specs
title: Technical Specifications
slots:
ie_details:
blocks:
- id: icon_end_details_text
type: Paragraph
properties:
content: Premium wireless headphones with active noise cancellation, 30-hour
battery life, and multipoint connection.
ie_specs:
blocks:
- id: icon_end_specs_text
type: Paragraph
properties:
content: Bluetooth 5.3, 40mm custom drivers, frequency response 20Hz-40kHz,
weight 250g, USB-C fast charging.
```
Real-time collaboration, version history, automated backups, and a powerful API for custom integrations.
Connect with Slack, GitHub, Jira, Google Workspace, Figma, and over 200 other services via our marketplace.
Flexible per-seat pricing starting at $10/month. Volume discounts available for teams larger than 50 members.
The expand icon can be passed as an object with name and color properties for further customization.
The icon rotates 90 degrees when the panel is expanded, providing a visual cue for the open/closed state.
```yaml
- id: custom_icon_collapse
type: Collapse
properties:
expandIcon: add-circle
panels:
- key: ci_features
title: Key Features
- key: ci_integrations
title: Integrations
- key: ci_pricing
title: Pricing
slots:
ci_features:
blocks:
- id: custom_icon_features_text
type: Paragraph
properties:
content: Real-time collaboration, version history, automated backups, and a
powerful API for custom integrations.
ci_integrations:
blocks:
- id: custom_icon_integrations_text
type: Paragraph
properties:
content: Connect with Slack, GitHub, Jira, Google Workspace, Figma, and over 200
other services via our marketplace.
ci_pricing:
blocks:
- id: custom_icon_pricing_text
type: Paragraph
properties:
content: Flexible per-seat pricing starting at $10/month. Volume discounts
available for teams larger than 50 members.
- id: custom_icon_obj_collapse
type: Collapse
properties:
expandIcon:
name: arrow-right
color: "#1677ff"
panels:
- key: cio_one
title: Colored Custom Icon
- key: cio_two
title: Another Panel
slots:
cio_one:
blocks:
- id: custom_icon_obj_one_text
type: Paragraph
properties:
content: The expand icon can be passed as an object with name and color
properties for further customization.
cio_two:
blocks:
- id: custom_icon_obj_two_text
type: Paragraph
properties:
content: The icon rotates 90 degrees when the panel is expanded, providing a
visual cue for the open/closed state.
```
This section is accessible to all users and contains general product documentation and getting-started guides.
This content requires a Pro subscription to access.
Enterprise-only analytics and reporting features.
Community resources, FAQ, and links to the public knowledge base are available here for everyone.
```yaml
- id: disabled_collapse
type: Collapse
properties:
panels:
- key: dis_available
title: Available Section
- key: dis_locked
title: Locked Section (Upgrade Required)
disabled: true
- key: dis_premium
title: Premium Content
disabled: true
- key: dis_open
title: Another Available Section
slots:
dis_available:
blocks:
- id: disabled_available_text
type: Paragraph
properties:
content: This section is accessible to all users and contains general product
documentation and getting-started guides.
dis_locked:
blocks:
- id: disabled_locked_text
type: Paragraph
properties:
content: This content requires a Pro subscription to access.
dis_premium:
blocks:
- id: disabled_premium_text
type: Paragraph
properties:
content: Enterprise-only analytics and reporting features.
dis_open:
blocks:
- id: disabled_open_text
type: Paragraph
properties:
content: Community resources, FAQ, and links to the public knowledge base are
available here for everyone.
```
Visit the registration page and fill in your name, email, and a secure password. You will receive a verification email within minutes.
Choose a workspace name, select your industry, and configure default permissions for new members joining the organization.
Send invitation links via email or share a join code. Assign roles (Admin, Editor, Viewer) to control access levels.
```yaml
- id: no_arrow_collapse
type: Collapse
properties:
showArrow: false
panels:
- key: na_step1
title: Step 1 - Create Account
- key: na_step2
title: Step 2 - Configure Workspace
- key: na_step3
title: Step 3 - Invite Team Members
slots:
na_step1:
blocks:
- id: no_arrow_step1_text
type: Paragraph
properties:
content: Visit the registration page and fill in your name, email, and a secure
password. You will receive a verification email within minutes.
na_step2:
blocks:
- id: no_arrow_step2_text
type: Paragraph
properties:
content: Choose a workspace name, select your industry, and configure default
permissions for new members joining the organization.
na_step3:
blocks:
- id: no_arrow_step3_text
type: Paragraph
properties:
content: Send invitation links via email or share a join code. Assign roles
(Admin, Editor, Viewer) to control access levels.
```
Our cross-functional engineering team brings together expertise in frontend, backend, and DevOps.
Built with modern frameworks and battle-tested infrastructure components.
> All dependencies are pinned and audited weekly for security vulnerabilities.
Key delivery milestones for the current development cycle.
Internal testing release with core features — March 2026
Public beta with limited access and feedback collection — June 2026
General availability with full feature set and SLA guarantees — September 2026
```yaml
- id: rich_collapse
type: Collapse
properties:
panels:
- key: rich_team
title: Development Team
- key: rich_stack
title: Technology Stack
- key: rich_milestones
title: Project Milestones
slots:
rich_team:
blocks:
- id: rich_team_intro
type: Paragraph
properties:
content: Our cross-functional engineering team brings together expertise in
frontend, backend, and DevOps.
- id: rich_team_tags_row
type: Box
layout:
gap: 6
blocks:
- id: rich_team_tag_fe
type: Tag
properties:
title: Frontend
color: blue
- id: rich_team_tag_be
type: Tag
properties:
title: Backend
color: green
- id: rich_team_tag_devops
type: Tag
properties:
title: DevOps
color: orange
- id: rich_team_tag_qa
type: Tag
properties:
title: QA
color: purple
- id: rich_team_stat_row
type: Box
layout:
gap: 16
blocks:
- id: rich_team_stat_members
type: Statistic
layout:
flex: 0 0 auto
properties:
title: Team Members
value: 12
- id: rich_team_stat_sprints
type: Statistic
layout:
flex: 0 0 auto
properties:
title: Sprints Completed
value: 24
rich_stack:
blocks:
- id: rich_stack_desc
type: Paragraph
properties:
content: Built with modern frameworks and battle-tested infrastructure
components.
- id: rich_stack_tags_row
type: Box
layout:
gap: 6
blocks:
- id: rich_stack_tag_react
type: Tag
properties:
title: React 18
color: cyan
- id: rich_stack_tag_next
type: Tag
properties:
title: Next.js 14
color: default
- id: rich_stack_tag_pg
type: Tag
properties:
title: PostgreSQL
color: blue
- id: rich_stack_tag_redis
type: Tag
properties:
title: Redis
color: red
- id: rich_stack_tag_docker
type: Tag
properties:
title: Docker
color: geekblue
- id: rich_stack_note
type: Alert
properties:
message: All dependencies are pinned and audited weekly for security
vulnerabilities.
type: info
showIcon: true
rich_milestones:
blocks:
- id: rich_milestones_desc
type: Paragraph
properties:
content: Key delivery milestones for the current development cycle.
- id: rich_milestones_p1
type: Box
layout:
gap: 8
blocks:
- id: rich_milestone_alpha_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Alpha
color: orange
- id: rich_milestone_alpha_text
type: Paragraph
properties:
content: Internal testing release with core features — March 2026
- id: rich_milestones_p2
type: Box
layout:
gap: 8
blocks:
- id: rich_milestone_beta_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Beta
color: blue
- id: rich_milestone_beta_text
type: Paragraph
properties:
content: Public beta with limited access and feedback collection — June 2026
- id: rich_milestones_p3
type: Box
layout:
gap: 8
blocks:
- id: rich_milestone_ga_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: GA
color: green
- id: rich_milestone_ga_text
type: Paragraph
properties:
content: General availability with full feature set and SLA guarantees —
September 2026
```
Manage user accounts, assign roles, reset passwords, and review login activity across the organization.
View current subscription details, download invoices, update payment methods, and manage billing contacts.
Audit trail of all administrative actions including user changes, permission updates, and configuration modifications.
```yaml
- id: extra_collapse
type: Collapse
properties:
panels:
- key: ex_users
title: User Management
extraKey: ex_users_extra
- key: ex_billing
title: Billing & Invoices
extraKey: ex_billing_extra
- key: ex_logs
title: Activity Logs
extraKey: ex_logs_extra
slots:
ex_users:
blocks:
- id: extra_users_text
type: Paragraph
properties:
content: Manage user accounts, assign roles, reset passwords, and review login
activity across the organization.
ex_users_extra:
blocks:
- id: extra_users_badge
type: Tag
properties:
title: 48 users
color: blue
ex_billing:
blocks:
- id: extra_billing_text
type: Paragraph
properties:
content: View current subscription details, download invoices, update payment
methods, and manage billing contacts.
ex_billing_extra:
blocks:
- id: extra_billing_badge
type: Tag
properties:
title: Pro Plan
color: gold
ex_logs:
blocks:
- id: extra_logs_text
type: Paragraph
properties:
content: Audit trail of all administrative actions including user changes,
permission updates, and configuration modifications.
ex_logs_extra:
blocks:
- id: extra_logs_badge
type: Tag
properties:
title: 1,204 events
color: default
```
The frontend is organized into feature modules, each with its own routing, state management, and component library.
Shared UI components built with Ant Design, organized by atomic design principles (atoms, molecules, organisms).
Global state managed via Redux Toolkit with RTK Query for server state synchronization and caching.
File-based routing with Next.js App Router, protected routes via middleware, and dynamic route segments.
The backend follows a microservices architecture with an API gateway handling authentication and rate limiting.
RESTful API with OpenAPI 3.1 documentation. GraphQL available for complex queries. Rate limited to 1000 req/min per tenant.
PostgreSQL with read replicas for horizontal scaling. Schema migrations managed with Prisma. Automated daily backups with point-in-time recovery.
OAuth 2.0 with PKCE flow, JWT access tokens (15 min TTL), and secure httpOnly refresh tokens. SAML SSO available for Enterprise.
```yaml
- id: nested_outer
type: Collapse
properties:
panels:
- key: no_frontend
title: Frontend Architecture
- key: no_backend
title: Backend Architecture
slots:
no_frontend:
blocks:
- id: nested_fe_intro
type: Paragraph
properties:
content: The frontend is organized into feature modules, each with its own
routing, state management, and component library.
- id: nested_fe_inner
type: Collapse
properties:
bordered: false
panels:
- key: nfi_components
title: Component Library
- key: nfi_state
title: State Management
- key: nfi_routing
title: Routing
slots:
nfi_components:
blocks:
- id: nested_fe_components_text
type: Paragraph
properties:
content: Shared UI components built with Ant Design, organized by atomic design
principles (atoms, molecules, organisms).
nfi_state:
blocks:
- id: nested_fe_state_text
type: Paragraph
properties:
content: Global state managed via Redux Toolkit with RTK Query for server state
synchronization and caching.
nfi_routing:
blocks:
- id: nested_fe_routing_text
type: Paragraph
properties:
content: File-based routing with Next.js App Router, protected routes via
middleware, and dynamic route segments.
no_backend:
blocks:
- id: nested_be_intro
type: Paragraph
properties:
content: The backend follows a microservices architecture with an API gateway
handling authentication and rate limiting.
- id: nested_be_inner
type: Collapse
properties:
bordered: false
panels:
- key: nbi_api
title: API Layer
- key: nbi_database
title: Database Design
- key: nbi_auth
title: Authentication
slots:
nbi_api:
blocks:
- id: nested_be_api_text
type: Paragraph
properties:
content: RESTful API with OpenAPI 3.1 documentation. GraphQL available for
complex queries. Rate limited to 1000 req/min per tenant.
nbi_database:
blocks:
- id: nested_be_database_text
type: Paragraph
properties:
content: PostgreSQL with read replicas for horizontal scaling. Schema migrations
managed with Prisma. Automated daily backups with
point-in-time recovery.
nbi_auth:
blocks:
- id: nested_be_auth_text
type: Paragraph
properties:
content: OAuth 2.0 with PKCE flow, JWT access tokens (15 min TTL), and secure
httpOnly refresh tokens. SAML SSO available for
Enterprise.
```
Deployed on 3 regions (us-east, eu-west, ap-southeast) with automatic failover and CDN edge caching.
Mirror of production with synthetic test data. Auto-deploys from the staging branch on every merge. Used for QA validation before production releases.
> Last deployment was 2 hours ago. All 847 integration tests passed.
Local development environment running via Docker Compose. Hot-reload enabled for frontend and backend services with seeded test database.
> 3 pending database migrations need to be applied before starting the dev server.
```yaml
- id: actions_collapse
type: Collapse
properties:
panels:
- key: act_server
title: Production Server
extraKey: act_server_extra
- key: act_staging
title: Staging Environment
extraKey: act_staging_extra
- key: act_dev
title: Development Environment
extraKey: act_dev_extra
slots:
act_server:
blocks:
- id: actions_server_stats
type: Box
layout:
gap: 16
blocks:
- id: act_server_uptime
type: Statistic
layout:
flex: 0 0 auto
properties:
title: Uptime
value: 99.97
suffix: "%"
- id: act_server_latency
type: Statistic
layout:
flex: 0 0 auto
properties:
title: Avg Latency
value: 42
suffix: ms
- id: act_server_rpm
type: Statistic
layout:
flex: 0 0 auto
properties:
title: Requests/min
value: 8420
- id: actions_server_desc
type: Paragraph
properties:
content: Deployed on 3 regions (us-east, eu-west, ap-southeast) with automatic
failover and CDN edge caching.
- id: actions_server_btns
type: Box
layout:
gap: 8
blocks:
- id: act_server_btn_logs
type: Button
layout:
flex: 0 0 auto
properties:
title: View Logs
icon: document
color: primary
variant: outlined
size: small
- id: act_server_btn_metrics
type: Button
layout:
flex: 0 0 auto
properties:
title: Metrics
icon: chart
color: primary
variant: outlined
size: small
act_server_extra:
blocks:
- id: act_server_status
type: Tag
properties:
title: Healthy
color: success
act_staging:
blocks:
- id: actions_staging_desc
type: Paragraph
properties:
content: Mirror of production with synthetic test data. Auto-deploys from the
staging branch on every merge. Used for QA validation before
production releases.
- id: actions_staging_alert
type: Alert
properties:
message: Last deployment was 2 hours ago. All 847 integration tests passed.
type: success
showIcon: true
act_staging_extra:
blocks:
- id: act_staging_status
type: Tag
properties:
title: Healthy
color: success
act_dev:
blocks:
- id: actions_dev_desc
type: Paragraph
properties:
content: Local development environment running via Docker Compose. Hot-reload
enabled for frontend and backend services with seeded test
database.
- id: actions_dev_alert
type: Alert
properties:
message: 3 pending database migrations need to be applied before starting the
dev server.
type: warning
showIcon: true
act_dev_extra:
blocks:
- id: act_dev_status
type: Tag
properties:
title: Needs Attention
color: warning
```
Follow the 8px grid system for all spacing. Use consistent border radius (8px for containers, 4px for inputs). Maintain a minimum touch target of 44x44px for mobile.
Primary: #1677ff, Success: #52c41a, Warning: #faad14, Error: #ff4d4f. Always use the design token system rather than hardcoding hex values.
Body: 14px/1.5715, Headings: 24px/1.3, Small: 12px/1.6667. Use the Inter font family for UI text and JetBrains Mono for code snippets.
```yaml
- id: css_styled_collapse
type: Collapse
style:
.element:
background: transparent
borderColor: "#d9d9d9"
.header:
fontWeight: 600
.content:
color: "#595959"
properties:
panels:
- key: css_design
title: Design Guidelines
- key: css_brand
title: Brand Colors
- key: css_typography
title: Typography
slots:
css_design:
blocks:
- id: css_design_text
type: Paragraph
properties:
content: Follow the 8px grid system for all spacing. Use consistent border
radius (8px for containers, 4px for inputs). Maintain a minimum
touch target of 44x44px for mobile.
css_brand:
blocks:
- id: css_brand_text
type: Paragraph
properties:
content: "Primary: #1677ff, Success: #52c41a, Warning: #faad14, Error: #ff4d4f.
Always use the design token system rather than hardcoding hex
values."
- id: css_brand_tags
type: Box
layout:
gap: 6
blocks:
- id: css_brand_tag_primary
type: Tag
properties:
title: Primary
color: "#1677ff"
- id: css_brand_tag_success
type: Tag
properties:
title: Success
color: "#52c41a"
- id: css_brand_tag_warning
type: Tag
properties:
title: Warning
color: "#faad14"
- id: css_brand_tag_error
type: Tag
properties:
title: Error
color: "#ff4d4f"
css_typography:
blocks:
- id: css_typography_text
type: Paragraph
properties:
content: "Body: 14px/1.5715, Headings: 24px/1.3, Small: 12px/1.6667. Use the
Inter font family for UI text and JetBrains Mono for code
snippets."
```
This collapse uses a light blue header background and a slightly tinted content area, achieved by overriding the headerBg and contentBg design tokens.
The padding has been increased to 16px vertically and 20px horizontally for both header and content areas, giving a more spacious feel.
A dark-themed collapse achieved entirely through design token overrides. The header, content, and border colors are all customized.
Token overrides cascade to all child elements, making it straightforward to create themed sections without global CSS changes.
The borderRadiusLG token controls the rounding of the collapse container corners. Set to 16px here for a softer appearance.
Combining borderRadiusLG with a green-tinted headerBg creates a nature-inspired visual style suitable for eco-friendly or wellness applications.
```yaml
- id: theme_blue_header
type: Collapse
properties:
theme:
headerPadding: 16px 20px
contentPadding: 20px 20px
panels:
- key: tb_overview
title: Blue Header Theme
- key: tb_details
title: Expanded Padding
slots:
tb_overview:
blocks:
- id: theme_blue_overview_text
type: Paragraph
properties:
content: This collapse uses a light blue header background and a slightly tinted
content area, achieved by overriding the headerBg and contentBg
design tokens.
tb_details:
blocks:
- id: theme_blue_details_text
type: Paragraph
properties:
content: The padding has been increased to 16px vertically and 20px horizontally
for both header and content areas, giving a more spacious feel.
- id: theme_dark_collapse
type: Collapse
properties:
theme:
headerBg: "#1f1f1f"
contentBg: "#141414"
colorText: "#ffffffd9"
colorTextHeading: "#ffffffd9"
colorBorder: "#424242"
panels:
- key: td_about
title: Dark Theme
- key: td_settings
title: Configuration
slots:
td_about:
blocks:
- id: theme_dark_about_text
type: Paragraph
properties:
content: A dark-themed collapse achieved entirely through design token
overrides. The header, content, and border colors are all
customized.
td_settings:
blocks:
- id: theme_dark_settings_text
type: Paragraph
properties:
content: Token overrides cascade to all child elements, making it
straightforward to create themed sections without global CSS
changes.
- id: theme_rounded_collapse
type: Collapse
properties:
theme:
borderRadiusLG: 16
panels:
- key: tr_one
title: Extra Rounded Corners
- key: tr_two
title: Green Tinted Headers
slots:
tr_one:
blocks:
- id: theme_rounded_one_text
type: Paragraph
properties:
content: The borderRadiusLG token controls the rounding of the collapse
container corners. Set to 16px here for a softer appearance.
tr_two:
blocks:
- id: theme_rounded_two_text
type: Paragraph
properties:
content: Combining borderRadiusLG with a green-tinted headerBg creates a
nature-inspired visual style suitable for eco-friendly or wellness
applications.
```
Get started at no cost with essential features for individuals and small teams exploring the platform.
> Community support via forums. No SLA guarantee.
Everything in Free, plus advanced collaboration tools, priority support, and higher resource limits for growing teams.
> Email and chat support with 24-hour response SLA.
Full platform access with dedicated infrastructure, custom integrations, and white-glove onboarding for large organizations.
> Dedicated account manager, 1-hour response SLA, and custom SLA agreements.
```yaml
- id: rich_accordion
type: Collapse
properties:
accordion: true
expandIconPlacement: end
panels:
- key: ra_plan_free
title: Free Plan
extraKey: ra_plan_free_extra
- key: ra_plan_pro
title: Pro Plan
extraKey: ra_plan_pro_extra
- key: ra_plan_enterprise
title: Enterprise Plan
extraKey: ra_plan_enterprise_extra
slots:
ra_plan_free:
blocks:
- id: ra_free_desc
type: Paragraph
properties:
content: Get started at no cost with essential features for individuals and
small teams exploring the platform.
- id: ra_free_features
type: Box
layout:
gap: 6
blocks:
- id: ra_free_tag_users
type: Tag
properties:
title: Up to 5 users
color: default
- id: ra_free_tag_projects
type: Tag
properties:
title: 3 projects
color: default
- id: ra_free_tag_storage
type: Tag
properties:
title: 1 GB storage
color: default
- id: ra_free_alert
type: Alert
properties:
message: Community support via forums. No SLA guarantee.
type: info
showIcon: true
ra_plan_free_extra:
blocks:
- id: ra_free_price
type: Tag
properties:
title: $0/month
color: green
ra_plan_pro:
blocks:
- id: ra_pro_desc
type: Paragraph
properties:
content: Everything in Free, plus advanced collaboration tools, priority
support, and higher resource limits for growing teams.
- id: ra_pro_features
type: Box
layout:
gap: 6
blocks:
- id: ra_pro_tag_users
type: Tag
properties:
title: Up to 50 users
color: blue
- id: ra_pro_tag_projects
type: Tag
properties:
title: Unlimited projects
color: blue
- id: ra_pro_tag_storage
type: Tag
properties:
title: 100 GB storage
color: blue
- id: ra_pro_tag_sso
type: Tag
properties:
title: SSO included
color: blue
- id: ra_pro_alert
type: Alert
properties:
message: Email and chat support with 24-hour response SLA.
type: success
showIcon: true
ra_plan_pro_extra:
blocks:
- id: ra_pro_price
type: Tag
properties:
title: $29/month
color: blue
ra_plan_enterprise:
blocks:
- id: ra_enterprise_desc
type: Paragraph
properties:
content: Full platform access with dedicated infrastructure, custom
integrations, and white-glove onboarding for large organizations.
- id: ra_enterprise_features
type: Box
layout:
gap: 6
blocks:
- id: ra_ent_tag_users
type: Tag
properties:
title: Unlimited users
color: gold
- id: ra_ent_tag_projects
type: Tag
properties:
title: Unlimited projects
color: gold
- id: ra_ent_tag_storage
type: Tag
properties:
title: Unlimited storage
color: gold
- id: ra_ent_tag_sso
type: Tag
properties:
title: SAML SSO
color: gold
- id: ra_ent_tag_sla
type: Tag
properties:
title: 99.99% SLA
color: gold
- id: ra_enterprise_alert
type: Alert
properties:
message: Dedicated account manager, 1-hour response SLA, and custom SLA
agreements.
type: warning
showIcon: true
ra_plan_enterprise_extra:
blocks:
- id: ra_enterprise_price
type: Tag
properties:
title: Custom
color: gold
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `accordion` | boolean | `false` | If true, only one panel is open at a time. |
| `activeKey` | string \| array | - | Current panel's key, or a list of keys of the open panels. |
| `bordered` | boolean | `true` | Toggles rendering of the border around the collapse block. |
| `collapsible` | string | - | How panels are toggled: by clicking anywhere in the `header` (default), only the expand `icon`, or `disabled` to stop all panels from toggling. Enum: `header`, `icon`, `disabled`. |
| `defaultActiveKey` | string \| array | - | Initial active panel key, or a list of keys, if activeKey is not set. |
| `destroyInactivePanel` | boolean | `false` | Destroy inactive panel. Maps to antd's `destroyOnHidden`. |
| `expandIcon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block for expand icon on the right of selector. |
| `expandIcon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `expandIcon.color` | string | - | Icon color. |
| `expandIcon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `expandIcon.rotate` | number | - | Number of degrees to rotate the icon. |
| `expandIcon.spin` | boolean | - | Continuously spin the icon with animation. |
| `expandIcon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `expandIcon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `expandIcon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `expandIcon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `expandIconPlacement` | string | `"start"` | Set placement of the expand icon. Enum: `start`, `end`. |
| `forceRender` | boolean | `false` | Force render for all panels. |
| `ghost` | boolean | `false` | Make the collapse borderless with a transparent background. |
| `padding` | string | `"default"` | Space inside each panel body. `compact` tightens it to 8px 16px. `none` removes it so content such as a table or list runs edge to edge; the panel headers keep their padding. Enum: `default`, `compact`, `none`. |
| `panels` | array | - | |
| `panels.$.title` | string | - | Title of the panel - supports html. |
| `panels.$.key` | string | - | Key of the panel. |
| `panels.$.extraKey` | string | - | Key for the extra area of the panel. |
| `panels.$.disabled` | boolean | `false` | Disable the panel if true. |
| `showArrow` | boolean | `true` | Show expand icon. |
| `size` | string | `"medium"` | Size of the panel headers and content padding. Enum: `small`, `medium`, `large`. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design collapse tokens](https://ant.design/components/collapse#design-token). |
| `theme.headerPadding` | string | `"12px 16px"` | Padding of the collapse header. |
| `theme.headerPaddingSM` | string | `"8px 12px 8px 8px"` | Padding of the collapse header when size is small. |
| `theme.headerPaddingLG` | string | `"16px 24px 16px 16px"` | Padding of the collapse header when size is large. |
| `theme.headerBg` | string | `"rgba(0, 0, 0, 0.02)"` | Background color of the collapse header. |
| `theme.contentPadding` | string | `"16px 16px"` | Padding of the collapse content area. |
| `theme.contentPaddingSM` | number \| string | `12` | Padding of the collapse content area when size is small. |
| `theme.contentPaddingLG` | number \| string | `24` | Padding of the collapse content area when size is large. |
| `theme.contentBg` | string | `"#ffffff"` | Background color of the collapse content area. |
| `theme.borderlessContentPadding` | string | `"4px 16px 16px"` | Padding of the content area in borderless (ghost) style. |
| `theme.borderlessContentBg` | string | `"transparent"` | Background color of the content area in borderless (ghost) style. |
| `theme.colorBorder` | string | - | Border color of the collapse component. |
| `theme.borderRadiusLG` | number | `8` | Border radius of the collapse container. |
| `theme.colorText` | string | - | Text color for the collapse content. |
| `theme.colorTextHeading` | string | - | Text color for the collapse header. |
| `theme.fontSize` | number | `14` | Font size of the collapse content. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onChange` | `{ activeKey }` | Trigger actions when collapse item is toggled. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Collapse element. |
| `/expandIcon` | The expand icon in the Collapse. |
| `/header` | The Collapse header. |
| `/title` | The panel title text in the Collapse header. |
| `/content` | The Collapse content. |
Slot keys are user-defined in your config and resolved at build time — not generated at runtime. The block typically pairs slots with an array property (`tabs`, `panels`, `slides`) listed in the Properties table; see the examples above for the expected shape.
---
url: https://docs.lowdefy.com/md/container-blocks/configprovider.md
---
# ConfigProvider
Global configuration provider for antd theme and locale settings.
```yaml
- id: cp_primary_color
type: ConfigProvider
properties:
token:
colorPrimary: "#722ed1"
blocks:
- id: cp_primary_row
type: Box
layout:
gap: 8
blocks:
- id: cp_primary_btn_solid
type: Button
layout:
flex: 0 0 auto
properties:
title: Solid
color: primary
variant: solid
- id: cp_primary_btn_outlined
type: Button
layout:
flex: 0 0 auto
properties:
title: Outlined
color: primary
variant: outlined
- id: cp_primary_btn_dashed
type: Button
layout:
flex: 0 0 auto
properties:
title: Dashed
color: primary
variant: dashed
- id: cp_primary_btn_text
type: Button
layout:
flex: 0 0 auto
properties:
title: Text
color: primary
variant: text
- id: cp_primary_btn_link
type: Button
layout:
flex: 0 0 auto
properties:
title: Link
color: primary
variant: link
- id: cp_primary_switch
type: Switch
properties:
label:
title: Purple themed switch
colon: false
- id: cp_primary_progress
type: Progress
properties:
percent: 65
```
Dark Mode
The dark algorithm inverts the color scheme for all child components. Backgrounds become dark and text becomes light automatically.
```yaml
- id: cp_dark
type: ConfigProvider
properties:
algorithm: dark
blocks:
- id: cp_dark_box
type: Box
style:
padding: 24px
background: "#141414"
borderRadius: 8px
layout:
gap: 12
blocks:
- id: cp_dark_title
type: Title
properties:
content: Dark Mode
level: 4
- id: cp_dark_text
type: Paragraph
properties:
content: The dark algorithm inverts the color scheme for all child components.
Backgrounds become dark and text becomes light automatically.
- id: cp_dark_btn_row
type: Box
layout:
gap: 8
blocks:
- id: cp_dark_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: Primary
color: primary
variant: solid
- id: cp_dark_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: Default
color: default
variant: outlined
- id: cp_dark_btn3
type: Button
layout:
flex: 0 0 auto
properties:
title: Danger
color: danger
variant: solid
- id: cp_dark_switch
type: Switch
properties:
label:
title: Dark switch
colon: false
```
The compact algorithm reduces padding and margins for denser layouts. Useful for data-heavy dashboards and admin panels.
```yaml
- id: cp_compact
type: ConfigProvider
properties:
algorithm: compact
blocks:
- id: cp_compact_row
type: Box
layout:
gap: 8
blocks:
- id: cp_compact_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: Compact Solid
color: primary
variant: solid
- id: cp_compact_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: Compact Outlined
color: primary
variant: outlined
- id: cp_compact_input
type: TextInput
properties:
label:
title: Compact input
colon: false
placeholder: Compact sized input
- id: cp_compact_text
type: Paragraph
properties:
content: The compact algorithm reduces padding and margins for denser layouts.
Useful for data-heavy dashboards and admin panels.
```
Dark + Compact
Multiple algorithms can be combined by passing an array. Here dark and compact are used together for a dense dark-themed layout.
```yaml
- id: cp_combined
type: ConfigProvider
properties:
algorithm:
- dark
- compact
blocks:
- id: cp_combined_box
type: Box
style:
padding: 24px
background: "#141414"
borderRadius: 8px
layout:
gap: 12
blocks:
- id: cp_combined_title
type: Title
properties:
content: Dark + Compact
level: 4
- id: cp_combined_text
type: Paragraph
properties:
content: Multiple algorithms can be combined by passing an array. Here dark and
compact are used together for a dense dark-themed layout.
- id: cp_combined_btn_row
type: Box
layout:
gap: 8
blocks:
- id: cp_combined_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: Action
color: primary
variant: solid
- id: cp_combined_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel
color: default
variant: outlined
```
**Small:**
**Middle (default):**
**Large:**
```yaml
- id: cp_size_small_label
type: Markdown
properties:
content: "**Small:**"
- id: cp_size_small
type: ConfigProvider
properties:
componentSize: small
blocks:
- id: cp_small_row
type: Box
layout:
gap: 8
blocks:
- id: cp_small_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Small Button
color: primary
variant: solid
- id: cp_small_input
type: TextInput
layout:
flex: 0 1 200px
properties:
placeholder: Small input
label:
disabled: true
- id: cp_size_middle_label
type: Markdown
properties:
content: "**Middle (default):**"
- id: cp_size_middle
type: ConfigProvider
properties:
componentSize: middle
blocks:
- id: cp_middle_row
type: Box
layout:
gap: 8
blocks:
- id: cp_middle_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Middle Button
color: primary
variant: solid
- id: cp_middle_input
type: TextInput
layout:
flex: 0 1 200px
properties:
placeholder: Middle input
label:
disabled: true
- id: cp_size_large_label
type: Markdown
properties:
content: "**Large:**"
- id: cp_size_large
type: ConfigProvider
properties:
componentSize: large
blocks:
- id: cp_large_row
type: Box
layout:
gap: 8
blocks:
- id: cp_large_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Large Button
color: primary
variant: solid
- id: cp_large_input
type: TextInput
layout:
flex: 0 1 200px
properties:
placeholder: Large input
label:
disabled: true
```
Setting componentDisabled to true disables all interactive child components at once, without needing to set disabled on each individual component. A block that sets disabled to false stays enabled.
```yaml
- id: cp_disabled
type: ConfigProvider
properties:
componentDisabled: true
blocks:
- id: cp_disabled_row
type: Box
layout:
gap: 8
blocks:
- id: cp_disabled_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Disabled Button
color: primary
variant: solid
- id: cp_disabled_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: Also Disabled
color: default
variant: outlined
- id: cp_disabled_switch
type: Switch
properties:
label:
title: Disabled switch
colon: false
- id: cp_disabled_input
type: TextInput
properties:
placeholder: Disabled input
label:
title: Disabled input
colon: false
- id: cp_disabled_selector
type: Selector
properties:
placeholder: Disabled selector
options:
- Option 1
- Option 2
label:
title: Disabled selector
colon: false
- id: cp_enabled_input
type: TextInput
properties:
placeholder: Still enabled
disabled: false
label:
title: "Re-enabled with disabled: false"
colon: false
- id: cp_disabled_text
type: Paragraph
properties:
content: Setting componentDisabled to true disables all interactive child
components at once, without needing to set disabled on each individual
component. A block that sets disabled to false stays enabled.
```
Setting direction to rtl enables right-to-left layout for all child components. This is essential for languages like Arabic and Hebrew.
```yaml
- id: cp_rtl
type: ConfigProvider
properties:
direction: rtl
blocks:
- id: cp_rtl_row
type: Box
layout:
gap: 8
blocks:
- id: cp_rtl_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Right-to-Left
color: primary
variant: solid
icon: arrow-left
- id: cp_rtl_input
type: TextInput
properties:
placeholder: RTL text input
label:
title: RTL Input
colon: false
- id: cp_rtl_text
type: Paragraph
properties:
content: Setting direction to rtl enables right-to-left layout for all child
components. This is essential for languages like Arabic and Hebrew.
```
**Outlined (default):**
**Filled:**
**Borderless:**
**Underlined:**
```yaml
- id: cp_variant_outlined_label
type: Markdown
properties:
content: "**Outlined (default):**"
- id: cp_variant_outlined
type: ConfigProvider
properties:
variant: outlined
blocks:
- id: cp_vo_input
type: TextInput
properties:
placeholder: Outlined input
label:
title: Name
colon: false
- id: cp_variant_filled_label
type: Markdown
properties:
content: "**Filled:**"
- id: cp_variant_filled
type: ConfigProvider
properties:
variant: filled
blocks:
- id: cp_vf_input
type: TextInput
properties:
placeholder: Filled input
label:
title: Name
colon: false
- id: cp_variant_borderless_label
type: Markdown
properties:
content: "**Borderless:**"
- id: cp_variant_borderless
type: ConfigProvider
properties:
variant: borderless
blocks:
- id: cp_vb_input
type: TextInput
properties:
placeholder: Borderless input
label:
title: Name
colon: false
- id: cp_variant_underlined_label
type: Markdown
properties:
content: "**Underlined:**"
- id: cp_variant_underlined
type: ConfigProvider
properties:
variant: underlined
blocks:
- id: cp_vu_input
type: TextInput
properties:
placeholder: Underlined input
label:
title: Name
colon: false
```
The components property allows overriding design tokens at the component level. Here, Button and Input components have custom borderRadius applied without affecting other components.
```yaml
- id: cp_components
type: ConfigProvider
properties:
components:
Button:
borderRadius: 20
controlHeight: 40
Input:
borderRadius: 20
blocks:
- id: cp_components_row
type: Box
layout:
gap: 8
blocks:
- id: cp_comp_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Pill Button
color: primary
variant: solid
- id: cp_comp_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: Also Pill
color: default
variant: outlined
- id: cp_comp_input
type: TextInput
properties:
placeholder: Rounded input
label:
title: Rounded input
colon: false
- id: cp_comp_text
type: Paragraph
properties:
content: The components property allows overriding design tokens at the
component level. Here, Button and Input components have custom
borderRadius applied without affecting other components.
```
Global design tokens customize the look of all child components. This section uses a custom primary color (orange), larger font size, rounded borders, and a warm background color.
```yaml
- id: cp_tokens
type: ConfigProvider
properties:
token:
colorPrimary: "#fa541c"
fontSize: 16
borderRadius: 8
blocks:
- id: cp_tokens_card
type: Card
properties:
title: Custom Themed Card
blocks:
- id: cp_tokens_text
type: Paragraph
properties:
content: Global design tokens customize the look of all child components. This
section uses a custom primary color (orange), larger font size,
rounded borders, and a warm background color.
- id: cp_tokens_btn_row
type: Box
layout:
gap: 8
blocks:
- id: cp_tokens_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: Primary
color: primary
variant: solid
- id: cp_tokens_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: Outlined
color: primary
variant: outlined
- id: cp_tokens_input
type: TextInput
properties:
placeholder: Themed input
label:
title: Themed Input
colon: false
```
The theme property provides antd design token overrides for this block and all its descendants. It works similarly to token but is applied at the block level through the antd theme system.
```yaml
- id: cp_theme
type: ConfigProvider
properties:
theme:
colorPrimary: "#13c2c2"
colorInfo: "#13c2c2"
borderRadius: 12
blocks:
- id: cp_theme_card
type: Card
properties:
title: Theme Overrides via theme Property
blocks:
- id: cp_theme_text
type: Paragraph
properties:
content: The theme property provides antd design token overrides for this block
and all its descendants. It works similarly to token but is
applied at the block level through the antd theme system.
- id: cp_theme_btn_row
type: Box
layout:
gap: 8
blocks:
- id: cp_theme_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: Teal Primary
color: primary
variant: solid
- id: cp_theme_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: Teal Outlined
color: primary
variant: outlined
- id: cp_theme_switch
type: Switch
properties:
label:
title: Teal themed switch
colon: false
```
Styled Wrapper
Tailwind CSS classes can be applied to the ConfigProvider wrapper div using the class property. Here a gradient background with rounded corners wraps all themed children.
Elevated Section
A ConfigProvider with shadow and padding classes creates a visually distinct themed section on the page.
```yaml
- id: cp_styled_gradient
type: ConfigProvider
class: bg-gradient-to-r from-primary/10 to-primary/5 p-6 rounded-xl border
border-border
properties:
token:
colorPrimary: "#6366f1"
blocks:
- id: cp_styled_gradient_title
type: Title
properties:
content: Styled Wrapper
level: 4
- id: cp_styled_gradient_text
type: Paragraph
properties:
content: Tailwind CSS classes can be applied to the ConfigProvider wrapper div
using the class property. Here a gradient background with rounded
corners wraps all themed children.
- id: cp_styled_gradient_row
type: Box
layout:
gap: 8
blocks:
- id: cp_styled_gradient_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: Indigo Action
color: primary
variant: solid
- id: cp_styled_gradient_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel
color: default
variant: outlined
- id: cp_styled_shadow
type: ConfigProvider
class: shadow-lg p-8 rounded-2xl bg-bg-container
properties:
token:
colorPrimary: "#059669"
blocks:
- id: cp_styled_shadow_title
type: Title
properties:
content: Elevated Section
level: 4
- id: cp_styled_shadow_text
type: Paragraph
properties:
content: A ConfigProvider with shadow and padding classes creates a visually
distinct themed section on the page.
- id: cp_styled_shadow_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Confirm
color: primary
variant: solid
```
Acme Commerce
This demonstrates using ConfigProvider to apply a brand theme across an entire section. The rose primary color, pill-shaped buttons, and custom font size create a cohesive brand identity for all child components.
```yaml
- id: cp_brand_wrapper
type: ConfigProvider
properties:
token:
colorPrimary: "#e11d48"
colorInfo: "#0ea5e9"
borderRadius: 6
fontSize: 14
components:
Button:
borderRadius: 20
blocks:
- id: cp_brand_header
type: Box
class: bg-bg-layout p-6 rounded-lg border border-border
layout:
gap: 16
blocks:
- id: cp_brand_title_row
type: Box
layout:
gap: 12
align: center
blocks:
- id: cp_brand_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: Store
size: 48
color: "#e11d48"
- id: cp_brand_title
type: Title
layout:
flex: 1 1 0
properties:
content: Acme Commerce
level: 3
- id: cp_brand_description
type: Paragraph
properties:
content: This demonstrates using ConfigProvider to apply a brand theme across an
entire section. The rose primary color, pill-shaped buttons, and
custom font size create a cohesive brand identity for all child
components.
- id: cp_brand_form_row
type: Box
layout:
gap: 12
blocks:
- id: cp_brand_search_input
type: TextInput
layout:
flex: 1 1 0
properties:
placeholder: Search products...
label:
disabled: true
suffixIcon: search
- id: cp_brand_search_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Search
color: primary
variant: solid
- id: cp_brand_cart_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cart
icon: ShoppingCart
color: default
variant: outlined
- id: cp_brand_stats_row
type: Box
layout:
gap: 16
blocks:
- id: cp_brand_stat1
type: Statistic
layout:
flex: 1 1 0
properties:
title: Products
value: 1240
- id: cp_brand_stat2
type: Statistic
layout:
flex: 1 1 0
properties:
title: Orders Today
value: 87
- id: cp_brand_stat3
type: Statistic
layout:
flex: 1 1 0
properties:
title: Revenue
value: 12480
prefix: $
```
System Metrics
```yaml
- id: cp_dashboard_wrapper
type: ConfigProvider
properties:
algorithm:
- compact
componentSize: small
token:
colorPrimary: "#1677ff"
fontSize: 12
variant: filled
blocks:
- id: cp_dashboard_title
type: Title
properties:
content: System Metrics
level: 4
- id: cp_dashboard_cards_row
type: Box
layout:
gap: 12
blocks:
- id: cp_dashboard_card1
type: Card
layout:
flex: 1 1 0
properties:
title: CPU Usage
size: small
blocks:
- id: cp_dashboard_progress1
type: Progress
properties:
percent: 72
- id: cp_dashboard_tag1
type: Tag
properties:
title: Normal
color: success
- id: cp_dashboard_card2
type: Card
layout:
flex: 1 1 0
properties:
title: Memory
size: small
blocks:
- id: cp_dashboard_progress2
type: Progress
properties:
percent: 89
- id: cp_dashboard_tag2
type: Tag
properties:
title: High
color: warning
- id: cp_dashboard_card3
type: Card
layout:
flex: 1 1 0
properties:
title: Disk I/O
size: small
blocks:
- id: cp_dashboard_progress3
type: Progress
properties:
percent: 34
- id: cp_dashboard_tag3
type: Tag
properties:
title: Low
color: blue
- id: cp_dashboard_filter_row
type: Box
layout:
gap: 8
align: center
blocks:
- id: cp_dashboard_filter_input
type: TextInput
layout:
flex: 0 1 200px
properties:
placeholder: Filter services...
label:
disabled: true
- id: cp_dashboard_selector
type: Selector
layout:
flex: 0 1 150px
properties:
placeholder: Region
label:
disabled: true
options:
- label: US East
value: us-east
- label: US West
value: us-west
- label: EU West
value: eu-west
- id: cp_dashboard_refresh_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Refresh
icon: refresh
color: primary
variant: solid
```
Admin Panel
A dark-themed admin panel using ConfigProvider to apply the dark algorithm with a custom purple accent color. All child components inherit the dark color scheme automatically.
```yaml
- id: cp_admin_wrapper
type: ConfigProvider
properties:
algorithm: dark
token:
colorPrimary: "#7c3aed"
borderRadius: 8
blocks:
- id: cp_admin_box
type: Box
style:
padding: 24px
background: "#141414"
borderRadius: 12px
layout:
gap: 16
blocks:
- id: cp_admin_header_row
type: Box
layout:
gap: 12
align: center
blocks:
- id: cp_admin_title
type: Title
layout:
flex: 1 1 0
properties:
content: Admin Panel
level: 3
- id: cp_admin_status_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Online
color: success
- id: cp_admin_desc
type: Paragraph
properties:
content: A dark-themed admin panel using ConfigProvider to apply the dark
algorithm with a custom purple accent color. All child components
inherit the dark color scheme automatically.
- id: cp_admin_form
type: Box
layout:
gap: 12
blocks:
- id: cp_admin_name_input
type: TextInput
properties:
placeholder: Enter username
label:
title: Username
colon: false
- id: cp_admin_email_input
type: TextInput
properties:
placeholder: Enter email address
label:
title: Email
colon: false
- id: cp_admin_role_selector
type: Selector
properties:
placeholder: Select role
label:
title: Role
colon: false
options:
- label: Administrator
value: admin
- label: Editor
value: editor
- label: Viewer
value: viewer
- id: cp_admin_btn_row
type: Box
layout:
gap: 8
blocks:
- id: cp_admin_save_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Save User
icon: save
color: primary
variant: solid
- id: cp_admin_cancel_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel
color: default
variant: outlined
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `algorithm` | string \| array | - | Theme algorithm. Can be "default", "dark", "compact", or an array of these values. |
| `componentDisabled` | boolean | `false` | Disable every input and button inside the ConfigProvider. A block that sets its own `disabled` property keeps that value, so `disabled: false` re-enables it. |
| `componentSize` | string | - | Set size for all child components. `middle` is the older name for `medium`. Enum: `small`, `medium`, `middle`, `large`. |
| `components` | object | - | Component-level token overrides. Keys are component names, values are token objects. |
| `direction` | string | `"ltr"` | Direction of layout. Enum: `ltr`, `rtl`. |
| `locale` | object | - | Antd locale object to localize built-in component strings (date pickers, pagination, modal, form validation). Pair with the _locale operator and config.i18n to keep the whole subtree in one language. |
| `popupMatchSelectWidth` | boolean \| number | - | Whether dropdowns of select-like components match the width of their input. A number sets a minimum dropdown width in pixels. `false` also turns off virtual scrolling. |
| `popupOverflow` | string | `"viewport"` | Keep dropdowns of select-like components inside the viewport, or let them follow the page scroll. Enum: `viewport`, `scroll`. |
| `token` | object | - | Theme token configuration. Customize design tokens like colorPrimary, fontSize, etc. |
| `virtual` | boolean | `true` | Set to false to turn off virtual scrolling in selectors, trees and tables, so every option renders. |
| `wave` | object | - | Click wave effect of buttons and other clickable components. |
| `wave.disabled` | boolean | `false` | Turn off the click wave effect. |
| `variant` | string | - | Global input variant style for all child components. Enum: `outlined`, `filled`, `borderless`, `underlined`. |
| `theme` | object | - | Antd design token overrides for this block and its descendants. Merged with token, which takes precedence. See [antd design tokens](https://ant.design/components/overview#design-token). |
No events defined.
No CSS keys defined.
| Slot | Description |
| --- | --- |
| `content` | Child blocks wrapped by the ConfigProvider. |
---
url: https://docs.lowdefy.com/md/container-blocks/confirmmodal.md
---
# ConfirmModal
Modal dialog requiring user confirmation before proceeding.
This action cannot be undone.
```yaml
- id: confirm_basic_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Confirm
color: primary
variant: solid
events:
onClick:
- id: confirm_basic_open
type: CallMethod
params:
blockId: confirm_basic
method: open
- id: confirm_basic
type: ConfirmModal
properties:
title: Are you sure?
content: This action cannot be undone.
```
Do you want to proceed with this action?
Your account has been updated successfully.
The operation completed successfully.
This will overwrite existing data. Are you sure you want to continue?
An error occurred while processing your request. Do you want to retry?
```yaml
- id: confirm_status_confirm_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Confirm
color: primary
variant: outlined
events:
onClick:
- id: confirm_status_confirm_open
type: CallMethod
params:
blockId: confirm_status_confirm
method: open
- id: confirm_status_info_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Info
color: blue
variant: outlined
events:
onClick:
- id: confirm_status_info_open
type: CallMethod
params:
blockId: confirm_status_info
method: open
- id: confirm_status_success_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Success
color: green
variant: outlined
events:
onClick:
- id: confirm_status_success_open
type: CallMethod
params:
blockId: confirm_status_success
method: open
- id: confirm_status_warning_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Warning
color: orange
variant: outlined
events:
onClick:
- id: confirm_status_warning_open
type: CallMethod
params:
blockId: confirm_status_warning
method: open
- id: confirm_status_error_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Error
color: danger
variant: outlined
events:
onClick:
- id: confirm_status_error_open
type: CallMethod
params:
blockId: confirm_status_error
method: open
- id: confirm_status_confirm
type: ConfirmModal
properties:
title: Confirm Action
content: Do you want to proceed with this action?
status: confirm
- id: confirm_status_info
type: ConfirmModal
properties:
title: Information
content: Your account has been updated successfully.
status: info
- id: confirm_status_success
type: ConfirmModal
properties:
title: Success
content: The operation completed successfully.
status: success
- id: confirm_status_warning
type: ConfirmModal
properties:
title: Warning
content: This will overwrite existing data. Are you sure you want to continue?
status: warning
- id: confirm_status_error
type: ConfirmModal
properties:
title: Error
content: An error occurred while processing your request. Do you want to retry?
status: error
```
The status of this modal was set at open time via the method args, overriding the default.
```yaml
- id: confirm_override_info_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open as Info
color: blue
variant: outlined
events:
onClick:
- id: confirm_override_info_open
type: CallMethod
params:
blockId: confirm_override
method: open
args:
status: info
- id: confirm_override_error_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open as Error
color: danger
variant: outlined
events:
onClick:
- id: confirm_override_error_open
type: CallMethod
params:
blockId: confirm_override
method: open
args:
status: error
- id: confirm_override_success_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open as Success
color: green
variant: outlined
events:
onClick:
- id: confirm_override_success_open
type: CallMethod
params:
blockId: confirm_override
method: open
args:
status: success
- id: confirm_override
type: ConfirmModal
properties:
title: Dynamic Status
content: The status of this modal was set at open time via the method args,
overriding the default.
status: confirm
```
You have unsaved changes. Do you want to save before leaving?
```yaml
- id: confirm_btn_text_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Custom Buttons
color: primary
variant: outlined
events:
onClick:
- id: confirm_btn_text_open
type: CallMethod
params:
blockId: confirm_btn_text
method: open
- id: confirm_btn_text
type: ConfirmModal
properties:
title: Save Changes?
content: You have unsaved changes. Do you want to save before leaving?
okText: Save
cancelText: Discard
```
This item will be permanently removed from the system.
Are you absolutely sure you want to delete this project and all its data?
```yaml
- id: confirm_icon_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open with Custom Icon
color: primary
variant: outlined
events:
onClick:
- id: confirm_icon_open
type: CallMethod
params:
blockId: confirm_icon
method: open
- id: confirm_icon_colored_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open with Colored Icon
color: danger
variant: outlined
events:
onClick:
- id: confirm_icon_colored_open
type: CallMethod
params:
blockId: confirm_icon_colored
method: open
- id: confirm_icon
type: ConfirmModal
properties:
title: Delete Item?
content: This item will be permanently removed from the system.
icon: delete
- id: confirm_icon_colored
type: ConfirmModal
properties:
title: Danger Zone
content: Are you absolutely sure you want to delete this project and all its data?
icon:
name: warning
color: "#ff4d4f"
size: 22
```
This confirm modal shows a close (x) button in the top right.
Click the mask area outside the modal to dismiss it.
This confirm modal has no mask overlay behind it.
```yaml
- id: confirm_closable_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Closable
color: primary
variant: outlined
events:
onClick:
- id: confirm_closable_open
type: CallMethod
params:
blockId: confirm_closable
method: open
- id: confirm_mask_closable_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Mask Closable
color: primary
variant: outlined
events:
onClick:
- id: confirm_mask_closable_open
type: CallMethod
params:
blockId: confirm_mask_closable
method: open
- id: confirm_no_mask_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: No Mask
color: primary
variant: outlined
events:
onClick:
- id: confirm_no_mask_open
type: CallMethod
params:
blockId: confirm_no_mask
method: open
- id: confirm_closable
type: ConfirmModal
properties:
title: Closable Confirm
content: This confirm modal shows a close (x) button in the top right.
closable: true
- id: confirm_mask_closable
type: ConfirmModal
properties:
title: Mask Closable
content: Click the mask area outside the modal to dismiss it.
maskClosable: true
- id: confirm_no_mask
type: ConfirmModal
properties:
title: No Mask
content: This confirm modal has no mask overlay behind it.
mask: false
```
This confirm modal is vertically centered in the viewport.
A compact 300px confirm modal.
A wider 600px confirm modal with more room for content. Useful for complex messages or forms.
```yaml
- id: confirm_centered_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Centered
color: primary
variant: outlined
events:
onClick:
- id: confirm_centered_open
type: CallMethod
params:
blockId: confirm_centered
method: open
- id: confirm_narrow_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Narrow (300px)
color: primary
variant: outlined
events:
onClick:
- id: confirm_narrow_open
type: CallMethod
params:
blockId: confirm_narrow
method: open
- id: confirm_wide_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Wide (600px)
color: primary
variant: outlined
events:
onClick:
- id: confirm_wide_open
type: CallMethod
params:
blockId: confirm_wide
method: open
- id: confirm_centered
type: ConfirmModal
properties:
title: Centered Confirm
content: This confirm modal is vertically centered in the viewport.
centered: true
- id: confirm_narrow
type: ConfirmModal
properties:
title: Narrow Confirm
content: A compact 300px confirm modal.
width: 300
- id: confirm_wide
type: ConfirmModal
properties:
title: Wide Confirm
content: A wider 600px confirm modal with more room for content. Useful for
complex messages or forms.
width: 600
```
This confirm modal uses a custom z-index of 2000, ensuring it appears above other overlays.
```yaml
- id: confirm_zindex_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Confirm (z-index 2000)
color: primary
variant: outlined
events:
onClick:
- id: confirm_zindex_open
type: CallMethod
params:
blockId: confirm_zindex
method: open
- id: confirm_zindex
type: ConfirmModal
properties:
title: High Z-Index Confirm
content: This confirm modal uses a custom z-index of 2000, ensuring it appears
above other overlays.
zIndex: 2000
```
This action will permanently delete the selected items and cannot be undone.
Your data will be exported to a CSV file and downloaded.
```yaml
- id: confirm_ok_btn_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open with Danger Ok
color: danger
variant: outlined
events:
onClick:
- id: confirm_ok_btn_open
type: CallMethod
params:
blockId: confirm_ok_btn
method: open
- id: confirm_icon_btns_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open with Icon Buttons
color: primary
variant: outlined
events:
onClick:
- id: confirm_icon_btns_open
type: CallMethod
params:
blockId: confirm_icon_btns
method: open
- id: confirm_ok_btn
type: ConfirmModal
properties:
title: Delete Permanently?
content: This action will permanently delete the selected items and cannot be
undone.
status: error
okText: Delete
okButton:
danger: true
cancelText: Keep Items
- id: confirm_icon_btns
type: ConfirmModal
properties:
title: Export Data?
content: Your data will be exported to a CSV file and downloaded.
status: confirm
okText: Export
okButton:
icon: download
iconPlacement: end
cancelText: Cancel
cancelButton:
icon: close
```
This modal uses style to apply custom CSS directly to the modal element.
```yaml
- id: confirm_modal_style_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Styled Modal
color: primary
variant: outlined
events:
onClick:
- id: confirm_modal_style_open
type: CallMethod
params:
blockId: confirm_modal_style
method: open
- id: confirm_modal_style
type: ConfirmModal
properties:
title: Styled Modal
content: This modal uses style to apply custom CSS directly to the modal element.
style:
.element:
borderRadius: 16
boxShadow: 0 8px 32px rgba(0, 0, 0, 0.2)
```
```yaml
- id: confirm_content_slot_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open with Rich Content
color: primary
variant: solid
events:
onClick:
- id: confirm_content_slot_open
type: CallMethod
params:
blockId: confirm_content_slot
method: open
- id: confirm_content_slot
type: ConfirmModal
properties:
title: Review Changes
status: confirm
width: 500
blocks:
- id: confirm_content_slot_desc
type: Descriptions
properties:
size: small
column: 1
items:
- label: File
value: report-2026-Q1.xlsx
- label: Size
value: 2.4 MB
- label: Modified
value: March 10, 2026
- label: Author
value: Jane Cooper
```
Your subscription will expire on March 31, 2026 . Please renew to avoid service interruption.
```yaml
- id: confirm_html_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open with HTML Content
color: primary
variant: outlined
events:
onClick:
- id: confirm_html_open
type: CallMethod
params:
blockId: confirm_html
method: open
- id: confirm_html
type: ConfirmModal
properties:
title: Important Notice
content: Your subscription will expire on March 31, 2026 . Please
renew to avoid service interruption.
status: warning
```
Clicking Ok or Cancel will update the state and show a message.
```yaml
- id: confirm_events_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open with Event Actions
color: primary
variant: solid
events:
onClick:
- id: confirm_events_open
type: CallMethod
params:
blockId: confirm_events
method: open
- id: confirm_events_result
type: Paragraph
properties:
content:
_if:
test:
_not:
_not:
_state: confirm_events_action
then:
_string.concat:
- "Last action: "
- _state: confirm_events_action
else: Click the button above and choose Ok or Cancel.
- id: confirm_events
type: ConfirmModal
properties:
title: Confirm with Events
content: Clicking Ok or Cancel will update the state and show a message.
okText: Confirm
events:
onOpen:
- id: confirm_events_on_open_set
type: SetState
params:
confirm_events_action: Modal opened...
onOk:
- id: confirm_events_on_ok_set
type: SetState
params:
confirm_events_action: Confirmed
- id: confirm_events_on_ok_msg
type: DisplayMessage
params:
content: Action confirmed successfully.
status: success
onCancel:
- id: confirm_events_on_cancel_set
type: SetState
params:
confirm_events_action: Cancelled
- id: confirm_events_on_cancel_msg
type: DisplayMessage
params:
content: Action was cancelled.
status: info
```
The element CSS key applies Tailwind classes to the modal wrapper. This modal uses rounded-2xl and shadow-2xl on the element key.
The body CSS key targets the modal body area. This modal uses bg-bg-layout and p-6 on the body key for a tinted content area.
```yaml
- id: confirm_css_element_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Styled Element
color: primary
variant: outlined
events:
onClick:
- id: confirm_css_element_open
type: CallMethod
params:
blockId: confirm_css_element
method: open
- id: confirm_css_body_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Styled Body
color: primary
variant: outlined
events:
onClick:
- id: confirm_css_body_open
type: CallMethod
params:
blockId: confirm_css_body
method: open
- id: confirm_css_element
type: ConfirmModal
class:
.element: rounded-2xl shadow-2xl
properties:
title: Styled Element
content: The element CSS key applies Tailwind classes to the modal wrapper. This
modal uses rounded-2xl and shadow-2xl on the element key.
- id: confirm_css_body
type: ConfirmModal
class:
.body: bg-bg-layout p-6
properties:
title: Styled Body
content: The body CSS key targets the modal body area. This modal uses
bg-bg-layout and p-6 on the body key for a tinted content area.
```
This modal uses theme tokens to set a custom header background, title color, content background, and footer background.
This modal uses confirmBodyPadding and confirmBtnsMarginTop tokens for tighter spacing. The confirmIconMarginInlineEnd adjusts icon-to-text distance.
This modal uses borderRadiusLG for extra-rounded corners and colorBgMask for a tinted overlay backdrop.
```yaml
- id: confirm_theme_colors_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom Colors
color: primary
variant: outlined
events:
onClick:
- id: confirm_theme_colors_open
type: CallMethod
params:
blockId: confirm_theme_colors
method: open
- id: confirm_theme_padding_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom Padding
color: primary
variant: outlined
events:
onClick:
- id: confirm_theme_padding_open
type: CallMethod
params:
blockId: confirm_theme_padding
method: open
- id: confirm_theme_radius_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom Radius and Mask
color: primary
variant: outlined
events:
onClick:
- id: confirm_theme_radius_open
type: CallMethod
params:
blockId: confirm_theme_radius
method: open
- id: confirm_theme_colors
type: ConfirmModal
properties:
title: Custom Color Theme
content: This modal uses theme tokens to set a custom header background, title
color, content background, and footer background.
theme:
titleColor: "#0958d9"
titleFontSize: 18
- id: confirm_theme_padding
type: ConfirmModal
properties:
title: Custom Padding
content: This modal uses confirmBodyPadding and confirmBtnsMarginTop tokens for
tighter spacing. The confirmIconMarginInlineEnd adjusts icon-to-text
distance.
theme:
confirmBodyPadding: 16px 24px
confirmBtnsMarginTop: 16
confirmIconMarginInlineEnd: 12
- id: confirm_theme_radius
type: ConfirmModal
properties:
title: Rounded with Tinted Mask
content: This modal uses borderRadiusLG for extra-rounded corners and
colorBgMask for a tinted overlay backdrop.
theme:
borderRadiusLG: 20
colorBgMask: rgba(0, 0, 100, 0.3)
titleLineHeight: 2
```
Sarah Chen - Product Manager
James Park - Engineering Lead
```yaml
- id: delete_flow_card
type: Card
properties:
title: Team Members
size: small
blocks:
- id: delete_flow_list_item_1
type: Box
layout:
gap: 12
align: center
blocks:
- id: delete_flow_avatar_1
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 32
color: "#1677ff"
- id: delete_flow_name_1
type: Paragraph
layout:
flex: 1 1 0
properties:
content: Sarah Chen - Product Manager
- id: delete_flow_remove_btn_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Remove
icon: delete
color: danger
variant: text
size: small
events:
onClick:
- id: delete_flow_set_member
type: SetState
params:
member_to_remove: Sarah Chen
- id: delete_flow_open_confirm
type: CallMethod
params:
blockId: delete_flow_confirm
method: open
- id: delete_flow_divider
type: Divider
- id: delete_flow_list_item_2
type: Box
layout:
gap: 12
align: center
blocks:
- id: delete_flow_avatar_2
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 32
color: "#52c41a"
- id: delete_flow_name_2
type: Paragraph
layout:
flex: 1 1 0
properties:
content: James Park - Engineering Lead
- id: delete_flow_remove_btn_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Remove
icon: delete
color: danger
variant: text
size: small
events:
onClick:
- id: delete_flow_set_member_2
type: SetState
params:
member_to_remove: James Park
- id: delete_flow_open_confirm_2
type: CallMethod
params:
blockId: delete_flow_confirm
method: open
- id: delete_flow_confirm
type: ConfirmModal
properties:
title: Remove Team Member
status: error
icon:
name: UserMinus
color: "#ff4d4f"
okText: Remove
okButton:
danger: true
cancelText: Keep Member
content:
_string.concat:
- "Are you sure you want to remove "
- _state: member_to_remove
- " from the team? They will lose access to all project resources."
events:
onOk:
- id: delete_flow_ok_msg
type: DisplayMessage
params:
content:
_string.concat:
- _state: member_to_remove
- " has been removed from the team."
status: success
```
Please verify your ticket details before submitting. You will receive a confirmation email once the ticket is created.
```yaml
- id: form_submit_card
type: Card
properties:
title: Submit Support Ticket
blocks:
- id: form_submit_subject
type: TextInput
properties:
title: Subject
placeholder: Brief description of the issue
- id: form_submit_priority
type: Selector
properties:
title: Priority
options:
- label: Low
value: low
- label: Medium
value: medium
- label: High
value: high
- label: Critical
value: critical
- id: form_submit_description
type: TextArea
properties:
title: Description
placeholder: Describe your issue in detail...
rows: 4
- id: form_submit_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Submit Ticket
icon: send
color: primary
variant: solid
events:
onClick:
- id: form_submit_open_confirm
type: CallMethod
params:
blockId: form_submit_confirm
method: open
- id: form_submit_confirm
type: ConfirmModal
properties:
title: Submit Support Ticket?
content: Please verify your ticket details before submitting. You will receive a
confirmation email once the ticket is created.
status: confirm
okText: Submit
cancelText: Review Again
centered: true
width: 480
icon: check-circle
events:
onOk:
- id: form_submit_ok_msg
type: DisplayMessage
params:
content: Support ticket submitted successfully. Check your email for
confirmation.
status: success
- id: form_submit_ok_reset
type: SetState
params:
form_submit_subject: null
form_submit_priority: null
form_submit_description: null
onCancel:
- id: form_submit_cancel_msg
type: DisplayMessage
params:
content: Take your time to review the details.
status: info
```
You have unsaved changes that will be lost if you leave this page. Do you want to save your changes before leaving?
```yaml
- id: nav_guard_card
type: Card
properties:
title: Edit Profile
blocks:
- id: nav_guard_name
type: TextInput
properties:
title: Display Name
placeholder: Enter your display name
- id: nav_guard_email
type: TextInput
properties:
title: Email Address
placeholder: name@example.com
- id: nav_guard_actions
type: Box
layout:
gap: 8
justify: end
blocks:
- id: nav_guard_save_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Save Changes
color: primary
variant: solid
events:
onClick:
- id: nav_guard_save_msg
type: DisplayMessage
params:
content: Profile saved successfully.
status: success
- id: nav_guard_leave_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Leave Page
color: default
variant: outlined
events:
onClick:
- id: nav_guard_open_confirm
type: CallMethod
params:
blockId: nav_guard_confirm
method: open
- id: nav_guard_confirm
type: ConfirmModal
properties:
title: Unsaved Changes
content: You have unsaved changes that will be lost if you leave this page. Do
you want to save your changes before leaving?
status: warning
icon: warning
okText: Save & Leave
cancelText: Discard Changes
closable: true
events:
onOk:
- id: nav_guard_ok_msg
type: DisplayMessage
params:
content: Changes saved. Navigating away...
status: success
- id: nav_guard_ok_link
type: Link
params:
home: true
onCancel:
- id: nav_guard_cancel_link
type: Link
params:
home: true
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `title` | string | - | Modal title - supports html. |
| `centered` | boolean | `false` | Centered Modal. |
| `closable` | boolean \| object | `false` | Whether a close (x) button is visible on top right of the confirm dialog or not. Set `{ disabled: true }` to show the button disabled. |
| `closable.disabled` | boolean | `false` | Show the close button, but disabled. |
| `content` | string | - | Modal content. Overridden by the "content" content area - supports html. |
| `icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize modal icon. |
| `icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `icon.color` | string | - | Icon color. |
| `icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `focusable` | object | - | Focus management of the dialog. |
| `focusable.trap` | boolean | `true` | Keep keyboard focus inside the dialog while it is open. |
| `focusable.focusTriggerAfterClose` | boolean | `true` | Return focus to the element that opened the dialog after it closes. |
| `focusable.autoFocusButton` | string \| null | `"ok"` | The button that receives focus when the confirm modal opens. Set to null to focus neither. Enum: `ok`, `cancel`, `null`. |
| `keyboard` | boolean | `true` | Whether pressing Esc closes the confirm modal. |
| `mask` | boolean \| object | `true` | Whether to show the mask. Set an object to configure the mask with `enabled`, `blur` and `closable`. |
| `mask.enabled` | boolean | `true` | Whether to show the mask. |
| `mask.blur` | boolean | `false` | Blur the page behind the mask. |
| `mask.closable` | boolean | - | Whether clicking the mask closes the dialog. Takes precedence over `maskClosable`. |
| `maskClosable` | boolean | `false` | Whether to close the modal dialog when the mask (area outside the modal) is clicked. `mask.closable` takes precedence. |
| `scrollLock` | boolean | `true` | Whether to lock page scrolling while the confirm modal is open. |
| `okText` | string | - | Text of the Ok button. When unset, antd uses the localized default from ConfigProvider locale. |
| `cancelText` | string | - | Text of the Cancel button. When unset, antd uses the localized default from ConfigProvider locale. |
| `okButton` | object | - | Ok button properties. |
| `okButton.type` | string | - | The button type. Enum: `default`, `primary`, `dashed`, `text`, `link`. |
| `okButton.danger` | boolean | `false` | Set the danger status of the button. |
| `okButton.disabled` | boolean | `false` | Disable the button. |
| `okButton.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to show in the button. |
| `okButton.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `okButton.icon.color` | string | - | Icon color. |
| `okButton.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `okButton.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `okButton.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `okButton.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `okButton.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `okButton.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `okButton.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `okButton.iconPlacement` | string | `"start"` | Place the icon before (`start`) or after (`end`) the button text. Enum: `start`, `end`. |
| `cancelButton` | object | - | Cancel button properties. |
| `cancelButton.type` | string | - | The button type. Enum: `default`, `primary`, `dashed`, `text`, `link`. |
| `cancelButton.danger` | boolean | `false` | Set the danger status of the button. |
| `cancelButton.disabled` | boolean | `false` | Disable the button. |
| `cancelButton.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to show in the button. |
| `cancelButton.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `cancelButton.icon.color` | string | - | Icon color. |
| `cancelButton.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `cancelButton.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `cancelButton.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `cancelButton.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `cancelButton.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `cancelButton.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `cancelButton.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `cancelButton.iconPlacement` | string | `"start"` | Place the icon before (`start`) or after (`end`) the button text. Enum: `start`, `end`. |
| `width` | number \| string | `416` | Width of the modal dialog. |
| `zIndex` | number | `1000` | The z-index of the Modal. |
| `status` | string | `"confirm"` | Modal status type. Enum: `success`, `error`, `info`, `warning`, `confirm`. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design modal tokens](https://ant.design/components/modal#design-token). |
| `theme.headerBg` | string | - | Background color of the modal header. |
| `theme.titleLineHeight` | number | `1.5` | Line height of the modal title. |
| `theme.titleFontSize` | number | `16` | Font size of the modal title. |
| `theme.titleColor` | string | - | Color of the modal title text. |
| `theme.contentBg` | string | - | Background color of the modal content. |
| `theme.footerBg` | string | `"transparent"` | Background color of the modal footer. |
| `theme.contentPadding` | number \| string | - | Padding of the content area. |
| `theme.confirmBodyPadding` | number \| string | - | Padding of the confirm modal body. |
| `theme.confirmIconMarginInlineEnd` | number \| string | - | Inline end margin of the confirm modal icon. |
| `theme.confirmBtnsMarginTop` | number \| string | - | Margin top of the confirm modal buttons. |
| `theme.borderRadiusLG` | number | `8` | Border radius of the modal. |
| `theme.colorBgMask` | string | `"rgba(0, 0, 0, 0.45)"` | Background color of the modal mask. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onOk` | \- | Trigger actions when Ok button is clicked. |
| `onOpen` | \- | Trigger actions when confirm modal is opened. |
| `onCancel` | \- | Trigger actions when Cancel button is clicked. |
| `onClose` | \- | Trigger actions after the confirm modal has closed, once the onOk or onCancel actions are completed. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The ConfirmModal element. |
| `/body` | The ConfirmModal body. |
| `/cancelIcon` | The cancel button icon in the ConfirmModal. |
| `/icon` | The icon in the ConfirmModal. |
| `/okIcon` | The ok button icon in the ConfirmModal. |
| Slot | Description |
| --- | --- |
| `content` | Content blocks in the confirm modal body. |
---
url: https://docs.lowdefy.com/md/container-blocks/content.md
---
# Content
Main content layout section.
The Content block is the main content area within a Layout. It maps to Ant Design's Layout.Content component and holds the primary page content.
Content without any special configuration. It fills the available space within its parent Layout.
```yaml
- id: content_basic_layout
type: Layout
blocks:
- id: content_basic
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
minHeight: 200px
blocks:
- id: content_basic_text
type: Paragraph
properties:
content: >
The Content block is the main content area within a Layout. It
maps to Ant Design's Layout.Content component and holds the
primary page content.
- id: content_empty_layout
type: Layout
blocks:
- id: content_empty
type: Content
style:
padding: 24px
background: var(--ant-color-bg-layout)
minHeight: 120px
display: flex
alignItems: center
justifyContent: center
blocks:
- id: content_empty_text
type: Paragraph
properties:
content: >
Content without any special configuration. It fills the available
space within its parent Layout.
```
My Application
Welcome Back
Content works within a Layout alongside Header and Footer blocks to form a complete page structure. It automatically fills the available vertical space between other layout sections.
© 2026 My Application
```yaml
- id: content_full_page_layout
type: Layout
style:
minHeight: 350px
blocks:
- id: content_full_page_header
type: Header
style:
paddingInline: 24px
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: content_full_page_header_title
type: Title
properties:
content: My Application
level: 4
style:
.element:
margin: 0
- id: content_full_page_main
type: Content
style:
padding: 24px 48px
background: var(--ant-color-bg-container)
blocks:
- id: content_full_page_title
type: Title
properties:
content: Welcome Back
level: 3
- id: content_full_page_desc
type: Paragraph
properties:
content: >
Content works within a Layout alongside Header and Footer blocks
to form a complete page structure. It automatically fills the
available vertical space between other layout sections.
- id: content_full_page_footer
type: Footer
style:
textAlign: center
blocks:
- id: content_full_page_footer_text
type: Paragraph
properties:
content: © 2026 My Application
```
App with Sidebar
Dashboard
When used alongside a Sider block, Content fills the remaining horizontal space. This is the standard layout pattern for admin dashboards and applications with navigation sidebars.
```yaml
- id: content_sider_outer
type: Layout
style:
minHeight: 350px
blocks:
- id: content_sider_header
type: Header
style:
paddingInline: 24px
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: content_sider_header_title
type: Title
properties:
content: App with Sidebar
level: 4
style:
.element:
margin: 0
- id: content_sider_inner
type: Layout
properties:
hasSider: true
blocks:
- id: content_sider_nav
type: Sider
layout:
flex: 0 0 auto
properties:
width: 200
style:
background: var(--ant-color-bg-container)
paddingTop: 16px
blocks:
- id: content_sider_menu
type: Menu
properties:
mode: inline
links:
- id: cs_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: cs_users
type: MenuLink
properties:
title: Users
icon: user
- id: cs_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: content_sider_main
type: Content
layout:
flex: 1 1 auto
style:
padding: 24px
background: var(--ant-color-bg-container)
margin: 0 16px
blocks:
- id: content_sider_main_title
type: Title
properties:
content: Dashboard
level: 3
- id: content_sider_main_text
type: Paragraph
properties:
content: >
When used alongside a Sider block, Content fills the remaining
horizontal space. This is the standard layout pattern for
admin dashboards and applications with navigation sidebars.
```
```yaml
- id: content_theme_layout
type: Layout
properties:
theme:
bodyBg: "#e6f4ff"
blocks:
- id: content_theme_custom
type: Content
style:
padding: 24px
minHeight: 150px
blocks:
- id: content_theme_text
type: Html
properties:
html: The parent Layout theme sets the background behind the Content area with
the bodyBg token.
- id: content_theme_warm_layout
type: Layout
properties:
theme:
bodyBg: "#fff7e6"
blocks:
- id: content_theme_warm
type: Content
style:
padding: 24px
minHeight: 150px
blocks:
- id: content_theme_warm_text
type: Html
properties:
html: A warm-toned content area from the same Layout token.
```
Rounded Content with Tailwind
Use the element CSS key to apply Tailwind classes directly to the Content element. Content has one CSS key: element, which targets the Layout.Content wrapper.
Gradient Background
Tailwind gradient and shadow utilities applied via the element CSS key create a visually distinct content area without needing custom CSS.
Accent Border Content
A left accent border highlights the content area. Combine Tailwind border utilities with background colors for status-aware content regions.
```yaml
- id: content_css_rounded_layout
type: Layout
blocks:
- id: content_css_rounded
type: Content
class:
.element: bg-bg-layout rounded-xl p-6 m-4
style:
minHeight: 150px
blocks:
- id: content_css_rounded_title
type: Title
properties:
content: Rounded Content with Tailwind
level: 4
- id: content_css_rounded_text
type: Paragraph
properties:
content: "Use the element CSS key to apply Tailwind classes directly to the
Content element. Content has one CSS key: element, which targets
the Layout.Content wrapper."
- id: content_css_gradient_layout
type: Layout
blocks:
- id: content_css_gradient
type: Content
class:
.element: bg-gradient-to-br from-primary/10 to-primary/5 p-8 m-4 rounded-lg
shadow-inner
style:
minHeight: 150px
blocks:
- id: content_css_gradient_title
type: Title
properties:
content: Gradient Background
level: 4
- id: content_css_gradient_text
type: Paragraph
properties:
content: >
Tailwind gradient and shadow utilities applied via the element CSS
key create a visually distinct content area without needing custom
CSS.
- id: content_css_border_layout
type: Layout
blocks:
- id: content_css_border
type: Content
class:
.element: border-l-4 border-l-green-500 bg-bg-layout p-6 m-4
style:
minHeight: 150px
blocks:
- id: content_css_border_title
type: Title
properties:
content: Accent Border Content
level: 4
- id: content_css_border_text
type: Paragraph
properties:
content: >
A left accent border highlights the content area. Combine Tailwind
border utilities with background colors for status-aware content
regions.
```
Analytics Dashboard
User John updated the project settings — 2 minutes ago
Deployment to production completed — 15 minutes ago
New team member Sarah joined — 1 hour ago
```yaml
- id: content_dashboard_outer
type: Layout
style:
minHeight: 450px
blocks:
- id: content_dashboard_header
type: Header
style:
justifyContent: space-between
borderBottom: 1px solid var(--ant-color-border)
paddingInline: 24px
blocks:
- id: content_dashboard_header_title
type: Title
layout:
flex: 0 0 auto
properties:
content: Analytics Dashboard
level: 4
style:
.element:
margin: 0
- id: content_dashboard_header_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Export Report
icon: download
color: default
variant: outlined
size: small
- id: content_dashboard_inner
type: Layout
properties:
hasSider: true
blocks:
- id: content_dashboard_sider
type: Sider
layout:
flex: 0 0 auto
properties:
width: 200
style:
background: var(--ant-color-bg-container)
paddingTop: 16px
blocks:
- id: content_dashboard_menu
type: Menu
properties:
mode: inline
links:
- id: cd_overview
type: MenuLink
properties:
title: Overview
icon: home
- id: cd_analytics
type: MenuLink
properties:
title: Analytics
icon: chart
- id: cd_reports
type: MenuLink
properties:
title: Reports
icon: document
- id: cd_team
type: MenuLink
properties:
title: Team
icon: users
- id: content_dashboard_main
type: Content
layout:
flex: 1 1 auto
style:
padding: 24px
background: var(--ant-color-bg-layout)
blocks:
- id: content_dashboard_stats_row
type: Box
layout:
gap: 16
blocks:
- id: content_dashboard_stat1
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: content_dashboard_stat1_val
type: Statistic
properties:
title: Total Users
value: 12480
- id: content_dashboard_stat2
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: content_dashboard_stat2_val
type: Statistic
properties:
title: Revenue
value: 48650
prefix: $
- id: content_dashboard_stat3
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: content_dashboard_stat3_val
type: Statistic
properties:
title: Conversion
value: 3.2
suffix: "%"
- id: content_dashboard_main_card
type: Card
properties:
title: Recent Activity
blocks:
- id: content_dashboard_activity_1
type: Paragraph
properties:
content: User John updated the project settings — 2 minutes ago
- id: content_dashboard_activity_2
type: Paragraph
properties:
content: Deployment to production completed — 15 minutes ago
- id: content_dashboard_activity_3
type: Paragraph
properties:
content: New team member Sarah joined — 1 hour ago
```
Account Settings
Profile Information
Update your personal details and preferences below.
```yaml
- id: content_settings_outer
type: Layout
style:
minHeight: 400px
blocks:
- id: content_settings_header
type: Header
style:
paddingInline: 24px
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: content_settings_header_title
type: Title
properties:
content: Account Settings
level: 4
style:
.element:
margin: 0
- id: content_settings_main
type: Content
style:
padding: 32px 48px
background: var(--ant-color-bg-container)
blocks:
- id: content_settings_title
type: Title
properties:
content: Profile Information
level: 3
- id: content_settings_desc
type: Paragraph
properties:
content: Update your personal details and preferences below.
- id: content_settings_form_name
type: TextInput
properties:
title: Display Name
placeholder: Enter your display name
- id: content_settings_form_email
type: TextInput
properties:
title: Email Address
placeholder: you@example.com
- id: content_settings_form_bio
type: TextArea
properties:
title: Bio
placeholder: Tell us about yourself
rows: 3
- id: content_settings_divider
type: Divider
- id: content_settings_actions
type: Box
layout:
gap: 12
justify: end
blocks:
- id: content_settings_cancel_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel
color: default
variant: outlined
- id: content_settings_save_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Save Changes
color: primary
variant: solid
icon: save
events:
onClick:
- id: content_settings_save_msg
type: DisplayMessage
params:
content: Settings saved successfully!
status: success
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `theme` | object | - | Not applied: antd scopes Layout design tokens to the Layout element, so set tokens such as headerHeight or footerBg on the parent Layout block theme. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Content element. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks in the content area. |
---
url: https://docs.lowdefy.com/md/container-blocks/descriptions.md
---
# Descriptions
Description list with configurable layout and columns.
```yaml
- id: basic_array_items
type: Descriptions
properties:
title: User Profile
items:
- label: Full Name
value: Sarah Johnson
- label: Email
value: sarah.johnson@example.com
- label: Phone
value: +1 (555) 123-4567
- label: Location
value: San Francisco, CA
- label: Role
value: Senior Developer
- label: Department
value: Engineering
- id: basic_object_items
type: Descriptions
properties:
title: Object Format
items:
Name: Alex Chen
Email: alex.chen@example.com
Phone: +1 (555) 987-6543
Location: New York, NY
Role: Product Manager
Team: Growth
```
```yaml
- id: bordered_default
type: Descriptions
properties:
title: Borderless (Default)
items:
- label: Hostname
value: prod-web-01
- label: IP Address
value: 192.168.1.100
- label: OS
value: Ubuntu 22.04 LTS
- label: CPU
value: 8 cores
- label: Memory
value: 32 GB
- label: Storage
value: 500 GB SSD
- id: bordered_true
type: Descriptions
properties:
title: Bordered
bordered: true
items:
- label: Hostname
value: prod-web-02
- label: IP Address
value: 192.168.1.101
- label: OS
value: Debian 12
- label: CPU
value: 16 cores
- label: Memory
value: 64 GB
- label: Storage
value: 1 TB NVMe
```
```yaml
- id: size_default
type: Descriptions
properties:
title: Default Size
size: default
bordered: true
items:
- label: Product
value: Widget Pro
- label: SKU
value: WGT-PRO-001
- label: Price
value: $49.99
- label: Category
value: Electronics
- label: Weight
value: 0.5 kg
- label: In Stock
value: 1,250 units
- id: size_medium
type: Descriptions
properties:
title: Medium Size
size: medium
bordered: true
items:
- label: Product
value: Widget Plus
- label: SKU
value: WGT-PLS-003
- label: Price
value: $34.99
- label: Category
value: Electronics
- label: Weight
value: 0.4 kg
- label: In Stock
value: 2,015 units
- id: size_small
type: Descriptions
properties:
title: Small Size
size: small
bordered: true
items:
- label: Product
value: Widget Lite
- label: SKU
value: WGT-LIT-002
- label: Price
value: $24.99
- label: Category
value: Electronics
- label: Weight
value: 0.3 kg
- label: In Stock
value: 3,480 units
```
```yaml
- id: vertical_borderless
type: Descriptions
properties:
title: Order Summary
layout: vertical
items:
- label: Order Number
value: ORD-2026-0042
- label: Date
value: March 10, 2026
- label: Status
value: Shipped
- label: Total
value: $129.97
- id: vertical_bordered
type: Descriptions
properties:
title: Invoice Details
bordered: true
layout: vertical
items:
- label: Invoice Number
value: INV-2026-003
- label: Date Issued
value: March 1, 2026
- label: Due Date
value: March 31, 2026
- label: Amount
value: $2,450.00
- label: Status
value: Pending
- label: Payment Method
value: Wire Transfer
```
```yaml
- id: columns_1
type: Descriptions
properties:
title: Single Column
column: 1
bordered: true
items:
- label: Full Name
value: Alex Chen
- label: Email
value: alex.chen@example.com
- label: Phone
value: +1 (555) 987-6543
- label: Address
value: 123 Main Street, New York, NY 10001
- id: columns_2
type: Descriptions
properties:
title: Two Columns
column: 2
bordered: true
items:
- label: First Name
value: Maria
- label: Last Name
value: Garcia
- label: Department
value: Marketing
- label: Title
value: Director
- label: Start Date
value: January 15, 2024
- label: Office
value: Building A, Floor 3
- id: columns_4
type: Descriptions
properties:
title: Four Columns
column: 4
bordered: true
items:
- label: Q1
value: $125,000
- label: Q2
value: $142,500
- label: Q3
value: $138,900
- label: Q4
value: $167,200
- label: YoY Growth
value: +12.4%
- label: Market Share
value: 23.1%
- label: Customers
value: 4,582
- label: NPS Score
value: 72
```
```yaml
- id: responsive_columns
type: Descriptions
properties:
title: Employee Record
bordered: true
column:
xs: 1
sm: 2
md: 3
lg: 3
xl: 4
items:
- label: Employee ID
value: EMP-1042
- label: Full Name
value: Jordan Rivera
- label: Department
value: Engineering
- label: Title
value: Staff Engineer
- label: Manager
value: Pat Williams
- label: Location
value: Austin, TX
- label: Start Date
value: April 2022
- label: Level
value: L5
```
```yaml
- id: spanning_basic
type: Descriptions
properties:
title: Support Ticket
bordered: true
items:
- label: Ticket ID
value: TICKET-7891
- label: Priority
value: High
- label: Created
value: March 9, 2026
- label: Description
value: Users are unable to log in after the latest deployment. The
authentication service returns a 503 error when attempting to validate
credentials against the LDAP directory.
span: 3
- id: spanning_mixed
type: Descriptions
properties:
title: Project Overview
bordered: true
column: 3
items:
- label: Project Name
value: Phoenix Migration
- label: Status
value: In Progress
- label: Priority
value: Critical
- label: Lead
value: Priya Patel
- label: Team Size
value: 12
- label: Sprint
value: Sprint 14
- label: Objective
value: Migrate all legacy microservices from the monolithic architecture to a
cloud-native Kubernetes deployment with zero downtime and full
backwards compatibility.
span: 2
- label: Deadline
value: June 30, 2026
- id: spanning_full_width
type: Descriptions
properties:
title: API Error Log
bordered: true
column: 3
items:
- label: Timestamp
value: 2026-03-10T14:23:07Z
- label: Endpoint
value: /api/v2/users/auth
- label: Status Code
value: 503
- label: Stack Trace
value: "Error: ECONNREFUSED 10.0.1.45:5432 - Connection refused at
TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)"
span: 3
- label: Resolution
value: Database connection pool exhausted. Increased max_connections from 100 to
250 and implemented connection retry logic with exponential backoff.
span: 3
- id: spanning_filled
type: Descriptions
properties:
title: Shipment
bordered: true
column: 3
items:
- label: Carrier
value: Road freight
- label: Tracking
value: Use span filled to take the rest of the row, whatever the column count.
span: filled
- label: Weight
value: 12 kg
- label: Pieces
value: 3
- label: Insured
value: Yes
```
```yaml
- id: colon_true
type: Descriptions
properties:
title: With Colons (Default)
colon: true
items:
- label: Name
value: Sarah Johnson
- label: Role
value: Engineer
- label: Team
value: Platform
- id: colon_false
type: Descriptions
properties:
title: Without Colons
colon: false
items:
- label: Name
value: Sarah Johnson
- label: Role
value: Engineer
- label: Team
value: Platform
```
```yaml
- id: no_title_borderless
type: Descriptions
properties:
items:
- label: Browser
value: Chrome 122
- label: Operating System
value: macOS 15.3
- label: Screen Resolution
value: 2560 x 1440
- label: Language
value: English (US)
- label: Timezone
value: America/Los_Angeles
- label: User Agent
value: Mozilla/5.0
- id: no_title_bordered
type: Descriptions
properties:
bordered: true
items:
- label: Protocol
value: HTTPS
- label: Method
value: POST
- label: Content-Type
value: application/json
- label: Response Time
value: 142ms
- label: Cache
value: MISS
- label: CDN Node
value: us-west-2a
```
```yaml
- id: html_content
type: Descriptions
properties:
title: Release Notes
bordered: true
items:
- label: Version
value: 'v3.2.0 '
- label: Release Date
value: March 10, 2026
- label: Status
value: 'Stable '
- label: Changes
value: Added OAuth2 support, fixed memory leak in worker pool, improved query
performance by 40%
span: 3
```
```yaml
- id: desc_with_extra
type: Descriptions
properties:
title: Account Details
bordered: true
items:
- label: Account ID
value: ACC-2026-0891
- label: Plan
value: Enterprise
- label: Status
value: Active
- label: Created
value: January 12, 2024
- label: Billing Cycle
value: Annual
- label: Next Invoice
value: January 12, 2027
slots:
extra:
blocks:
- id: desc_extra_button
type: Button
layout:
flex: 0 0 auto
properties:
title: Edit
color: primary
variant: link
size: small
```
```yaml
- id: user_account
type: Descriptions
properties:
title: Account Information
bordered: true
column: 2
items:
- label: Username
value: sjohnson
- label: Display Name
value: Sarah Johnson
- label: Email
value: sarah.johnson@acme.com
- label: Phone
value: +1 (555) 123-4567
- label: Role
value: Administrator
- label: Last Login
value: March 10, 2026 at 9:14 AM
- label: Two-Factor Auth
value: Enabled
- label: API Key
value: sk-****-****-7f3a
- label: Permissions
value: Read, Write, Delete, Manage Users, Audit Logs
span: 2
```
```yaml
- id: order_details
type: Descriptions
properties:
title: "Order #ORD-2026-11583"
bordered: true
items:
- label: Customer
value: Acme Corporation
- label: Date Placed
value: March 8, 2026
- label: Payment Method
value: Visa ending in 4242
- label: Subtotal
value: $1,249.00
- label: Tax (8.25%)
value: $103.04
- label: Shipping
value: $0.00 (Free)
- label: Total
value: $1,352.04
span: 3
- id: order_shipping
type: Descriptions
properties:
title: Shipping Information
bordered: true
column: 2
items:
- label: Carrier
value: FedEx Ground
- label: Tracking Number
value: 7489 2305 1847
- label: Ship Date
value: March 9, 2026
- label: Est. Delivery
value: March 14, 2026
- label: Ship From
value: Warehouse B, Dallas, TX
- label: Ship To
value: 456 Oak Avenue, Portland, OR 97201
```
```yaml
- id: system_info
type: Descriptions
properties:
title: System Health Dashboard
bordered: true
size: small
items:
- label: Service
value: api-gateway
- label: Status
value: 'Healthy '
- label: Uptime
value: 99.97%
- label: CPU Usage
value: 34%
- label: Memory
value: 12.4 / 32 GB
- label: Disk
value: 187 / 500 GB
- label: Active Connections
value: 2,847
- label: Requests/sec
value: 1,243
- label: Avg Latency
value: 23ms
- label: Error Rate
value: '0.02% '
- label: Last Deploy
value: March 10, 2026 08:30 UTC
- label: Version
value: v2.14.3-rc1
```
```yaml
- id: item_label_styles
type: Descriptions
properties:
title: Styled Labels and Values
bordered: true
items:
- label: Revenue
value: $487,200
labelStyle:
fontWeight: bold
contentStyle:
color: "#52c41a"
fontWeight: bold
- label: Expenses
value: $312,100
labelStyle:
fontWeight: bold
contentStyle:
color: "#ff4d4f"
fontWeight: bold
- label: Net Profit
value: $175,100
labelStyle:
fontWeight: bold
contentStyle:
color: "#52c41a"
fontWeight: bold
fontSize: 16
- id: item_inline_styles
type: Descriptions
properties:
title: Custom Item Backgrounds
bordered: true
items:
- label: Critical
value: 2 issues
- label: Warning
value: 5 issues
- label: Info
value: 12 issues
```
```yaml
- id: css_element
type: Descriptions
properties:
title: Element CSS Key
bordered: true
items:
- label: Name
value: Jordan Rivera
- label: Email
value: jordan@example.com
- label: Phone
value: +1 (555) 444-7890
style:
.element:
border: "2px solid #1677ff"
borderRadius: 8px
padding: 4px
- id: css_label_content
type: Descriptions
properties:
title: Label and Content CSS Keys
bordered: true
items:
- label: Service
value: Production API
- label: Region
value: us-east-1
- label: Tier
value: Premium
style:
.label:
fontWeight: bold
color: "#1677ff"
.content:
fontStyle: italic
```
```yaml
- id: tailwind_shadow
type: Descriptions
class: shadow-md rounded-lg overflow-hidden
properties:
title: Card-Style Descriptions
bordered: true
items:
- label: Company
value: Acme Inc.
- label: Industry
value: Technology
- label: Founded
value: 2018
- label: Employees
value: 250
- label: Headquarters
value: San Francisco, CA
- label: Revenue
value: $48M ARR
- id: tailwind_dark_bg
type: Box
class: bg-bg-layout p-4 rounded-lg
blocks:
- id: tailwind_on_dark
type: Descriptions
properties:
title: 'Dark Background '
colon: false
items:
- label: 'Status '
value: 'Online '
- label: 'Latency '
value: '12ms '
- label: 'Region '
value: 'us-west-2 '
```
```yaml
- id: theme_custom_colors
type: Descriptions
properties:
title: Custom Label Colors
bordered: true
theme:
labelColor: "#0958d9"
contentColor: "#434343"
items:
- label: Environment
value: Production
- label: Region
value: us-east-1
- label: Availability Zone
value: us-east-1a
- label: Instance Type
value: m5.xlarge
- label: Auto Scaling
value: Enabled
- label: Load Balancer
value: ALB-prod-01
- id: theme_warm_palette
type: Descriptions
properties:
title: Warm Color Palette
bordered: true
theme:
labelColor: "#ad4e00"
titleColor: "#ad4e00"
contentColor: "#613400"
items:
- label: Cafe
value: The Daily Grind
- label: Location
value: 42 Roast Avenue
- label: Hours
value: 7 AM - 9 PM
- label: Specialty
value: Single-origin pour over
- label: Rating
value: 4.8 / 5.0
- label: Price Range
value: $$
- id: theme_compact_spacing
type: Descriptions
properties:
title: Compact Spacing
bordered: true
size: small
theme:
itemPaddingBottom: 4
itemPaddingEnd: 8
titleMarginBottom: 8
items:
- label: CPU
value: 24%
- label: RAM
value: 8.2 GB
- label: Disk
value: 45%
- label: Network In
value: 12 Mbps
- label: Network Out
value: 8 Mbps
- label: Processes
value: 312
- id: theme_green_palette
type: Descriptions
properties:
title: Success Theme
bordered: true
theme:
labelColor: "#135200"
titleColor: "#135200"
contentColor: "#237804"
items:
- label: Test Suite
value: Integration Tests
- label: Passed
value: 247 / 247
- label: Duration
value: 4m 32s
- label: Coverage
value: 94.2%
- label: Branch
value: main
- label: Commit
value: a3f7b21
- id: theme_wide_colons
type: Descriptions
properties:
title: Wide Colon Spacing
theme:
colonMarginLeft: 4
colonMarginRight: 16
items:
- label: First Name
value: Taylor
- label: Last Name
value: Brooks
- label: Department
value: Design
```
```yaml
- id: combined_full_profile
type: Descriptions
class: shadow-sm rounded-lg overflow-hidden
properties:
title: Employee Profile
bordered: true
column: 2
size: small
theme:
labelColor: "#1d39c4"
items:
- label: Employee ID
value: EMP-4521
- label: Full Name
value: Priya Patel
- label: Department
value: Engineering
- label: Title
value: Principal Engineer
- label: Email
value: priya.patel@acme.com
- label: Phone
value: +1 (555) 867-5309
- label: Office
value: Building C, Floor 7
- label: Manager
value: David Kim
- label: Bio
value: 15+ years of experience in distributed systems and cloud architecture.
Led the migration of core services to Kubernetes, reducing
infrastructure costs by 40%.
span: 2
- id: combined_invoice
type: Descriptions
class: shadow-sm rounded-lg overflow-hidden
properties:
title: "Invoice #INV-2026-0847"
bordered: true
layout: vertical
column: 4
size: small
items:
- label: Billed To
value: Acme Corporation
- label: Invoice Date
value: March 1, 2026
- label: Due Date
value: March 31, 2026
- label: Status
value: 'Pending '
- label: Professional Services (160 hrs @ $150/hr)
value: $24,000.00
span: 2
- label: Cloud Infrastructure
value: $3,200.00
- label: Support Plan
value: $1,800.00
- label: Subtotal
value: $29,000.00
- label: Tax (8%)
value: $2,320.00
- label: Total Due
value: '$31,320.00 '
span: 2
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `bordered` | boolean | `false` | Render items in a table. |
| `colon` | boolean | `true` | Include a colon in item labels. |
| `column` | number \| object | `3` | The number of description items in a row. |
| `column.xs` | integer | - | The number of description items in a row for 'xs' media size. |
| `column.sm` | integer | - | The number of description items in a row for 'sm' media size. |
| `column.md` | integer | - | The number of description items in a row for 'md' media size. |
| `column.lg` | integer | - | The number of description items in a row for 'lg' media size. |
| `column.xl` | integer | - | The number of description items in a row for 'xl' media size. |
| `column.xxl` | integer | - | The number of description items in a row for 'xxl' media size. |
| `column.xxxl` | integer | - | The number of description items in a row for 'xxxl' media size. |
| `itemOptions` | array | - | |
| `itemOptions.$.key` | string | - | Item key to which these settings should apply. |
| `itemOptions.$.span` | number \| string \| object | - | Item span for this key, or 'filled' to fill the rest of the row. Can also be a function that receives item and index. |
| `itemOptions.$.style` | object | - | Item css style for this key. Can also be a function that receives item and index. |
| `itemOptions.$.transformLabel` | object | - | Function to transform item key or label. Function receives arguments label, item and index. |
| `itemOptions.$.transformValue` | object | - | Function to transform item value. Function receives arguments value, item and index. |
| `items` | array \| object | - | List of items to display |
| `items.$.contentStyle` | object | - | Customize content style. |
| `items.$.labelStyle` | object | - | Customize label style. |
| `items.$.label` | string | - | Item label - supports html. |
| `items.$.value` | string \| number | - | Value of item - supports html. |
| `items.$.span` | integer \| string \| object | - | Number of columns for this item to span. Set to 'filled' to fill the rest of the row, or an object of breakpoint spans like `{ xs: 1, md: 2 }`. |
| `items.$.style` | object | - | Css style object to applied to item. |
| `layout` | string | `"horizontal"` | Put values next to or below their labels. Enum: `horizontal`, `vertical`. |
| `size` | string | `"default"` | Size of the block. `default` is the largest size. Enum: `default`, `medium`, `small`. |
| `title` | string | - | The title of the description block, placed at the top - supports html. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design descriptions tokens](https://ant.design/components/descriptions#design-token). |
| `theme.labelBg` | string | `"rgba(0, 0, 0, 0.02)"` | Background color for labels in bordered mode. |
| `theme.labelColor` | string | `"rgba(0, 0, 0, 0.45)"` | Text color for labels. |
| `theme.titleColor` | string | `"rgba(0, 0, 0, 0.88)"` | Color for the component title. |
| `theme.titleMarginBottom` | number | `20` | Bottom margin spacing for the title. |
| `theme.itemPaddingBottom` | number | `16` | Bottom padding for description items. |
| `theme.itemPaddingEnd` | number | `16` | End (right in LTR) padding for description items. |
| `theme.colonMarginRight` | number | `8` | Right margin for colons after labels. |
| `theme.colonMarginLeft` | number | `2` | Left margin for colons after labels. |
| `theme.contentColor` | string | `"rgba(0, 0, 0, 0.88)"` | Text color for content values. |
| `theme.extraColor` | string | `"rgba(0, 0, 0, 0.88)"` | Color for extra content in the header. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Descriptions element. |
| `/header` | The header row with the title and extra content. |
| `/title` | The Descriptions title. |
| `/content` | The Descriptions content. |
| `/label` | The Descriptions label. |
| Slot | Description |
| --- | --- |
| `extra` | Extra content in the header. |
---
url: https://docs.lowdefy.com/md/container-blocks/drawer.md
---
# Drawer
Panel that slides in from the edge of the screen.
This is a basic drawer with a title and default settings. It opens from the right side with the default width of 378px.
Click the X button or the mask area to close it.
```yaml
- id: drawer_basic_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Drawer
color: primary
variant: solid
events:
onClick:
- id: drawer_basic_open
type: CallMethod
params:
blockId: drawer_basic
method: setOpen
args:
- open: true
- id: drawer_basic
type: Drawer
properties:
title: Basic Drawer
blocks:
- id: drawer_basic_p1
type: Paragraph
properties:
content: This is a basic drawer with a title and default settings. It opens from
the right side with the default width of 378px.
- id: drawer_basic_p2
type: Paragraph
properties:
content: Click the X button or the mask area to close it.
```
This drawer slides in from the right side, which is the default placement.
This drawer slides in from the left side. Useful for navigation panels.
This drawer slides in from the top. Use the height property instead of width for top and bottom placements.
This drawer slides in from the bottom. Commonly used for mobile action sheets or bottom panels.
```yaml
- id: drawer_place_right_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Right (default)
color: primary
variant: outlined
events:
onClick:
- id: drawer_place_right_open
type: CallMethod
params:
blockId: drawer_place_right
method: setOpen
args:
- open: true
- id: drawer_place_left_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Left
color: primary
variant: outlined
events:
onClick:
- id: drawer_place_left_open
type: CallMethod
params:
blockId: drawer_place_left
method: setOpen
args:
- open: true
- id: drawer_place_top_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Top
color: primary
variant: outlined
events:
onClick:
- id: drawer_place_top_open
type: CallMethod
params:
blockId: drawer_place_top
method: setOpen
args:
- open: true
- id: drawer_place_bottom_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Bottom
color: primary
variant: outlined
events:
onClick:
- id: drawer_place_bottom_open
type: CallMethod
params:
blockId: drawer_place_bottom
method: setOpen
args:
- open: true
- id: drawer_place_right
type: Drawer
properties:
title: Right Placement
placement: right
blocks:
- id: drawer_place_right_content
type: Paragraph
properties:
content: This drawer slides in from the right side, which is the default
placement.
- id: drawer_place_left
type: Drawer
properties:
title: Left Placement
placement: left
blocks:
- id: drawer_place_left_content
type: Paragraph
properties:
content: This drawer slides in from the left side. Useful for navigation panels.
- id: drawer_place_top
type: Drawer
properties:
title: Top Placement
placement: top
height: 300
blocks:
- id: drawer_place_top_content
type: Paragraph
properties:
content: This drawer slides in from the top. Use the height property instead of
width for top and bottom placements.
- id: drawer_place_bottom
type: Drawer
properties:
title: Bottom Placement
placement: bottom
height: 300
blocks:
- id: drawer_place_bottom_content
type: Paragraph
properties:
content: This drawer slides in from the bottom. Commonly used for mobile action
sheets or bottom panels.
```
A narrow 200px drawer, suitable for simple menus or quick settings.
A 500px wide drawer with more room for complex content like forms, tables, or detail views.
Using a percentage width makes the drawer responsive. This drawer takes up 60% of the viewport width.
```yaml
- id: drawer_narrow_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Narrow (200px)
color: primary
variant: outlined
size: small
events:
onClick:
- id: drawer_narrow_open
type: CallMethod
params:
blockId: drawer_narrow
method: setOpen
args:
- open: true
- id: drawer_wide_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Wide (500px)
color: primary
variant: outlined
size: small
events:
onClick:
- id: drawer_wide_open
type: CallMethod
params:
blockId: drawer_wide
method: setOpen
args:
- open: true
- id: drawer_pct_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Percentage (60%)
color: primary
variant: outlined
size: small
events:
onClick:
- id: drawer_pct_open
type: CallMethod
params:
blockId: drawer_pct
method: setOpen
args:
- open: true
- id: drawer_narrow
type: Drawer
properties:
title: Narrow Drawer
width: 200
blocks:
- id: drawer_narrow_content
type: Paragraph
properties:
content: A narrow 200px drawer, suitable for simple menus or quick settings.
- id: drawer_wide
type: Drawer
properties:
title: Wide Drawer
width: 500
blocks:
- id: drawer_wide_content
type: Paragraph
properties:
content: A 500px wide drawer with more room for complex content like forms,
tables, or detail views.
- id: drawer_pct
type: Drawer
properties:
title: 60% Width Drawer
width: 60%
blocks:
- id: drawer_pct_content
type: Paragraph
properties:
content: Using a percentage width makes the drawer responsive. This drawer takes
up 60% of the viewport width.
```
```yaml
- id: drawer_padding_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Drawer with padding none
events:
onClick:
- id: drawer_padding_open
type: CallMethod
params:
blockId: drawer_padding
method: setOpen
args:
- open: true
- id: drawer_padding
type: Drawer
properties:
title: Recent invoices
padding: none
blocks:
- id: drawer_padding_rows
type: Html
properties:
html: >
INV-1042 $1,280.00
INV-1041 $640.00
INV-1040 $2,115.50
INV-1039 $96.00
```
The close button is visible in the top right corner. This is the default behavior.
The close (x) button is hidden. Users can still close by clicking the mask or pressing Escape.
```yaml
- id: drawer_closable_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Closable (default)
color: primary
variant: outlined
events:
onClick:
- id: drawer_closable_open
type: CallMethod
params:
blockId: drawer_closable
method: setOpen
args:
- open: true
- id: drawer_not_closable_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No Close Button
color: danger
variant: outlined
events:
onClick:
- id: drawer_not_closable_open
type: CallMethod
params:
blockId: drawer_not_closable
method: setOpen
args:
- open: true
- id: drawer_closable
type: Drawer
properties:
title: Closable Drawer
closable: true
blocks:
- id: drawer_closable_content
type: Paragraph
properties:
content: The close button is visible in the top right corner. This is the
default behavior.
- id: drawer_not_closable
type: Drawer
properties:
title: No Close Button
closable: false
blocks:
- id: drawer_not_closable_content
type: Paragraph
properties:
content: The close (x) button is hidden. Users can still close by clicking the
mask or pressing Escape.
- id: drawer_not_closable_close_btn
type: Button
properties:
title: Close Drawer
color: primary
variant: solid
events:
onClick:
- id: drawer_not_closable_close
type: CallMethod
params:
blockId: drawer_not_closable
method: setOpen
args:
- open: false
```
The mask is shown and clicking it closes the drawer. This is the default behavior.
No mask overlay is shown behind the drawer. The page content remains fully visible and interactive.
The mask is visible but clicking it does not close the drawer. Users must use the close button or Escape key.
```yaml
- id: drawer_mask_default_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: With Mask (default)
color: primary
variant: outlined
events:
onClick:
- id: drawer_mask_default_open
type: CallMethod
params:
blockId: drawer_mask_default
method: setOpen
args:
- open: true
- id: drawer_no_mask_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No Mask
color: primary
variant: outlined
events:
onClick:
- id: drawer_no_mask_open
type: CallMethod
params:
blockId: drawer_no_mask
method: setOpen
args:
- open: true
- id: drawer_mask_no_close_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Mask Not Closable
color: primary
variant: outlined
events:
onClick:
- id: drawer_mask_no_close_open
type: CallMethod
params:
blockId: drawer_mask_no_close
method: setOpen
args:
- open: true
- id: drawer_mask_default
type: Drawer
properties:
title: Default Mask
mask: true
maskClosable: true
blocks:
- id: drawer_mask_default_content
type: Paragraph
properties:
content: The mask is shown and clicking it closes the drawer. This is the
default behavior.
- id: drawer_no_mask
type: Drawer
properties:
title: No Mask
mask: false
blocks:
- id: drawer_no_mask_content
type: Paragraph
properties:
content: No mask overlay is shown behind the drawer. The page content remains
fully visible and interactive.
- id: drawer_mask_no_close
type: Drawer
properties:
title: Mask Not Closable
mask: true
maskClosable: false
blocks:
- id: drawer_mask_no_close_content
type: Paragraph
properties:
content: The mask is visible but clicking it does not close the drawer. Users
must use the close button or Escape key.
```
Drag the left edge to resize the drawer. The onResizeEnd event receives the new size, so it can be saved as a user preference.
```yaml
- id: drawer_resizable_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Resizable Drawer
color: primary
variant: outlined
events:
onClick:
- id: drawer_resizable_open
type: CallMethod
params:
blockId: drawer_resizable
method: setOpen
args:
- open: true
- id: drawer_resizable
type: Drawer
properties:
title: Resizable Drawer
size: 480
resizable: true
maxSize: 900
closable:
placement: end
mask:
blur: true
events:
onResizeEnd:
- id: drawer_resizable_save_size
type: SetState
params:
drawer_size:
_event: size
blocks:
- id: drawer_resizable_p1
type: Paragraph
properties:
content: Drag the left edge to resize the drawer. The onResizeEnd event receives
the new size, so it can be saved as a user preference.
```
Pressing the Escape key closes this drawer. This is the default behavior.
Pressing Escape does not close this drawer. The user must click the close button or mask to dismiss.
```yaml
- id: drawer_keyboard_on_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Keyboard Enabled (default)
color: primary
variant: outlined
events:
onClick:
- id: drawer_keyboard_on_open
type: CallMethod
params:
blockId: drawer_keyboard_on
method: setOpen
args:
- open: true
- id: drawer_keyboard_off_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Keyboard Disabled
color: danger
variant: outlined
events:
onClick:
- id: drawer_keyboard_off_open
type: CallMethod
params:
blockId: drawer_keyboard_off
method: setOpen
args:
- open: true
- id: drawer_keyboard_on
type: Drawer
properties:
title: Press Escape to Close
keyboard: true
blocks:
- id: drawer_keyboard_on_content
type: Paragraph
properties:
content: Pressing the Escape key closes this drawer. This is the default
behavior.
- id: drawer_keyboard_off
type: Drawer
properties:
title: Escape Disabled
keyboard: false
blocks:
- id: drawer_keyboard_off_content
type: Paragraph
properties:
content: Pressing Escape does not close this drawer. The user must click the
close button or mask to dismiss.
```
This drawer uses a custom z-index of 2000 to ensure it appears above other overlays. The default is 1000.
```yaml
- id: drawer_zindex_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Drawer (z-index 2000)
color: primary
variant: outlined
events:
onClick:
- id: drawer_zindex_open
type: CallMethod
params:
blockId: drawer_zindex
method: setOpen
args:
- open: true
- id: drawer_zindex
type: Drawer
properties:
title: High Z-Index Drawer
zIndex: 2000
blocks:
- id: drawer_zindex_content
type: Paragraph
properties:
content: This drawer uses a custom z-index of 2000 to ensure it appears above
other overlays. The default is 1000.
```
The extra slot renders content in the header area opposite the title. Commonly used for action buttons like Save or Cancel.
```yaml
- id: drawer_extra_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Drawer with Extra
color: primary
variant: solid
events:
onClick:
- id: drawer_extra_open
type: CallMethod
params:
blockId: drawer_extra
method: setOpen
args:
- open: true
- id: drawer_extra
type: Drawer
properties:
title: Drawer with Extra
slots:
extra:
blocks:
- id: drawer_extra_actions_row
type: Box
layout:
gap: 8
blocks:
- id: drawer_extra_cancel_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel
color: default
variant: outlined
size: small
events:
onClick:
- id: drawer_extra_cancel
type: CallMethod
params:
blockId: drawer_extra
method: setOpen
args:
- open: false
- id: drawer_extra_submit_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Submit
color: primary
variant: solid
size: small
blocks:
- id: drawer_extra_content
type: Paragraph
properties:
content: The extra slot renders content in the header area opposite the title.
Commonly used for action buttons like Save or Cancel.
```
The footer slot renders content in the drawer's footer area, pinned at the bottom. It is commonly used for action buttons like Save and Cancel.
```yaml
- id: drawer_footer_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Drawer with Footer
color: primary
variant: solid
events:
onClick:
- id: drawer_footer_open
type: CallMethod
params:
blockId: drawer_footer
method: setOpen
args:
- open: true
- id: drawer_footer
type: Drawer
properties:
title: Drawer with Footer
width: 400
slots:
footer:
blocks:
- id: drawer_footer_actions_row
type: Box
layout:
gap: 8
justify: end
blocks:
- id: drawer_footer_cancel_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel
color: default
variant: outlined
events:
onClick:
- id: drawer_footer_cancel
type: CallMethod
params:
blockId: drawer_footer
method: setOpen
args:
- open: false
- id: drawer_footer_save_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Save
color: primary
variant: solid
events:
onClick:
- id: drawer_footer_save_msg
type: DisplayMessage
params:
content: Saved successfully
status: success
duration: 2
blocks:
- id: drawer_footer_content
type: Paragraph
properties:
content: The footer slot renders content in the drawer's footer area, pinned at
the bottom. It is commonly used for action buttons like Save and
Cancel.
```
This drawer uses the toggleOpen method. Each click of the button alternates between open and closed states.
```yaml
- id: drawer_toggle_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Toggle Drawer
color: primary
variant: solid
icon: menu
events:
onClick:
- id: drawer_toggle_call
type: CallMethod
params:
blockId: drawer_toggle
method: toggleOpen
- id: drawer_toggle
type: Drawer
properties:
title: Toggle Drawer
blocks:
- id: drawer_toggle_content
type: Paragraph
properties:
content: This drawer uses the toggleOpen method. Each click of the button
alternates between open and closed states.
```
This drawer triggers DisplayMessage actions on onOpen, onClose, and afterClose events. Close the drawer to see all three messages fire in sequence.
Available events: onOpen fires when opening, onClose fires when the close action starts, onToggle fires on toggle, afterClose fires after the close animation completes, and afterOpenChange fires after any open state transition.
```yaml
- id: drawer_events_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Drawer with Events
color: primary
variant: solid
events:
onClick:
- id: drawer_events_open
type: CallMethod
params:
blockId: drawer_events
method: setOpen
args:
- open: true
- id: drawer_events
type: Drawer
properties:
title: Drawer with Events
width: 400
events:
onOpen:
- id: drawer_events_on_open_msg
type: DisplayMessage
params:
content: Drawer opened
duration: 2
onClose:
- id: drawer_events_on_close_msg
type: DisplayMessage
params:
content: Drawer closing...
duration: 2
afterClose:
- id: drawer_events_after_close_msg
type: DisplayMessage
params:
content: Drawer fully closed
duration: 2
blocks:
- id: drawer_events_p1
type: Paragraph
properties:
content: This drawer triggers DisplayMessage actions on onOpen, onClose, and
afterClose events. Close the drawer to see all three messages fire in
sequence.
- id: drawer_events_p2
type: Paragraph
properties:
content: "Available events: onOpen fires when opening, onClose fires when the
close action starts, onToggle fires on toggle, afterClose fires after
the close animation completes, and afterOpenChange fires after any
open state transition."
```
This drawer uses style.header and style.body to apply custom background colors to the header and body areas.
```yaml
- id: drawer_inline_style_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Styled Drawer
color: primary
variant: solid
events:
onClick:
- id: drawer_inline_style_open
type: CallMethod
params:
blockId: drawer_inline_style
method: setOpen
args:
- open: true
- id: drawer_inline_style
type: Drawer
properties:
title: Styled Drawer
style:
.header:
backgroundColor: var(--ant-color-primary-bg)
borderBottom: 1px solid var(--ant-color-primary-border)
.body:
backgroundColor: var(--ant-color-fill-quaternary)
blocks:
- id: drawer_inline_style_content
type: Paragraph
properties:
content: This drawer uses style.header and style.body to apply custom background
colors to the header and body areas.
```
Drawer supports these CSS keys: element, header, body, footer, mask, wrapper, content. Use class as an object to target each area with Tailwind classes.
A gradient header created using Tailwind classes on the header CSS key. The body uses a subtle gray background.
The mask CSS key applies a backdrop blur effect, and the content CSS key adds rounded corners to the drawer panel.
```yaml
- id: drawer_css_keys_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open CSS Styled Drawer
color: primary
variant: solid
events:
onClick:
- id: drawer_css_keys_open
type: CallMethod
params:
blockId: drawer_css_keys
method: setOpen
args:
- open: true
- id: drawer_css_keys
type: Drawer
properties:
title: Tailwind CSS Keys
class:
.header: bg-bg-layout
.body: bg-bg-layout
blocks:
- id: drawer_css_keys_content
type: Paragraph
properties:
content: "Drawer supports these CSS keys: element, header, body, footer, mask,
wrapper, content. Use class as an object to target each area with
Tailwind classes."
- id: drawer_css_accent_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Accent Drawer
color: primary
variant: outlined
events:
onClick:
- id: drawer_css_accent_open
type: CallMethod
params:
blockId: drawer_css_accent
method: setOpen
args:
- open: true
- id: drawer_css_accent
type: Drawer
properties:
title: Accent Header
class:
.header: bg-gradient-to-r from-primary/100 to-indigo-600 text-white
.body: bg-bg-layout
blocks:
- id: drawer_css_accent_content
type: Paragraph
properties:
content: A gradient header created using Tailwind classes on the header CSS key.
The body uses a subtle gray background.
- id: drawer_css_mask_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Blurred Mask Drawer
color: primary
variant: outlined
events:
onClick:
- id: drawer_css_mask_open
type: CallMethod
params:
blockId: drawer_css_mask
method: setOpen
args:
- open: true
- id: drawer_css_mask
type: Drawer
properties:
title: Custom Mask Style
class:
.mask: backdrop-blur-sm
.content: rounded-l-xl
blocks:
- id: drawer_css_mask_content
type: Paragraph
properties:
content: The mask CSS key applies a backdrop blur effect, and the content CSS
key adds rounded corners to the drawer panel.
```
Overrides colorBgElevated for a green-tinted background and colorBgMask for a subtle green mask overlay.
A dark-themed drawer using design token overrides for background, text, and icon colors.
Overrides footerPaddingBlock, footerPaddingInline, and zIndexPopup design tokens. These control footer spacing and the popup layer z-index.
```yaml
- id: drawer_theme_green_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Green Theme
color: primary
variant: solid
events:
onClick:
- id: drawer_theme_green_open
type: CallMethod
params:
blockId: drawer_theme_green
method: setOpen
args:
- open: true
- id: drawer_theme_green
type: Drawer
properties:
title: Custom Theme Drawer
theme:
colorBgMask: rgba(0, 100, 0, 0.15)
blocks:
- id: drawer_theme_green_content
type: Paragraph
properties:
content: Overrides colorBgElevated for a green-tinted background and colorBgMask
for a subtle green mask overlay.
- id: drawer_theme_dark_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Dark Theme
color: default
variant: solid
events:
onClick:
- id: drawer_theme_dark_open
type: CallMethod
params:
blockId: drawer_theme_dark
method: setOpen
args:
- open: true
- id: drawer_theme_dark
type: Drawer
properties:
title: Dark Theme Drawer
theme:
colorBgElevated: "#1f1f1f"
colorBgMask: rgba(0, 0, 0, 0.7)
colorText: "#ffffff"
colorTextHeading: "#ffffff"
colorIcon: "#ffffff"
colorIconHover: "#1677ff"
blocks:
- id: drawer_theme_dark_content
type: Paragraph
class: text-text-secondary
properties:
content: A dark-themed drawer using design token overrides for background, text,
and icon colors.
- id: drawer_theme_spacing_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom Spacing
color: primary
variant: outlined
events:
onClick:
- id: drawer_theme_spacing_open
type: CallMethod
params:
blockId: drawer_theme_spacing
method: setOpen
args:
- open: true
- id: drawer_theme_spacing
type: Drawer
properties:
title: Custom Footer Padding
theme:
footerPaddingBlock: 16
footerPaddingInline: 24
zIndexPopup: 1500
blocks:
- id: drawer_theme_spacing_content
type: Paragraph
properties:
content: Overrides footerPaddingBlock, footerPaddingInline, and zIndexPopup
design tokens. These control footer spacing and the popup layer
z-index.
```
```yaml
- id: drawer_edit_form_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Edit Record
color: primary
variant: solid
icon: edit
events:
onClick:
- id: drawer_edit_form_open
type: CallMethod
params:
blockId: drawer_edit_form
method: setOpen
args:
- open: true
- id: drawer_edit_form
type: Drawer
properties:
title: Edit Customer
width: 480
slots:
extra:
blocks:
- id: drawer_edit_form_extra_row
type: Box
layout:
gap: 8
blocks:
- id: drawer_edit_form_cancel_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel
color: default
variant: outlined
size: small
events:
onClick:
- id: drawer_edit_form_cancel
type: CallMethod
params:
blockId: drawer_edit_form
method: setOpen
args:
- open: false
- id: drawer_edit_form_save_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Save Changes
color: primary
variant: solid
size: small
events:
onClick:
- id: drawer_edit_form_save_msg
type: DisplayMessage
params:
content: Changes saved successfully
status: success
duration: 3
- id: drawer_edit_form_close
type: CallMethod
params:
blockId: drawer_edit_form
method: setOpen
args:
- open: false
blocks:
- id: drawer_edit_form_name
type: TextInput
properties:
title: Full Name
placeholder: Enter customer name
- id: drawer_edit_form_email
type: TextInput
properties:
title: Email Address
placeholder: customer@example.com
- id: drawer_edit_form_phone
type: TextInput
properties:
title: Phone Number
placeholder: +1 (555) 000-0000
- id: drawer_edit_form_status
type: Selector
properties:
title: Status
options:
- label: Active
value: active
- label: Inactive
value: inactive
- label: Pending
value: pending
- id: drawer_edit_form_notes
type: TextArea
properties:
title: Notes
placeholder: Additional notes about this customer...
autoSize:
minRows: 3
```
```yaml
- id: drawer_filter_panel_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Filters
color: default
variant: outlined
icon: filter
events:
onClick:
- id: drawer_filter_panel_open
type: CallMethod
params:
blockId: drawer_filter_panel
method: setOpen
args:
- open: true
- id: drawer_filter_panel
type: Drawer
properties:
title: Filter Results
placement: left
width: 320
events:
onClose:
- id: drawer_filter_panel_close_msg
type: DisplayMessage
params:
content: Filters applied
status: info
duration: 2
slots:
extra:
blocks:
- id: drawer_filter_panel_clear_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Clear All
color: danger
variant: link
size: small
events:
onClick:
- id: drawer_filter_panel_clear_msg
type: DisplayMessage
params:
content: All filters cleared
status: warning
duration: 2
blocks:
- id: drawer_filter_panel_category
type: MultipleSelector
properties:
title: Category
options:
- label: Electronics
value: electronics
- label: Clothing
value: clothing
- label: Books
value: books
- label: Home & Garden
value: home
- id: drawer_filter_panel_price
type: Slider
properties:
title: Price Range
min: 0
max: 500
step: 10
- id: drawer_filter_panel_rating
type: ButtonSelector
properties:
title: Minimum Rating
options:
- label: Any
value: 0
- label: 3+
value: 3
- label: 4+
value: 4
- label: "5"
value: 5
- id: drawer_filter_panel_in_stock
type: Switch
properties:
title: In Stock Only
- id: drawer_filter_panel_apply_btn
type: Button
properties:
title: Apply Filters
color: primary
variant: solid
block: true
events:
onClick:
- id: drawer_filter_panel_apply_msg
type: DisplayMessage
params:
content: Filters applied to results
status: success
duration: 2
- id: drawer_filter_panel_apply_close
type: CallMethod
params:
blockId: drawer_filter_panel
method: setOpen
args:
- open: false
```
Jane Cooper
```yaml
- id: drawer_profile_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: View Profile
color: primary
variant: solid
icon: user
events:
onClick:
- id: drawer_profile_open
type: CallMethod
params:
blockId: drawer_profile
method: setOpen
args:
- open: true
- id: drawer_profile
type: Drawer
properties:
title: User Profile
width: 400
blocks:
- id: drawer_profile_avatar_row
type: Box
layout:
gap: 16
align: center
blocks:
- id: drawer_profile_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 64
color: "#1677ff"
- id: drawer_profile_info
type: Box
layout:
flex: 1 1 0
direction: column
gap: 4
blocks:
- id: drawer_profile_name
type: Title
properties:
content: Jane Cooper
level: 4
- id: drawer_profile_role_tag
type: Tag
properties:
title: Senior Product Designer
color: blue
- id: drawer_profile_divider
type: Divider
- id: drawer_profile_details
type: Descriptions
properties:
size: small
column: 1
items:
- label: Email
value: jane.cooper@example.com
- label: Phone
value: +1 (555) 123-4567
- label: Location
value: San Francisco, CA
- label: Department
value: Design
- label: Start Date
value: January 15, 2023
- id: drawer_profile_divider2
type: Divider
- id: drawer_profile_actions_row
type: Box
layout:
gap: 8
blocks:
- id: drawer_profile_edit_btn
type: Button
layout:
flex: 1 1 0
properties:
title: Edit Profile
color: primary
variant: outlined
icon: edit
- id: drawer_profile_message_btn
type: Button
layout:
flex: 1 1 0
properties:
title: Send Message
color: primary
variant: solid
icon: mail
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `closable` | boolean \| object | `true` | Whether a close (x) button is visible in the Drawer header or not. Set an object to disable the button or to move it to the end of the header. |
| `closable.disabled` | boolean | `false` | Show the close button, but disabled. |
| `closable.placement` | string | `"start"` | Place the close button at the start or the end of the header. Enum: `start`, `end`. |
| `destroyOnHidden` | boolean | `false` | Unmount the blocks inside the Drawer when it closes, so they mount again (and their onMount events run) each time it opens. Their state is kept. |
| `focusable` | object | - | Focus management of the dialog. |
| `focusable.trap` | boolean | `true` | Keep keyboard focus inside the dialog while it is open. |
| `focusable.focusTriggerAfterClose` | boolean | `true` | Return focus to the element that opened the dialog after it closes. |
| `forceRender` | boolean | `false` | Render the blocks inside the Drawer before it is first opened, so their methods can be called and their onMount events run while it is still closed. |
| `getContainer` | string \| boolean | - | Where the Drawer is mounted. By default it is mounted on the page body. Set to `false` to render it in place, inside the nearest positioned parent (give that parent `position: relative`), or to a CSS selector to mount it in the first matching element. |
| `loading` | boolean | `false` | Show a loading skeleton in place of the Drawer body. |
| `mask` | boolean \| object | `true` | Whether to show the mask. Set an object to configure the mask with `enabled`, `blur` and `closable`. |
| `mask.enabled` | boolean | `true` | Whether to show the mask. |
| `mask.blur` | boolean | `false` | Blur the page behind the mask. |
| `mask.closable` | boolean | - | Whether clicking the mask closes the dialog. Takes precedence over `maskClosable`. |
| `maskClosable` | boolean | `true` | Clicking on the mask (area outside the Drawer) to close the Drawer or not. `mask.closable` takes precedence. |
| `maxSize` | number | - | Maximum size in pixels a resizable Drawer can be dragged to. |
| `padding` | string | `"default"` | Space inside the drawer. `compact` tightens the header and body. `none` removes the body padding so content such as a table or list runs edge to edge; the header and footer keep their padding. Enum: `default`, `compact`, `none`. |
| `resizable` | boolean | `false` | Let the user resize the Drawer by dragging its edge. The configured size is the starting size. |
| `size` | string \| number | - | Size of the Drawer: width for left and right placements, height for top and bottom. `default` (378px), `large` (736px), a number of pixels or a CSS length. Takes precedence over width and height. |
| `title` | string | - | The title of the Drawer - supports html. |
| `width` | string \| number | `378` | Width of the Drawer dialog. |
| `height` | string \| number | `378` | When placement is top or bottom, height of the Drawer dialog. |
| `zIndex` | integer | `1000` | The z-index of the Drawer. |
| `placement` | string | `"right"` | The placement of the Drawer. Enum: `top`, `right`, `bottom`, `left`. |
| `keyboard` | boolean | `true` | Whether pressing Esc closes the Drawer. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design drawer tokens](https://ant.design/components/drawer#design-token). |
| `theme.footerPaddingBlock` | number | `8` | Vertical padding of the footer. |
| `theme.footerPaddingInline` | number | `16` | Horizontal padding of the footer. |
| `theme.zIndexPopup` | number | `1000` | Z-index of the drawer. |
| `theme.draggerSize` | number | `4` | Size of the resize handle. |
| `theme.colorBgElevated` | string | - | Background color of the drawer. |
| `theme.colorBgMask` | string | `"rgba(0, 0, 0, 0.45)"` | Background color of the drawer mask. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onToggle` | \- | Trigger actions when drawer is toggled. |
| `onClose` | \- | Trigger actions when drawer is closed. |
| `onOpen` | \- | Trigger actions when drawer is opened. |
| `afterClose` | \- | Trigger actions after drawer is closed. |
| `afterOpenChange` | `{ open, drawerOpen }` | Trigger actions after the open or close animation of the drawer has finished. |
| `onResizeEnd` | `{ size }` | Trigger actions when the user finishes resizing a resizable drawer. Not triggered when the resize handle is clicked without dragging. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Drawer element. |
| `/header` | The Drawer header. |
| `/title` | The Drawer title. |
| `/body` | The Drawer body. |
| `/footer` | The Drawer footer. |
| `/mask` | The Drawer mask. |
| `/wrapper` | The Drawer wrapper. |
| `/content` | The Drawer content. |
| Slot | Description |
| --- | --- |
| `content` | Main Drawer body. |
| `extra` | Extra content in the header. |
| `footer` | The Drawer footer. |
---
url: https://docs.lowdefy.com/md/container-blocks/dropdownmenu.md
---
# DropdownMenu
Floating dropdown menu triggered by any child block. Menu items follow the Menu block links pattern — MenuLink for navigation, MenuGroup for grouping, MenuDivider for separators. Use trigger modes click, hover, or contextMenu.
```yaml
- id: dropdown_menu_basic
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
links:
- id: dm_basic_home
type: MenuLink
pageId: home
properties:
title: Home
icon: home
- id: dm_basic_profile
type: MenuLink
pageId: home
properties:
title: Profile
icon: user
- id: dm_basic_div
type: MenuDivider
- id: dm_basic_logout
type: MenuLink
properties:
title: Log Out
icon: logout
danger: true
blocks:
- id: dropdown_menu_basic_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Account
color: primary
variant: solid
```
```yaml
- id: dropdown_menu_hover
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
links:
- id: dm_hover_item1
type: MenuLink
properties:
title: Option A
- id: dm_hover_item2
type: MenuLink
properties:
title: Option B
- id: dm_hover_item3
type: MenuLink
properties:
title: Option C
blocks:
- id: dropdown_menu_hover_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Hover me
color: default
variant: outlined
```
Right-click anywhere in this card to open the context menu.
```yaml
- id: dropdown_menu_context
type: DropdownMenu
properties:
trigger: contextMenu
links:
- id: dm_ctx_copy
type: MenuLink
properties:
title: Copy
icon: copy
- id: dm_ctx_paste
type: MenuLink
properties:
title: Paste
icon: Files
- id: dm_ctx_div
type: MenuDivider
- id: dm_ctx_delete
type: MenuLink
properties:
title: Delete
icon: delete
danger: true
blocks:
- id: dropdown_menu_context_area
type: Card
properties:
size: small
bordered: true
blocks:
- id: dropdown_menu_context_text
type: Paragraph
properties:
content: Right-click anywhere in this card to open the context menu.
```
```yaml
- id: dropdown_menu_pl_bl
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
placement: bottomLeft
links:
- id: dm_pl_bl_1
type: MenuLink
properties:
title: Item 1
- id: dm_pl_bl_2
type: MenuLink
properties:
title: Item 2
blocks:
- id: dropdown_menu_pl_bl_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: bottomLeft
color: primary
variant: solid
size: small
- id: dropdown_menu_pl_br
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
placement: bottomRight
links:
- id: dm_pl_br_1
type: MenuLink
properties:
title: Item 1
- id: dm_pl_br_2
type: MenuLink
properties:
title: Item 2
blocks:
- id: dropdown_menu_pl_br_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: bottomRight
color: primary
variant: outlined
size: small
- id: dropdown_menu_pl_tl
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
placement: topLeft
links:
- id: dm_pl_tl_1
type: MenuLink
properties:
title: Item 1
- id: dm_pl_tl_2
type: MenuLink
properties:
title: Item 2
blocks:
- id: dropdown_menu_pl_tl_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: topLeft
color: default
variant: outlined
size: small
- id: dropdown_menu_pl_right
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
placement: right
links:
- id: dm_pl_right_1
type: MenuLink
properties:
title: Item 1
- id: dm_pl_right_2
type: MenuLink
properties:
title: Item 2
blocks:
- id: dropdown_menu_pl_right_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: right
color: default
variant: outlined
size: small
```
```yaml
- id: dropdown_menu_selectable
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
selectable: true
selectedKeys:
_if_none:
- _state: dm_sort_keys
- - dm_sort_newest
links:
- id: dm_sort_newest
type: MenuLink
properties:
title: Newest first
- id: dm_sort_oldest
type: MenuLink
properties:
title: Oldest first
- id: dm_sort_name
type: MenuLink
properties:
title: Name
events:
onSelect:
- id: dm_sort_set
type: SetState
params:
dm_sort_keys:
_event: selectedKeys
blocks:
- id: dropdown_menu_selectable_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Sort
icon: sort
color: default
variant: outlined
```
```yaml
- id: dropdown_menu_arrow
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
arrow: true
links:
- id: dm_arrow_1
type: MenuLink
properties:
title: Settings
icon: settings
- id: dm_arrow_2
type: MenuLink
properties:
title: Help
icon: help
blocks:
- id: dropdown_menu_arrow_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: With Arrow
color: primary
variant: solid
- id: dropdown_menu_arrow_center
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
arrow:
pointAtCenter: true
links:
- id: dm_arrowc_1
type: MenuLink
properties:
title: Settings
icon: settings
- id: dm_arrowc_2
type: MenuLink
properties:
title: Help
icon: help
blocks:
- id: dropdown_menu_arrow_center_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Arrow at Center
color: primary
variant: outlined
```
```yaml
- id: dropdown_menu_groups
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
links:
- id: dm_grp_nav
type: MenuGroup
properties:
title: Navigation
icon: grid
links:
- id: dm_grp_nav_home
type: MenuLink
pageId: home
properties:
title: Home
- id: dm_grp_nav_dash
type: MenuLink
pageId: home
properties:
title: Dashboard
- id: dm_grp_div
type: MenuDivider
- id: dm_grp_account
type: MenuGroup
properties:
title: Account
icon: user
links:
- id: dm_grp_acc_profile
type: MenuLink
pageId: home
properties:
title: Profile
- id: dm_grp_acc_settings
type: MenuLink
pageId: home
properties:
title: Settings
blocks:
- id: dropdown_menu_groups_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Grouped Menu
color: primary
variant: solid
```
```yaml
- id: dropdown_menu_disabled
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
links:
- id: dm_dis_active
type: MenuLink
properties:
title: Available Action
icon: check
- id: dm_dis_disabled
type: MenuLink
properties:
title: Unavailable (disabled)
disabled: true
- id: dm_dis_div
type: MenuDivider
- id: dm_dis_danger
type: MenuLink
properties:
title: Danger Action
danger: true
blocks:
- id: dropdown_menu_disabled_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Mixed States
color: default
variant: outlined
```
```yaml
- id: dropdown_menu_shortcuts
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
links:
- id: dm_sc_new
type: MenuLink
properties:
title: New File
icon: FilePlus
shortcut: mod+shift+N
- id: dm_sc_save
type: MenuLink
properties:
title: Save
icon: save
shortcut: mod+shift+S
- id: dm_sc_div
type: MenuDivider
- id: dm_sc_close
type: MenuLink
properties:
title: Close
icon: close
shortcut: mod+shift+W
events:
onClick:
- id: dropdown_menu_shortcuts_msg
type: DisplayMessage
params:
content:
_string.concat:
- "Shortcut action: "
- _event: key
duration: 2
blocks:
- id: dropdown_menu_shortcuts_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: File Menu
color: primary
variant: solid
```
```yaml
- id: dropdown_menu_event
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
links:
- id: dm_ev_1
type: MenuLink
properties:
title: Option A
- id: dm_ev_2
type: MenuLink
properties:
title: Option B
events:
onOpenChange:
- id: dropdown_menu_event_msg
type: DisplayMessage
params:
content: Dropdown toggled!
duration: 2
blocks:
- id: dropdown_menu_event_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Click to Toggle
color: primary
variant: solid
icon: bell
```
```yaml
- id: dropdown_menu_onclick
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
links:
- id: dm_oc_edit
type: MenuLink
properties:
title: Edit
icon: edit
- id: dm_oc_copy
type: MenuLink
properties:
title: Copy
icon: copy
- id: dm_oc_delete
type: MenuLink
properties:
title: Delete
icon: delete
danger: true
events:
onClick:
- id: dropdown_menu_onclick_msg
type: DisplayMessage
params:
content:
_string.concat:
- "Clicked: "
- _event: key
duration: 2
blocks:
- id: dropdown_menu_onclick_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Actions
color: default
variant: outlined
```
```yaml
- id: dropdown_menu_theme
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
theme:
controlItemBgHover: "#f0f5ff"
borderRadiusLG: 12
links:
- id: dm_th_1
type: MenuLink
properties:
title: Styled Item A
- id: dm_th_2
type: MenuLink
properties:
title: Styled Item B
- id: dm_th_3
type: MenuLink
properties:
title: Styled Item C
blocks:
- id: dropdown_menu_theme_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom Theme
color: primary
variant: solid
```
JD
Jane Doe
```yaml
- id: dropdown_menu_user
type: DropdownMenu
layout:
flex: 0 0 auto
properties:
trigger: click
placement: bottomRight
links:
- id: dm_user_profile
type: MenuLink
pageId: home
properties:
title: My Profile
icon: user
- id: dm_user_settings
type: MenuLink
pageId: home
properties:
title: Settings
icon: settings
- id: dm_user_div
type: MenuDivider
- id: dm_user_logout
type: MenuLink
properties:
title: Log Out
icon: logout
danger: true
blocks:
- id: dropdown_menu_user_trigger
type: Box
layout:
gap: 8
align: center
blocks:
- id: dropdown_menu_user_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
content: JD
color: "#1677ff"
- id: dropdown_menu_user_name
type: Paragraph
layout:
flex: 0 0 auto
properties:
content: Jane Doe
```
```yaml
- id: dropdown_menu_op
type: DropdownMenu
properties:
trigger: click
links:
_menu: default
blocks:
- id: dropdown_menu_op_trigger
type: Button
properties:
title: Open Menu
icon: menu
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `links` | array | - | Menu items. Same structure as Menu block: MenuLink, MenuGroup, MenuDivider. |
| `links.$.id` | string | - | Menu item id. |
| `links.$.type` | string | `"MenuLink"` | Menu item type. Enum: `MenuDivider`, `MenuLink`, `MenuGroup`. |
| `links.$.pageId` | string | - | Page to link to. |
| `links.$.url` | string | - | External URL to link to. |
| `links.$.newTab` | boolean | - | Open link in new tab. |
| `links.$.style` | object \| string \| array | - | CSS styles for the menu item. Use a flat object for the item wrapper, or dot-prefixed slot keys (`.element`, `.icon`, `.label`). |
| `links.$.class` | string \| array \| object | - | CSS classes for the menu item. Flat applies to the item wrapper; use dot-prefixed slot keys to target parts. |
| `links.$.properties` | object | - | Properties for the menu item. |
| `links.$.properties.title` | string | - | Menu item title. |
| `links.$.properties.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize icon on menu item. |
| `links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `links.$.properties.icon.color` | string | - | Icon color. |
| `links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `links.$.properties.danger` | boolean | `false` | Apply danger style to menu item. |
| `links.$.properties.disabled` | boolean | `false` | Disable the menu item. |
| `links.$.properties.tooltip` | string | - | Tooltip text shown when the menu is collapsed. |
| `links.$.properties.extra` | string | - | Free-form right-aligned label on a MenuLink. For real keybindings use `shortcut`; when both are set, `shortcut` sits to the right of `extra`. |
| `links.$.properties.dashed` | boolean | `false` | Whether the divider line is dashed. |
| `links.$.properties.shortcut` | string | - | Keyboard shortcut for this menu item. Renders a kbd badge floated to the far right of the item AND wires the key handler. Use "mod" for Cmd/Ctrl. |
| `links.$.links` | array | - | Nested menu items for MenuGroup. |
| `links.$.links.$.id` | string | - | Menu item id. |
| `links.$.links.$.type` | string | `"MenuLink"` | Menu item type. Enum: `MenuDivider`, `MenuLink`. |
| `links.$.links.$.pageId` | string | - | Page to link to. |
| `links.$.links.$.url` | string | - | External URL to link to. |
| `links.$.links.$.newTab` | boolean | - | Open link in new tab. |
| `links.$.links.$.style` | object \| string \| array | - | CSS styles for the menu item. Flat or dot-prefixed slot keys (`.element`, `.icon`, `.label`). |
| `links.$.links.$.class` | string \| array \| object | - | CSS classes for the menu item. |
| `links.$.links.$.properties` | object | - | Properties for the menu item. |
| `links.$.links.$.properties.title` | string | - | Menu item title. |
| `links.$.links.$.properties.icon` | string \| object | - | Icon name or config. |
| `links.$.links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `links.$.links.$.properties.icon.color` | string | - | Icon color. |
| `links.$.links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `links.$.links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `links.$.links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `links.$.links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `links.$.links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `links.$.links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `links.$.links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `links.$.links.$.properties.danger` | boolean | `false` | Danger style. |
| `links.$.links.$.properties.disabled` | boolean | `false` | Disable the item. |
| `links.$.links.$.properties.tooltip` | string | - | Tooltip text shown when the menu is collapsed. |
| `links.$.links.$.properties.extra` | string | - | Free-form right-aligned label on a MenuLink. For real keybindings use `shortcut`. |
| `links.$.links.$.properties.dashed` | boolean | `false` | Dashed divider line. |
| `links.$.links.$.properties.shortcut` | string | - | Keyboard shortcut. Renders a kbd badge floated to the far right and wires the key handler. Use "mod" for Cmd/Ctrl. |
| `trigger` | string | `"hover"` | How the dropdown opens. Enum: `click`, `hover`, `contextMenu`. |
| `placement` | string | `"bottomLeft"` | Position relative to trigger. Enum: `bottomLeft`, `bottom`, `bottomRight`, `topLeft`, `top`, `topRight`, `left`, `leftTop`, `leftBottom`, `right`, `rightTop`, `rightBottom`. |
| `arrow` | boolean \| object | `false` | Show arrow pointing to trigger. |
| `arrow.pointAtCenter` | boolean | - | |
| `disabled` | boolean | `false` | Disable the dropdown. |
| `destroyOnClose` | boolean | `false` | Unmount menu DOM when closed. |
| `selectable` | boolean | `false` | Allow menu items to be selected. Selecting an item highlights it and fires onSelect. |
| `selectedKeys` | array | - | Highlighted menu items. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design dropdown tokens](https://ant.design/components/dropdown#design-token). |
| `theme.zIndexPopup` | number | `1050` | Z-index of the dropdown popup. |
| `theme.controlItemBgHover` | string | - | Background color on item hover. |
| `theme.colorPrimary` | string | - | Primary color override. |
| `theme.borderRadiusLG` | number | - | Border radius for the dropdown. |
| `theme.paddingBlock` | number | - | Vertical padding for menu items. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onClick` | `{ key, keyPath, pageId, url }` | Trigger action when a menu item is clicked. |
| `onSelect` | `{ key, selectedKeys, pageId, url }` | Trigger action when a menu item is selected. Requires `selectable: true`. |
| `onOpenChange` | `{ open }` | Trigger action when dropdown opens or closes. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The trigger wrapper element. |
| `/menu` | The floating menu container. |
| `/item` | Individual menu items. |
| `/itemIcon` | Icon within menu items. |
| `/subMenu` | Has no effect: antd does not expose submenu containers as a separately styled part. The item key also applies to submenu items. |
| `/arrow` | Has no effect: antd does not expose the dropdown arrow as a separately styled part. |
| Slot | Description |
| --- | --- |
| `content` | Blocks that trigger the dropdown. |
---
url: https://docs.lowdefy.com/md/container-blocks/flex.md
---
# Flex
Flexible box layout container for arranging child blocks.
```yaml
- id: flex_basic
type: Flex
properties:
gap: 8
blocks:
- id: flex_basic_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: One
color: primary
variant: solid
- id: flex_basic_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: Two
color: primary
variant: outlined
- id: flex_basic_btn3
type: Button
layout:
flex: 0 0 auto
properties:
title: Three
color: primary
variant: dashed
```
Stacked vertically.
Below the first card.
Below the second card.
```yaml
- id: flex_vertical
type: Flex
properties:
orientation: vertical
gap: 12
blocks:
- id: flex_vert_card1
type: Card
properties:
title: First
size: small
blocks:
- id: flex_vert_card1_p
type: Paragraph
properties:
content: Stacked vertically.
- id: flex_vert_card2
type: Card
properties:
title: Second
size: small
blocks:
- id: flex_vert_card2_p
type: Paragraph
properties:
content: Below the first card.
- id: flex_vert_card3
type: Card
properties:
title: Third
size: small
blocks:
- id: flex_vert_card3_p
type: Paragraph
properties:
content: Below the second card.
```
**gap: small (8px)**
**gap: medium (16px)**
**gap: large (24px)**
**gap: 40 (custom number)**
```yaml
- id: flex_gap_small_label
type: Markdown
properties:
content: "**gap: small (8px)**"
- id: flex_gap_small
type: Flex
properties:
gap: small
blocks:
- id: flex_gs_1
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag A
color: blue
- id: flex_gs_2
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag B
color: blue
- id: flex_gs_3
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag C
color: blue
- id: flex_gap_middle_label
type: Markdown
properties:
content: "**gap: medium (16px)**"
- id: flex_gap_middle
type: Flex
properties:
gap: medium
blocks:
- id: flex_gm_1
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag A
color: green
- id: flex_gm_2
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag B
color: green
- id: flex_gm_3
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag C
color: green
- id: flex_gap_large_label
type: Markdown
properties:
content: "**gap: large (24px)**"
- id: flex_gap_large
type: Flex
properties:
gap: large
blocks:
- id: flex_gl_1
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag A
color: orange
- id: flex_gl_2
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag B
color: orange
- id: flex_gl_3
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag C
color: orange
- id: flex_gap_custom_label
type: Markdown
properties:
content: "**gap: 40 (custom number)**"
- id: flex_gap_custom
type: Flex
properties:
gap: 40
blocks:
- id: flex_gc_1
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag A
color: purple
- id: flex_gc_2
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag B
color: purple
- id: flex_gc_3
type: Tag
layout:
flex: 0 0 auto
properties:
title: Tag C
color: purple
```
**justify: flex-start**
**justify: center**
**justify: flex-end**
**justify: space-between**
**justify: space-around**
**justify: space-evenly**
```yaml
- id: flex_j_start_label
type: Markdown
properties:
content: "**justify: flex-start**"
- id: flex_j_start
type: Flex
class: bg-bg-layout p-2 rounded
properties:
justify: flex-start
gap: 8
blocks:
- id: flex_js_1
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: primary
variant: solid
size: small
- id: flex_js_2
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: primary
variant: solid
size: small
- id: flex_js_3
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: primary
variant: solid
size: small
- id: flex_j_center_label
type: Markdown
properties:
content: "**justify: center**"
- id: flex_j_center
type: Flex
class: bg-bg-layout p-2 rounded
properties:
justify: center
gap: 8
blocks:
- id: flex_jc_1
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: blue
variant: solid
size: small
- id: flex_jc_2
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: blue
variant: solid
size: small
- id: flex_jc_3
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: blue
variant: solid
size: small
- id: flex_j_end_label
type: Markdown
properties:
content: "**justify: flex-end**"
- id: flex_j_end
type: Flex
class: bg-bg-layout p-2 rounded
properties:
justify: flex-end
gap: 8
blocks:
- id: flex_je_1
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: green
variant: solid
size: small
- id: flex_je_2
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: green
variant: solid
size: small
- id: flex_je_3
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: green
variant: solid
size: small
- id: flex_j_between_label
type: Markdown
properties:
content: "**justify: space-between**"
- id: flex_j_between
type: Flex
class: bg-bg-layout p-2 rounded
properties:
justify: space-between
blocks:
- id: flex_jb_1
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: orange
variant: solid
size: small
- id: flex_jb_2
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: orange
variant: solid
size: small
- id: flex_jb_3
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: orange
variant: solid
size: small
- id: flex_j_around_label
type: Markdown
properties:
content: "**justify: space-around**"
- id: flex_j_around
type: Flex
class: bg-bg-layout p-2 rounded
properties:
justify: space-around
blocks:
- id: flex_ja_1
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: purple
variant: solid
size: small
- id: flex_ja_2
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: purple
variant: solid
size: small
- id: flex_ja_3
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: purple
variant: solid
size: small
- id: flex_j_evenly_label
type: Markdown
properties:
content: "**justify: space-evenly**"
- id: flex_j_evenly
type: Flex
class: bg-bg-layout p-2 rounded
properties:
justify: space-evenly
blocks:
- id: flex_jev_1
type: Button
layout:
flex: 0 0 auto
properties:
title: A
color: red
variant: solid
size: small
- id: flex_jev_2
type: Button
layout:
flex: 0 0 auto
properties:
title: B
color: red
variant: solid
size: small
- id: flex_jev_3
type: Button
layout:
flex: 0 0 auto
properties:
title: C
color: red
variant: solid
size: small
```
**align: flex-start**
**align: center**
**align: flex-end**
**align: stretch**
Stretches to fill.
Same height as tallest sibling.
**align: baseline**
Large Title
Body text aligned to the same baseline.
Small
```yaml
- id: flex_a_start_label
type: Markdown
properties:
content: "**align: flex-start**"
- id: flex_a_start
type: Flex
class: bg-bg-layout p-2 rounded
style:
.element:
minHeight: 80px
properties:
align: flex-start
gap: 8
blocks:
- id: flex_as_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Short
color: primary
variant: solid
- id: flex_as_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Tall
color: primary
variant: solid
size: large
- id: flex_as_3
type: Button
layout:
flex: 0 0 auto
properties:
title: Short
color: primary
variant: solid
size: small
- id: flex_a_center_label
type: Markdown
properties:
content: "**align: center**"
- id: flex_a_center
type: Flex
class: bg-bg-layout p-2 rounded
style:
.element:
minHeight: 80px
properties:
align: center
gap: 8
blocks:
- id: flex_ac_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Short
color: blue
variant: solid
- id: flex_ac_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Tall
color: blue
variant: solid
size: large
- id: flex_ac_3
type: Button
layout:
flex: 0 0 auto
properties:
title: Short
color: blue
variant: solid
size: small
- id: flex_a_end_label
type: Markdown
properties:
content: "**align: flex-end**"
- id: flex_a_end
type: Flex
class: bg-bg-layout p-2 rounded
style:
.element:
minHeight: 80px
properties:
align: flex-end
gap: 8
blocks:
- id: flex_ae_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Short
color: green
variant: solid
- id: flex_ae_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Tall
color: green
variant: solid
size: large
- id: flex_ae_3
type: Button
layout:
flex: 0 0 auto
properties:
title: Short
color: green
variant: solid
size: small
- id: flex_a_stretch_label
type: Markdown
properties:
content: "**align: stretch**"
- id: flex_a_stretch
type: Flex
class: bg-bg-layout p-2 rounded
style:
.element:
minHeight: 80px
properties:
align: stretch
gap: 8
blocks:
- id: flex_ax_1
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: flex_ax_1_p
type: Paragraph
properties:
content: Stretches to fill.
- id: flex_ax_2
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: flex_ax_2_p
type: Paragraph
properties:
content: Same height as tallest sibling.
- id: flex_a_baseline_label
type: Markdown
properties:
content: "**align: baseline**"
- id: flex_a_baseline
type: Flex
class: bg-bg-layout p-2 rounded
properties:
align: baseline
gap: 16
blocks:
- id: flex_ab_1
type: Title
layout:
flex: 0 0 auto
properties:
content: Large Title
level: 2
- id: flex_ab_2
type: Paragraph
layout:
flex: 0 0 auto
properties:
content: Body text aligned to the same baseline.
- id: flex_ab_3
type: Title
layout:
flex: 0 0 auto
properties:
content: Small
level: 5
```
**wrap: true** - items wrap to next line when space runs out
```yaml
- id: flex_wrap_label
type: Markdown
properties:
content: "**wrap: true** - items wrap to next line when space runs out"
- id: flex_wrap
type: Flex
class: bg-bg-layout p-2 rounded
properties:
wrap: true
gap: 8
blocks:
- id: flex_w_1
type: Button
layout:
flex: 0 0 auto
properties:
title: Alpha
color: primary
variant: solid
- id: flex_w_2
type: Button
layout:
flex: 0 0 auto
properties:
title: Bravo
color: blue
variant: solid
- id: flex_w_3
type: Button
layout:
flex: 0 0 auto
properties:
title: Charlie
color: green
variant: solid
- id: flex_w_4
type: Button
layout:
flex: 0 0 auto
properties:
title: Delta
color: orange
variant: solid
- id: flex_w_5
type: Button
layout:
flex: 0 0 auto
properties:
title: Echo
color: purple
variant: solid
- id: flex_w_6
type: Button
layout:
flex: 0 0 auto
properties:
title: Foxtrot
color: red
variant: solid
- id: flex_w_7
type: Button
layout:
flex: 0 0 auto
properties:
title: Golf
color: cyan
variant: solid
- id: flex_w_8
type: Button
layout:
flex: 0 0 auto
properties:
title: Hotel
color: magenta
variant: solid
- id: flex_w_9
type: Button
layout:
flex: 0 0 auto
properties:
title: India
color: gold
variant: solid
- id: flex_w_10
type: Button
layout:
flex: 0 0 auto
properties:
title: Juliet
color: lime
variant: solid
```
**flex** property on the Flex container itself sets the CSS flex shorthand
flex 1 (grows)
flex none (fixed)
flex 2 (grows 2x)
```yaml
- id: flex_prop_label
type: Markdown
properties:
content: "**flex** property on the Flex container itself sets the CSS flex
shorthand"
- id: flex_prop_outer
type: Flex
properties:
gap: 16
blocks:
- id: flex_prop_grow
type: Flex
layout:
flex: 1 1 0
class: bg-bg-layout p-4 rounded
properties:
flex: 1
justify: center
align: center
blocks:
- id: flex_prop_grow_txt
type: Paragraph
properties:
content: flex 1 (grows)
- id: flex_prop_fixed
type: Flex
layout:
flex: 0 0 auto
class: bg-bg-layout p-4 rounded
properties:
flex: none
justify: center
align: center
blocks:
- id: flex_prop_fixed_txt
type: Paragraph
properties:
content: flex none (fixed)
- id: flex_prop_grow2
type: Flex
layout:
flex: 2 1 0
class: bg-bg-layout p-4 rounded
properties:
flex: 2
justify: center
align: center
blocks:
- id: flex_prop_grow2_txt
type: Paragraph
properties:
content: flex 2 (grows 2x)
```
```yaml
- id: flex_component_nav
type: Flex
properties:
component: nav
gap: 16
justify: center
blocks:
- id: flex_component_nav_link1
type: Button
layout:
flex: 0 0 auto
properties:
title: Home
color: primary
variant: link
- id: flex_component_nav_link2
type: Button
layout:
flex: 0 0 auto
properties:
title: About
color: primary
variant: link
- id: flex_component_nav_link3
type: Button
layout:
flex: 0 0 auto
properties:
title: Contact
color: primary
variant: link
```
```yaml
- id: flex_theme_medium
type: Flex
properties:
gap: medium
theme:
padding: 32
blocks:
- id: flex_theme_medium_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: Wider medium gap
color: primary
variant: solid
- id: flex_theme_medium_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: padding token 32
color: primary
variant: outlined
- id: flex_theme_small
type: Flex
properties:
gap: small
theme:
paddingXS: 2
blocks:
- id: flex_theme_small_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: Tighter small gap
color: green
variant: solid
- id: flex_theme_small_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: paddingXS token 2
color: green
variant: outlined
```
Dark Panel
```yaml
- id: flex_style_inline
type: Flex
style:
.element:
padding: 16px
borderRadius: 8px
border: "1px dashed #91caff"
properties:
gap: 12
justify: center
blocks:
- id: flex_style_inline_btn1
type: Button
layout:
flex: 0 0 auto
properties:
title: Styled Container
color: primary
variant: solid
- id: flex_style_inline_btn2
type: Button
layout:
flex: 0 0 auto
properties:
title: With Dashed Border
color: primary
variant: outlined
- id: flex_style_dark
type: Flex
style:
.element:
backgroundColor: "#1f1f1f"
padding: 20px
borderRadius: 12px
properties:
gap: 12
justify: space-between
align: center
blocks:
- id: flex_style_dark_title
type: Title
layout:
flex: 0 0 auto
class: text-white
properties:
content: Dark Panel
level: 5
- id: flex_style_dark_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Action
color: primary
variant: solid
size: small
```
Gradient Flex
Ring utility applied to the element CSS key.
```yaml
- id: flex_tw_gradient
type: Flex
class:
.element: bg-gradient-to-r from-primary/100 to-purple-600 p-6 rounded-xl shadow-lg
properties:
gap: 16
align: center
justify: space-between
blocks:
- id: flex_tw_gradient_title
type: Title
layout:
flex: 0 0 auto
class: text-white
properties:
content: Gradient Flex
level: 4
- id: flex_tw_gradient_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Learn More
color: default
variant: solid
size: small
- id: flex_tw_bordered
type: Flex
class:
.element: border-2 border-dashed border-border p-4 rounded-lg
hover:border-blue-400 transition-colors duration-200
properties:
gap: 12
justify: center
wrap: true
blocks:
- id: flex_tw_bordered_tag1
type: Tag
layout:
flex: 0 0 auto
properties:
title: Hover me
color: blue
- id: flex_tw_bordered_tag2
type: Tag
layout:
flex: 0 0 auto
properties:
title: Dashed border
color: cyan
- id: flex_tw_bordered_tag3
type: Tag
layout:
flex: 0 0 auto
properties:
title: Transitions
color: purple
- id: flex_tw_ring
type: Flex
class:
.element: ring-2 ring-green-400 ring-offset-2 p-4 rounded-lg bg-bg-layout
properties:
gap: 8
align: center
blocks:
- id: flex_tw_ring_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: check-circle
color: "#52c41a"
size: 24
- id: flex_tw_ring_text
type: Paragraph
layout:
flex: 0 0 auto
properties:
content: Ring utility applied to the element CSS key.
```
Dashboard
```yaml
- id: flex_app_toolbar
type: Flex
class: bg-bg-container p-3 rounded-lg shadow-sm border
properties:
justify: space-between
align: center
gap: 8
blocks:
- id: flex_app_toolbar_left
type: Flex
properties:
gap: 8
align: center
blocks:
- id: flex_app_toolbar_title
type: Title
layout:
flex: 0 0 auto
properties:
content: Dashboard
level: 5
- id: flex_app_toolbar_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Live
color: success
- id: flex_app_toolbar_right
type: Flex
properties:
gap: 8
blocks:
- id: flex_app_toolbar_btn_filter
type: Button
layout:
flex: 0 0 auto
properties:
title: Filter
icon: filter
color: default
variant: outlined
size: small
events:
onClick:
- id: flex_app_toolbar_filter_msg
type: DisplayMessage
params:
content: Filter panel toggled.
status: info
- id: flex_app_toolbar_btn_export
type: Button
layout:
flex: 0 0 auto
properties:
title: Export
icon: download
color: primary
variant: solid
size: small
events:
onClick:
- id: flex_app_toolbar_export_msg
type: DisplayMessage
params:
content: Export started.
status: success
```
```yaml
- id: flex_stats_row
type: Flex
properties:
gap: 16
wrap: true
blocks:
- id: flex_stats_card1
type: Card
layout:
flex: 1 1 200px
properties:
title: Users
size: small
hoverable: true
blocks:
- id: flex_stats_stat1
type: Statistic
properties:
title: Total
value: 1234
- id: flex_stats_tag1
type: Tag
properties:
title: +8.2%
color: success
- id: flex_stats_card2
type: Card
layout:
flex: 1 1 200px
properties:
title: Revenue
size: small
hoverable: true
blocks:
- id: flex_stats_stat2
type: Statistic
properties:
title: Monthly
value: 8650
prefix: $
- id: flex_stats_tag2
type: Tag
properties:
title: +12.5%
color: success
- id: flex_stats_card3
type: Card
layout:
flex: 1 1 200px
properties:
title: Orders
size: small
hoverable: true
blocks:
- id: flex_stats_stat3
type: Statistic
properties:
title: This Week
value: 56
- id: flex_stats_tag3
type: Tag
properties:
title: -3.1%
color: error
```
Jane Cooper
Senior Product Designer at Acme Corp
```yaml
- id: flex_profile_header
type: Flex
class: bg-bg-container p-6 rounded-xl shadow-sm border
properties:
gap: 24
align: center
wrap: true
blocks:
- id: flex_profile_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 72
color: "#1677ff"
- id: flex_profile_info
type: Flex
layout:
flex: 1 1 200px
properties:
vertical: true
gap: 4
blocks:
- id: flex_profile_name
type: Title
properties:
content: Jane Cooper
level: 4
- id: flex_profile_role
type: Paragraph
properties:
content: Senior Product Designer at Acme Corp
- id: flex_profile_tags
type: Flex
properties:
gap: 8
wrap: true
blocks:
- id: flex_profile_tag1
type: Tag
layout:
flex: 0 0 auto
properties:
title: Design
color: blue
- id: flex_profile_tag2
type: Tag
layout:
flex: 0 0 auto
properties:
title: UX Research
color: purple
- id: flex_profile_tag3
type: Tag
layout:
flex: 0 0 auto
properties:
title: Figma
color: cyan
- id: flex_profile_actions
type: Flex
layout:
flex: 0 0 auto
properties:
gap: 8
blocks:
- id: flex_profile_btn_msg
type: Button
layout:
flex: 0 0 auto
properties:
title: Message
icon: mail
color: primary
variant: outlined
events:
onClick:
- id: flex_profile_msg_action
type: DisplayMessage
params:
content: Opening message composer...
status: info
- id: flex_profile_btn_follow
type: Button
layout:
flex: 0 0 auto
properties:
title: Follow
icon: UserPlus
color: primary
variant: solid
events:
onClick:
- id: flex_profile_follow_action
type: SetState
params:
following: true
- id: flex_profile_follow_msg
type: DisplayMessage
params:
content: You are now following Jane Cooper.
status: success
```
Fast Builds
Incremental compilation and smart caching reduce build times by up to 80% compared to traditional frameworks.
Secure by Default
Built-in authentication, role-based access control, and automatic input sanitization protect your application out of the box.
Fully Extensible
Custom plugins for blocks, connections, operators, and actions let you extend functionality to match any requirement.
```yaml
- id: flex_features_row
type: Flex
properties:
gap: 16
wrap: true
align: stretch
blocks:
- id: flex_feature_card1
type: Card
layout:
flex: 1 1 240px
properties:
hoverable: true
blocks:
- id: flex_feature1_icon_row
type: Flex
properties:
gap: 12
align: center
blocks:
- id: flex_feature1_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: Zap
color: "#1677ff"
size: 28
- id: flex_feature1_title
type: Title
layout:
flex: 0 0 auto
properties:
content: Fast Builds
level: 5
- id: flex_feature1_desc
type: Paragraph
properties:
content: Incremental compilation and smart caching reduce build times by up to
80% compared to traditional frameworks.
- id: flex_feature1_btn
type: Button
properties:
title: Learn More
color: primary
variant: link
size: small
events:
onClick:
- id: flex_feature1_link
type: Link
params:
url: https://docs.lowdefy.com
newTab: true
- id: flex_feature_card2
type: Card
layout:
flex: 1 1 240px
properties:
hoverable: true
blocks:
- id: flex_feature2_icon_row
type: Flex
properties:
gap: 12
align: center
blocks:
- id: flex_feature2_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: Shield
color: "#52c41a"
size: 28
- id: flex_feature2_title
type: Title
layout:
flex: 0 0 auto
properties:
content: Secure by Default
level: 5
- id: flex_feature2_desc
type: Paragraph
properties:
content: Built-in authentication, role-based access control, and automatic input
sanitization protect your application out of the box.
- id: flex_feature2_btn
type: Button
properties:
title: Learn More
color: primary
variant: link
size: small
events:
onClick:
- id: flex_feature2_link
type: Link
params:
url: https://docs.lowdefy.com
newTab: true
- id: flex_feature_card3
type: Card
layout:
flex: 1 1 240px
properties:
hoverable: true
blocks:
- id: flex_feature3_icon_row
type: Flex
properties:
gap: 12
align: center
blocks:
- id: flex_feature3_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: Maximize2
color: "#722ed1"
size: 28
- id: flex_feature3_title
type: Title
layout:
flex: 0 0 auto
properties:
content: Fully Extensible
level: 5
- id: flex_feature3_desc
type: Paragraph
properties:
content: Custom plugins for blocks, connections, operators, and actions let you
extend functionality to match any requirement.
- id: flex_feature3_btn
type: Button
properties:
title: Learn More
color: primary
variant: link
size: small
events:
onClick:
- id: flex_feature3_link
type: Link
params:
url: https://docs.lowdefy.com
newTab: true
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `orientation` | string | `"horizontal"` | Direction of the main axis. Takes precedence over vertical. Enum: `horizontal`, `vertical`. |
| `vertical` | boolean | `false` | Whether the main axis direction is vertical. |
| `wrap` | boolean \| string | - | Set whether the element is displayed in a single line or in multiple lines. |
| `justify` | string | - | Set the alignment of elements on the main axis. Enum: `flex-start`, `center`, `flex-end`, `space-between`, `space-around`, `space-evenly`, `start`, `end`, `left`, `right`, `stretch`, `normal`. |
| `align` | string | - | Set the alignment of elements on the cross axis. Enum: `flex-start`, `center`, `flex-end`, `stretch`, `baseline`, `start`, `end`, `self-start`, `self-end`, `normal`. |
| `gap` | string \| number | - | Set the gap between items. Can be "small", "medium" ("middle" is an alias), "large", a number of pixels or a CSS length. |
| `flex` | string \| number | - | Flex CSS shorthand property. |
| `component` | string | - | Custom element type. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design flex tokens](https://ant.design/components/flex#design-token). |
| `theme.paddingXS` | number | `8` | Gap of the "small" gap preset. |
| `theme.padding` | number | `16` | Gap of the "medium" gap preset. |
| `theme.paddingLG` | number | `24` | Gap of the "large" gap preset. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Flex element. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks laid out by the Flex container. |
---
url: https://docs.lowdefy.com/md/container-blocks/footer.md
---
# Footer
Page footer layout section.
Page content above the footer.
My Application - Copyright 2026
```yaml
- id: footer_basic_layout
type: Layout
blocks:
- id: footer_basic_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
minHeight: 120px
blocks:
- id: footer_basic_content_text
type: Paragraph
properties:
content: Page content above the footer.
- id: footer_basic_el
type: Footer
style:
textAlign: center
blocks:
- id: footer_basic_text
type: Paragraph
properties:
content: My Application - Copyright 2026
```
Page content.
Made with Lowdefy
```yaml
- id: footer_links_layout
type: Layout
blocks:
- id: footer_links_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
minHeight: 80px
blocks:
- id: footer_links_content_text
type: Paragraph
properties:
content: Page content.
- id: footer_links_el
type: Footer
style:
textAlign: center
blocks:
- id: footer_links_row
type: Box
layout:
gap: 16
justify: center
blocks:
- id: footer_links_privacy
type: Button
layout:
flex: 0 0 auto
properties:
title: Privacy Policy
color: default
variant: link
- id: footer_links_terms
type: Button
layout:
flex: 0 0 auto
properties:
title: Terms of Service
color: default
variant: link
- id: footer_links_contact
type: Button
layout:
flex: 0 0 auto
properties:
title: Contact Us
color: default
variant: link
- id: footer_links_copyright
type: Paragraph
properties:
content: Made with Lowdefy
style:
.element:
marginTop: 8px
color: "#999"
```
Main website content goes here.
Acme Corp
Building better tools for modern teams since 2020.
Product
Company
© 2026 Acme Corp. All rights reserved.
```yaml
- id: footer_corp_layout
type: Layout
blocks:
- id: footer_corp_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
minHeight: 100px
blocks:
- id: footer_corp_content_text
type: Paragraph
properties:
content: Main website content goes here.
- id: footer_corp_el
type: Footer
class:
.element: bg-bg-layout
style:
padding: 40px 50px 24px
blocks:
- id: footer_corp_columns
type: Box
layout:
gap: 32
justify: space-between
blocks:
- id: footer_corp_col1
type: Box
layout:
flex: 1 1 200px
direction: column
gap: 8
blocks:
- id: footer_corp_col1_title
type: Title
properties:
content: Acme Corp
level: 5
- id: footer_corp_col1_desc
type: Paragraph
properties:
content: Building better tools for modern teams since 2020.
style:
.element:
color: "#666"
- id: footer_corp_col2
type: Box
layout:
flex: 0 0 auto
direction: column
gap: 4
blocks:
- id: footer_corp_col2_title
type: Title
properties:
content: Product
level: 5
- id: footer_corp_col2_link1
type: Button
properties:
title: Features
color: default
variant: link
size: small
- id: footer_corp_col2_link2
type: Button
properties:
title: Pricing
color: default
variant: link
size: small
- id: footer_corp_col2_link3
type: Button
properties:
title: Documentation
color: default
variant: link
size: small
- id: footer_corp_col3
type: Box
layout:
flex: 0 0 auto
direction: column
gap: 4
blocks:
- id: footer_corp_col3_title
type: Title
properties:
content: Company
level: 5
- id: footer_corp_col3_link1
type: Button
properties:
title: About
color: default
variant: link
size: small
- id: footer_corp_col3_link2
type: Button
properties:
title: Careers
color: default
variant: link
size: small
- id: footer_corp_col3_link3
type: Button
properties:
title: Contact
color: default
variant: link
size: small
- id: footer_corp_divider
type: Divider
- id: footer_corp_bottom
type: Box
layout:
justify: space-between
align: center
blocks:
- id: footer_corp_copyright
type: Paragraph
layout:
flex: 0 0 auto
properties:
content: © 2026 Acme Corp. All rights reserved.
style:
.element:
color: "#999"
margin: 0
- id: footer_corp_social
type: Box
layout:
flex: 0 0 auto
gap: 12
blocks:
- id: footer_corp_social_github
type: Button
layout:
flex: 0 0 auto
properties:
icon: GitBranch
color: default
variant: text
size: small
hideTitle: true
- id: footer_corp_social_twitter
type: Button
layout:
flex: 0 0 auto
properties:
icon: Bird
color: default
variant: text
size: small
hideTitle: true
```
Dashboard
Admin Portal v2.4.1 - Powered by Lowdefy
```yaml
- id: footer_admin_layout
type: Layout
properties:
hasSider: true
blocks:
- id: footer_admin_sider
type: Sider
layout:
flex: 0 0 auto
properties:
width: 200
theme: dark
style:
minHeight: 200px
blocks:
- id: footer_admin_sider_menu
type: Menu
properties:
theme: dark
mode: inline
links:
- id: footer_admin_menu_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: footer_admin_menu_users
type: MenuLink
properties:
title: Users
icon: user
- id: footer_admin_menu_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: footer_admin_inner_layout
type: Layout
layout:
flex: 1 1 auto
blocks:
- id: footer_admin_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
minHeight: 120px
blocks:
- id: footer_admin_content_title
type: Title
properties:
content: Dashboard
level: 3
- id: footer_admin_stats_row
type: Box
layout:
gap: 16
blocks:
- id: footer_admin_stat1
type: Statistic
layout:
flex: 1 1 0
properties:
title: Total Users
value: 1284
- id: footer_admin_stat2
type: Statistic
layout:
flex: 1 1 0
properties:
title: Active Sessions
value: 312
- id: footer_admin_stat3
type: Statistic
layout:
flex: 1 1 0
properties:
title: Pending Tasks
value: 47
- id: footer_admin_el
type: Footer
style:
textAlign: center
padding: 12px 50px
blocks:
- id: footer_admin_text
type: Paragraph
properties:
content: Admin Portal v2.4.1 - Powered by Lowdefy
style:
.element:
color: "#999"
margin: 0
fontSize: 12px
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `theme` | object | - | Not applied: antd scopes Layout design tokens to the Layout element, so set tokens such as headerHeight or footerBg on the parent Layout block theme. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Footer element. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks in the footer. |
---
url: https://docs.lowdefy.com/md/container-blocks/googlemaps.md
---
# GoogleMaps
Interactive Google Map with markers, info windows, marker clusterers, and heatmap layer. Must be wrapped in a `GoogleMapsScript` block. Supports auto-bounding, custom map styles, and events for clicks, zoom changes, and marker interactions.
> The GoogleMaps block must be wrapped in a GoogleMapsScript block with a valid Google Maps API key. The examples on this page require a configured API key to render maps.
```yaml
- id: gm_default
type: GoogleMaps
```
```yaml
- id: gm_center_paris
type: GoogleMaps
properties:
map:
center:
lat: 48.8566
lng: 2.3522
zoom: 14
```
```yaml
- id: gm_type_satellite
type: GoogleMaps
properties:
map:
center:
lat: 37.7749
lng: -122.4194
zoom: 13
mapTypeId: satellite
```
```yaml
- id: gm_no_default_ui
type: GoogleMaps
properties:
map:
center:
lat: 34.0522
lng: -118.2437
zoom: 10
disableDefaultUI: true
- id: gm_selective_controls
type: GoogleMaps
properties:
map:
center:
lat: 34.0522
lng: -118.2437
zoom: 10
zoomControl: false
streetViewControl: false
fullscreenControl: true
mapTypeControl: false
```
```yaml
- id: gm_single_marker
type: GoogleMaps
properties:
map:
center:
lat: 48.8566
lng: 2.3522
zoom: 14
markers:
- position:
lat: 48.8584
lng: 2.2945
label: E
title: Eiffel Tower
```
```yaml
- id: gm_multi_markers
type: GoogleMaps
properties:
map:
center:
lat: 40.7484
lng: -73.9857
zoom: 12
markers:
- position:
lat: 40.6892
lng: -74.0445
label: A
title: Statue of Liberty
- position:
lat: 40.7484
lng: -73.9857
label: B
title: Empire State Building
- position:
lat: 40.7589
lng: -73.9851
label: C
title: Times Square
- position:
lat: 40.7527
lng: -73.9772
label: D
title: Grand Central Terminal
```
```yaml
- id: gm_clusterer_basic
type: GoogleMaps
properties:
map:
center:
lat: 51.51
lng: -0.13
zoom: 12
markerClusterers:
- markers:
- position:
lat: 51.5074
lng: -0.1278
- position:
lat: 51.5155
lng: -0.1419
- position:
lat: 51.5014
lng: -0.1419
- position:
lat: 51.5194
lng: -0.127
- position:
lat: 51.5033
lng: -0.1195
- id: gm_clusterer_options
type: GoogleMaps
properties:
map:
center:
lat: 51.51
lng: -0.13
zoom: 10
markerClusterers:
- markers:
- position:
lat: 51.5074
lng: -0.1278
- position:
lat: 51.5155
lng: -0.1419
- position:
lat: 51.5014
lng: -0.1419
- position:
lat: 51.5194
lng: -0.127
- position:
lat: 51.5033
lng: -0.1195
- position:
lat: 51.49
lng: -0.14
- position:
lat: 51.525
lng: -0.11
options:
averageCenter: true
gridSize: 60
minimumClusterSize: 3
zoomOnClick: true
```
```yaml
- id: gm_info_window
type: GoogleMaps
properties:
map:
center:
lat: -33.8568
lng: 151.2153
zoom: 15
markers:
- position:
lat: -33.8568
lng: 151.2153
title: Sydney Opera House
infoWindow:
position:
lat: -33.8568
lng: 151.2153
```
```yaml
- id: gm_auto_bounds_enabled
type: GoogleMaps
properties:
markers:
- position:
lat: 48.8566
lng: 2.3522
label: Paris
- position:
lat: 35.6762
lng: 139.6503
label: Tokyo
- position:
lat: -33.8688
lng: 151.2093
label: Sydney
- id: gm_auto_bounds_disabled
type: GoogleMaps
properties:
autoBounds: false
map:
center:
lat: 0
lng: 0
zoom: 2
markers:
- position:
lat: 48.8566
lng: 2.3522
- position:
lat: 35.6762
lng: 139.6503
```
```yaml
- id: gm_custom_style_tall
type: GoogleMaps
properties:
style:
height: 500px
map:
center:
lat: 40.7128
lng: -74.006
zoom: 12
- id: gm_custom_style_compact
type: GoogleMaps
properties:
style:
height: 200px
map:
center:
lat: 51.5074
lng: -0.1278
zoom: 10
```
```yaml
- id: gm_heatmap
type: GoogleMaps
properties:
map:
center:
lat: 37.775
lng: -122.434
zoom: 13
heatmap:
data:
- lat: 37.782
lng: -122.447
weight: 3
- lat: 37.782
lng: -122.445
weight: 2
- lat: 37.782
lng: -122.443
weight: 5
- lat: 37.78
lng: -122.44
weight: 1
- lat: 37.779
lng: -122.438
weight: 4
- lat: 37.774
lng: -122.43
weight: 2
- lat: 37.77
lng: -122.425
weight: 3
```
```yaml
- id: gm_events_click
type: GoogleMaps
properties:
map:
center:
lat: 51.5074
lng: -0.1278
zoom: 12
markers:
- position:
lat: 51.5074
lng: -0.1278
label: A
title: Central London
events:
onClick:
- id: gm_click_action
type: DisplayMessage
params:
content: Map clicked!
duration: 3
onMarkerClick:
- id: gm_marker_click_action
type: DisplayMessage
params:
content: Marker clicked!
duration: 3
onZoomChanged:
- id: gm_zoom_action
type: SetState
params:
lastZoomEvent: zoom level changed
```
```yaml
- id: gm_tailwind_rounded
type: GoogleMaps
class: rounded-xl overflow-hidden shadow-lg
properties:
map:
center:
lat: 48.8566
lng: 2.3522
zoom: 13
- id: gm_tailwind_bordered
type: GoogleMaps
class: rounded-lg border-2 border-blue-400 shadow-md
properties:
map:
center:
lat: 35.6762
lng: 139.6503
zoom: 12
```
```yaml
- id: gm_css_key_element
type: GoogleMaps
class:
element: rounded-2xl overflow-hidden shadow-xl border border-gray-200
properties:
map:
center:
lat: 40.4168
lng: -3.7038
zoom: 13
```
Coffee Shop Locations
Find your nearest branch. Click a marker for details.
```yaml
- id: gm_store_locator_title
type: Title
properties:
content: Coffee Shop Locations
level: 4
- id: gm_store_locator_description
type: Paragraph
properties:
content: Find your nearest branch. Click a marker for details.
- id: gm_store_locator_map
type: GoogleMaps
class: rounded-lg overflow-hidden shadow-md
properties:
style:
height: 400px
map:
center:
lat: 40.758
lng: -73.9855
zoom: 14
markers:
- position:
lat: 40.7614
lng: -73.9776
label: "1"
title: 5th Avenue Branch
- position:
lat: 40.7549
lng: -73.984
label: "2"
title: Times Square Branch
- position:
lat: 40.7527
lng: -73.9772
label: "3"
title: Grand Central Branch
events:
onMarkerClick:
- id: gm_store_locator_marker_click
type: DisplayMessage
params:
content: Loading branch details...
duration: 2
```
Active Deliveries
```yaml
- id: gm_delivery_header
type: Box
layout:
gap: 16
align: center
blocks:
- id: gm_delivery_title
type: Title
layout:
flex: 1 1 0
properties:
content: Active Deliveries
level: 4
- id: gm_delivery_count
type: Tag
layout:
flex: 0 0 auto
properties:
title: 4 in transit
color: processing
- id: gm_delivery_map
type: GoogleMaps
class: rounded-lg overflow-hidden border border-gray-200
properties:
style:
height: 450px
map:
center:
lat: 51.51
lng: -0.12
zoom: 12
markers:
- position:
lat: 51.5225
lng: -0.0835
label: "1"
title: "Order #1042 - En route"
- position:
lat: 51.5074
lng: -0.1278
label: "2"
title: "Order #1043 - Arriving soon"
- position:
lat: 51.4975
lng: -0.1357
label: "3"
title: "Order #1044 - Picked up"
- position:
lat: 51.5155
lng: -0.1419
label: "4"
title: "Order #1045 - En route"
events:
onMarkerClick:
- id: gm_delivery_marker_action
type: DisplayMessage
params:
content: Opening delivery details...
duration: 2
- id: gm_delivery_legend
type: Box
layout:
gap: 16
blocks:
- id: gm_delivery_tag1
type: Tag
properties:
title: En route
color: blue
- id: gm_delivery_tag2
type: Tag
properties:
title: Arriving soon
color: green
- id: gm_delivery_tag3
type: Tag
properties:
title: Picked up
color: orange
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `autoBounds` | boolean | `true` | Automatically fit the map bounds to include all markers, clusterers, and info windows. |
| `map` | object | - | Map settings object. |
| `map.center` | object | - | A coordinate position object by which to center the map. |
| `map.center.lat` | number | - | Lateral coordinate. |
| `map.center.lng` | number | - | Longitudinal coordinate. |
| `map.zoom` | number | - | Map zoom level. |
| `map.options` | object | - | Map options. See [Google Maps MapOptions](https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions). |
| `heatmap` | object | - | Add a heatmap layer. This will automatically load the visualization library. See [heatmap options](https://developers.google.com/maps/documentation/javascript/reference/visualization#HeatmapLayerOptions). |
| `heatmap.data` | array | - | A list of heatmap data points. |
| `heatmap.data.$.lat` | number | - | Lateral coordinate. |
| `heatmap.data.$.lng` | number | - | Longitudinal coordinate. |
| `heatmap.data.$.weight` | number | - | Item weight on heatmap. |
| `markers` | array | - | A list of markers with marker options. See [Google Maps Markers](https://developers.google.com/maps/documentation/javascript/markers). |
| `markers.$.position` | object | - | |
| `markers.$.position.lat` | number | - | Lateral coordinate. |
| `markers.$.position.lng` | number | - | Longitudinal coordinate. |
| `markers.$.label` | string | - | Label displayed on marker. |
| `markers.$.title` | string | - | Marker title shown on hover. |
| `markerClusterers` | array | - | A list of marker clusterers with marker clusterer options. |
| `markerClusterers.$.markers` | array | - | A list of markers with marker options. |
| `markerClusterers.$.markers.$.position` | object | - | |
| `markerClusterers.$.markers.$.position.lat` | number | - | Lateral coordinate. |
| `markerClusterers.$.markers.$.position.lng` | number | - | Longitudinal coordinate. |
| `markerClusterers.$.markers.$.label` | string | - | Label displayed on marker. |
| `markerClusterers.$.options` | object | - | Marker clusterer options. See [MarkerClusterer](https://react-google-maps-api-docs.netlify.app/#markerclusterer). |
| `markerClusterers.$.options.averageCenter` | boolean | - | Whether the position of a cluster marker should be the average position of all markers in the cluster. |
| `markerClusterers.$.options.gridSize` | number | - | The grid size of a cluster in pixels. |
| `markerClusterers.$.options.maxZoom` | number | - | The maximum zoom level at which clustering is enabled. |
| `markerClusterers.$.options.minimumClusterSize` | number | - | The minimum number of markers needed to form a cluster. |
| `markerClusterers.$.options.styles` | array | - | Styles of the cluster markers to be used. |
| `markerClusterers.$.options.zoomOnClick` | boolean | - | Whether to zoom the map when a cluster marker is clicked. |
| `infoWindow` | object | - | Info window options. See [InfoWindowOptions](https://developers.google.com/maps/documentation/javascript/reference/info-window#InfoWindowOptions). |
| `infoWindow.visible` | boolean | - | When visible is true, blocks inside the infoWindow content area will be rendered. |
| `infoWindow.position` | object | - | |
| `infoWindow.position.lat` | number | - | Lateral coordinate. |
| `infoWindow.position.lng` | number | - | Longitudinal coordinate. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onBoundsChanged` | \- | Trigger actions when the bounds of the map are changed. |
| `onCenterChanged` | \- | Trigger actions when the center of the map is changed. |
| `onClick` | \- | Trigger actions when the map is clicked. |
| `onClusterClick` | \- | Trigger actions when a marker cluster is clicked. |
| `onMarkerClick` | \- | Trigger actions when a marker is clicked. |
| `onZoomChanged` | \- | Trigger actions when the zoom on the map is changed. |
| `onInfoWindowCloseClick` | \- | Trigger actions when the info window close button is clicked. |
| `onInfoWindowPositionChanged` | \- | Trigger actions when the info window position changes. |
| `onLoad` | \- | Trigger actions when the map is loaded. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The map container element. |
| Slot | Description |
| --- | --- |
| `content` | Marker blocks on the map. |
| `infoWindow` | Info window popup content. |
---
url: https://docs.lowdefy.com/md/container-blocks/googlemapsheatmap.md
---
# GoogleMapsHeatmap
Google Map with a heatmap visualization layer for displaying data density. Must be wrapped in a `GoogleMapsScript` block with `libraries: [visualization]`. Supports weighted data points, configurable radius and opacity, markers, and info windows.
> The GoogleMapsHeatmap block must be wrapped in a GoogleMapsScript block with a valid Google Maps API key and the visualization library. The examples on this page require a configured API key to render maps.
```yaml
- id: heatmap_basic
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 37.775
lng: -122.434
zoom: 13
heatmap:
data:
- lat: 37.782
lng: -122.447
- lat: 37.782
lng: -122.445
- lat: 37.782
lng: -122.443
- lat: 37.784
lng: -122.441
- lat: 37.786
lng: -122.439
- lat: 37.786
lng: -122.435
- lat: 37.77
lng: -122.432
- lat: 37.768
lng: -122.43
```
```yaml
- id: heatmap_zoomed_out
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 51.509
lng: -0.118
zoom: 10
heatmap:
data:
- lat: 51.512
lng: -0.091
- lat: 51.507
lng: -0.076
- lat: 51.503
lng: -0.119
- lat: 51.515
lng: -0.142
- id: heatmap_zoomed_in
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 51.509
lng: -0.118
zoom: 15
heatmap:
data:
- lat: 51.512
lng: -0.091
- lat: 51.507
lng: -0.076
- lat: 51.503
lng: -0.119
- lat: 51.515
lng: -0.142
```
```yaml
- id: heatmap_map_options
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 40.7128
lng: -74.006
zoom: 12
options:
mapTypeId: satellite
disableDefaultUI: true
heatmap:
data:
- lat: 40.7128
lng: -74.006
- lat: 40.72
lng: -73.998
- lat: 40.706
lng: -74.01
- lat: 40.718
lng: -73.99
```
```yaml
- id: heatmap_weighted
type: GoogleMapsHeatmap
properties:
autoBounds: false
map:
center:
lat: 51.509
lng: -0.118
zoom: 13
heatmap:
data:
- location:
lat: 51.512
lng: -0.091
weight: 10
- location:
lat: 51.507
lng: -0.076
weight: 5
- location:
lat: 51.503
lng: -0.119
weight: 8
- location:
lat: 51.515
lng: -0.142
weight: 3
- location:
lat: 51.52
lng: -0.105
weight: 7
```
```yaml
- id: heatmap_radius_small
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 40.7128
lng: -74.006
zoom: 12
heatmap:
radius: 15
data:
- lat: 40.7128
lng: -74.006
- lat: 40.72
lng: -73.998
- lat: 40.706
lng: -74.01
- lat: 40.718
lng: -73.99
- lat: 40.71
lng: -74.015
- id: heatmap_radius_large
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 40.7128
lng: -74.006
zoom: 12
heatmap:
radius: 50
data:
- lat: 40.7128
lng: -74.006
- lat: 40.72
lng: -73.998
- lat: 40.706
lng: -74.01
- lat: 40.718
lng: -73.99
- lat: 40.71
lng: -74.015
- id: heatmap_opacity_low
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 34.0522
lng: -118.2437
zoom: 12
heatmap:
opacity: 0.3
data:
- lat: 34.0522
lng: -118.2437
- lat: 34.06
lng: -118.25
- lat: 34.048
lng: -118.235
- lat: 34.055
lng: -118.26
- id: heatmap_opacity_full
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 34.0522
lng: -118.2437
zoom: 12
heatmap:
opacity: 1
data:
- lat: 34.0522
lng: -118.2437
- lat: 34.06
lng: -118.25
- lat: 34.048
lng: -118.235
- lat: 34.055
lng: -118.26
```
```yaml
- id: heatmap_no_auto_bounds
type: GoogleMapsHeatmap
properties:
autoBounds: false
map:
center:
lat: 35.6762
lng: 139.6503
zoom: 11
heatmap:
data:
- lat: 35.6812
lng: 139.7671
- lat: 35.6595
lng: 139.7005
- lat: 35.6938
lng: 139.7034
- lat: 35.6586
lng: 139.7454
```
```yaml
- id: heatmap_with_markers
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 48.8566
lng: 2.3522
zoom: 13
markers:
- position:
lat: 48.8584
lng: 2.2945
label: A
- position:
lat: 48.8606
lng: 2.3376
label: B
- position:
lat: 48.853
lng: 2.3499
label: C
heatmap:
radius: 25
data:
- lat: 48.8584
lng: 2.2945
- lat: 48.8606
lng: 2.3376
- lat: 48.853
lng: 2.3499
- lat: 48.862
lng: 2.332
- lat: 48.8566
lng: 2.3522
```
```yaml
- id: heatmap_custom_style
type: GoogleMapsHeatmap
properties:
style:
width: 100%
height: 500px
map:
center:
lat: -33.8688
lng: 151.2093
zoom: 12
heatmap:
radius: 30
data:
- lat: -33.8688
lng: 151.2093
- lat: -33.856
lng: 151.2153
- lat: -33.875
lng: 151.2
- lat: -33.861
lng: 151.21
```
```yaml
- id: heatmap_events
type: GoogleMapsHeatmap
properties:
map:
center:
lat: 48.8566
lng: 2.3522
zoom: 13
markers:
- position:
lat: 48.8584
lng: 2.2945
label: A
- position:
lat: 48.8606
lng: 2.3376
label: B
heatmap:
data:
- lat: 48.8584
lng: 2.2945
- lat: 48.8606
lng: 2.3376
- lat: 48.8566
lng: 2.3522
events:
onClick:
- id: heatmap_click_display
type: DisplayMessage
params:
content: Map clicked!
status: info
onMarkerClick:
- id: heatmap_marker_click_msg
type: DisplayMessage
params:
content: Marker clicked!
status: success
onZoomChanged:
- id: heatmap_zoom_set_state
type: SetState
params:
currentZoom:
_event: zoom
```
```yaml
- id: heatmap_css_element
type: GoogleMapsHeatmap
class:
element: rounded-xl shadow-lg border-2 border-blue-300
properties:
map:
center:
lat: 37.775
lng: -122.434
zoom: 13
heatmap:
data:
- lat: 37.782
lng: -122.447
- lat: 37.782
lng: -122.445
- lat: 37.784
lng: -122.441
- lat: 37.786
lng: -122.435
- id: heatmap_css_rounded_shadow
type: GoogleMapsHeatmap
class:
element: rounded-2xl shadow-2xl overflow-hidden
properties:
style:
height: 350px
map:
center:
lat: 51.509
lng: -0.118
zoom: 13
heatmap:
data:
- lat: 51.512
lng: -0.091
- lat: 51.507
lng: -0.076
- lat: 51.503
lng: -0.119
```
Store Foot Traffic Analysis
Visualizing customer activity density across downtown locations. Higher intensity areas indicate more foot traffic during peak hours.
```yaml
- id: store_dashboard_title
type: Title
properties:
content: Store Foot Traffic Analysis
level: 3
- id: store_dashboard_desc
type: Paragraph
properties:
content: Visualizing customer activity density across downtown locations. Higher
intensity areas indicate more foot traffic during peak hours.
- id: store_dashboard_map
type: GoogleMapsHeatmap
class:
element: rounded-lg shadow-md
properties:
style:
height: 450px
map:
center:
lat: 40.758
lng: -73.9855
zoom: 14
markers:
- position:
lat: 40.7614
lng: -73.9776
label: S1
- position:
lat: 40.7549
lng: -73.984
label: S2
- position:
lat: 40.7587
lng: -73.99
label: S3
heatmap:
radius: 35
opacity: 0.7
data:
- lat: 40.7614
lng: -73.9776
- lat: 40.76
lng: -73.979
- lat: 40.759
lng: -73.98
- lat: 40.7549
lng: -73.984
- lat: 40.756
lng: -73.983
- lat: 40.7587
lng: -73.99
- lat: 40.7575
lng: -73.987
events:
onMarkerClick:
- id: store_marker_click_msg
type: DisplayMessage
params:
content: Click a store marker to view detailed foot traffic analytics.
status: info
```
Real-time air quality index readings from distributed sensor stations. Warmer areas on the heatmap indicate higher pollutant concentrations. Markers show individual sensor locations.
```yaml
- id: sensor_network_card
type: Card
properties:
title: Air Quality Monitoring - San Francisco Bay Area
slots:
extra:
blocks:
- id: sensor_network_refresh_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Refresh Data
icon: refresh
color: primary
variant: outlined
size: small
events:
onClick:
- id: sensor_refresh_msg
type: DisplayMessage
params:
content: Sensor data refreshed.
status: success
blocks:
- id: sensor_network_desc
type: Paragraph
properties:
content: Real-time air quality index readings from distributed sensor stations.
Warmer areas on the heatmap indicate higher pollutant concentrations.
Markers show individual sensor locations.
- id: sensor_network_map
type: GoogleMapsHeatmap
class:
element: rounded-lg
properties:
autoBounds: false
style:
height: 500px
map:
center:
lat: 37.775
lng: -122.418
zoom: 12
options:
mapTypeControl: false
streetViewControl: false
markers:
- position:
lat: 37.7849
lng: -122.4094
label: "1"
- position:
lat: 37.7694
lng: -122.4862
label: "2"
- position:
lat: 37.7599
lng: -122.4148
label: "3"
- position:
lat: 37.7909
lng: -122.4
label: "4"
- position:
lat: 37.775
lng: -122.435
label: "5"
heatmap:
radius: 40
opacity: 0.6
data:
- lat: 37.7849
lng: -122.4094
- lat: 37.7694
lng: -122.4862
- lat: 37.7599
lng: -122.4148
- lat: 37.7909
lng: -122.4
- lat: 37.775
lng: -122.435
- lat: 37.78
lng: -122.42
- lat: 37.772
lng: -122.45
events:
onMarkerClick:
- id: sensor_marker_click_msg
type: DisplayMessage
params:
content: Select a sensor station to view detailed air quality readings.
status: info
onClick:
- id: sensor_map_click_set
type: SetState
params:
selectedLocation:
_event: latLng
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `autoBounds` | boolean | `true` | Automatically fit the map bounds to include all markers and heatmap data points. |
| `map` | object | - | Map settings object. |
| `map.center` | object | - | A coordinate position object by which to center the map. |
| `map.center.lat` | number | - | Lateral coordinate. |
| `map.center.lng` | number | - | Longitudinal coordinate. |
| `map.zoom` | number | - | Map zoom level. |
| `map.options` | object | - | Map options. See [Google Maps MapOptions](https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions). |
| `heatmap` | object | - | Heatmap layer options. See [heatmap options](https://developers.google.com/maps/documentation/javascript/reference/visualization#HeatmapLayerOptions). |
| `heatmap.data` | array | - | A list of heatmap data points. |
| `heatmap.data.$.lat` | number | - | Lateral coordinate. |
| `heatmap.data.$.lng` | number | - | Longitudinal coordinate. |
| `heatmap.data.$.weight` | number | - | Item weight on heatmap. |
| `heatmap.radius` | number | - | The radius of influence for each data point, in pixels. |
| `heatmap.opacity` | number | - | The opacity of the heatmap, from 0 to 1. |
| `markers` | array | - | A list of markers with marker options. See [Google Maps Markers](https://developers.google.com/maps/documentation/javascript/markers). |
| `markers.$.position` | object | - | |
| `markers.$.position.lat` | number | - | Lateral coordinate. |
| `markers.$.position.lng` | number | - | Longitudinal coordinate. |
| `markers.$.label` | string | - | Label displayed on marker. |
| `infoWindow` | object | - | Info window options. See [InfoWindowOptions](https://developers.google.com/maps/documentation/javascript/reference/info-window#InfoWindowOptions). |
| `infoWindow.visible` | boolean | - | When visible is true, blocks inside the infoWindow content area will be rendered. |
| `infoWindow.position` | object | - | |
| `infoWindow.position.lat` | number | - | Lateral coordinate. |
| `infoWindow.position.lng` | number | - | Longitudinal coordinate. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onClick` | \- | Trigger actions when the map is clicked. |
| `onMarkerClick` | \- | Trigger actions when a marker is clicked. |
| `onZoomChanged` | \- | Trigger actions when the zoom on the map is changed. |
| `onBoundsChanged` | \- | Trigger actions when the bounds of the map are changed. |
| `onCenterChanged` | \- | Trigger actions when the center of the map is changed. |
| `onInfoWindowCloseClick` | \- | Trigger actions when the info window close button is clicked. |
| `onInfoWindowPositionChanged` | \- | Trigger actions when the info window position changes. |
| `onLoad` | \- | Trigger actions when the map is loaded. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The map container element. |
| Slot | Description |
| --- | --- |
| `content` | Marker blocks on the map. |
| `infoWindow` | Info window popup content. |
---
url: https://docs.lowdefy.com/md/container-blocks/googlemapsscript.md
---
# GoogleMapsScript
Loads the Google Maps JavaScript API and wraps `GoogleMaps`, `GoogleMapsHeatmap` and `PlacesAutocomplete` blocks as a parent container. Configure the API key, language, region, libraries, and API version. Blocks that use an optional library should be wrapped in a GoogleMapsScript that loads it — list `libraries: [places]` for `PlacesAutocomplete` so the library is ready on first render. When it is not listed, `PlacesAutocomplete` imports it on demand through `google.maps.importLibrary`.
> GoogleMapsScript loads the Google Maps JavaScript API. Only one GoogleMapsScript should be used per page. It must wrap GoogleMaps, GoogleMapsHeatmap or PlacesAutocomplete blocks as a parent container. The examples below show configuration patterns — maps require a valid API key to render.
```yaml
- id: gms_full_config
type: GoogleMapsScript
properties:
apiKey: null
language: en
region: US
version: weekly
libraries:
- visualization
- places
channel: production
blocks:
- id: gms_full_config_map
type: GoogleMaps
properties:
map:
center:
lat: 40.7128
lng: -74.006
zoom: 12
markers:
- position:
lat: 40.7484
lng: -73.9857
label: A
title: Empire State Building
- position:
lat: 40.6892
lng: -74.0445
label: B
title: Statue of Liberty
- position:
lat: 40.7589
lng: -73.9851
label: C
title: Times Square
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `apiKey` | string | - | Your Google Maps API key. |
| `libraries` | array | - | A list of Google libraries to load. See [Google Maps Libraries](https://developers.google.com/maps/documentation/javascript/libraries). |
| `language` | string | - | The language code for the Google Maps API (e.g. "en", "fr", "ja"). |
| `region` | string | - | The region code to bias geocoding results (e.g. "US", "GB"). See [localization](https://developers.google.com/maps/documentation/javascript/localization). |
| `version` | string | - | The version of the Google Maps JavaScript API to load (e.g. "weekly", "3.50"). |
| `channel` | string | - | A channel parameter for tracking API usage. |
No events defined.
No CSS keys defined.
| Slot | Description |
| --- | --- |
| `content` | Child blocks wrapped by the script provider. |
---
url: https://docs.lowdefy.com/md/container-blocks/header.md
---
# Header
Page header layout section. Supports built-in notifications, profile avatar, and dark mode toggle.
```yaml
- id: header_basic
type: Header
style:
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: header_basic_logo
type: Html
layout:
flex: 0 0 auto
properties:
html: MyApp
```
```yaml
- id: header_nav
type: Header
style:
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: header_nav_logo
type: Html
layout:
flex: 0 0 auto
properties:
html: MyApp
- id: header_nav_home
type: Button
layout:
flex: 0 0 auto
properties:
title: Home
icon: home
color: default
variant: link
- id: header_nav_about
type: Button
layout:
flex: 0 0 auto
properties:
title: About
color: default
variant: link
- id: header_nav_contact
type: Button
layout:
flex: 0 0 auto
properties:
title: Contact
color: default
variant: link
```
```yaml
- id: header_profile
type: Header
properties:
darkModeToggle: true
notifications:
count: 3
profile:
avatar:
content: JD
color: "#1677ff"
links:
- id: header_prof_profile
type: MenuLink
properties:
title: My Profile
icon: user
- id: header_prof_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: header_prof_divider
type: MenuDivider
- id: header_prof_logout
type: MenuLink
properties:
title: Logout
icon: logout
danger: true
style:
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: header_profile_logo
type: Html
layout:
flex: 0 0 auto
properties:
html: Dashboard
- id: header_profile_overview
type: Button
layout:
flex: 0 0 auto
properties:
title: Overview
icon: Gauge
color: default
variant: link
- id: header_profile_projects
type: Button
layout:
flex: 0 0 auto
properties:
title: Projects
icon: SquareKanban
color: default
variant: link
```
Build Better Products, Faster
A Header for marketing pages with button navigation and call-to-action buttons.
```yaml
- id: header_marketing
type: Layout
style:
minHeight: 300px
blocks:
- id: header_marketing_el
type: Header
style:
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: header_marketing_brand
type: Html
layout:
flex: 0 0 auto
properties:
html: Acme Inc
- id: header_marketing_nav_features
type: Button
layout:
flex: 0 0 auto
properties:
title: Features
color: default
variant: link
- id: header_marketing_nav_pricing
type: Button
layout:
flex: 0 0 auto
properties:
title: Pricing
color: default
variant: link
- id: header_marketing_nav_docs
type: Button
layout:
flex: 0 0 auto
properties:
title: Docs
color: default
variant: link
- id: header_marketing_spacer
type: Box
layout:
flex: 1 1 0
- id: header_marketing_btn_login
type: Button
layout:
flex: 0 0 auto
properties:
title: Log In
color: default
variant: outlined
- id: header_marketing_btn_signup
type: Button
layout:
flex: 0 0 auto
properties:
title: Get Started
color: primary
variant: solid
- id: header_marketing_content
type: Content
style:
padding: 64px 48px
textAlign: center
blocks:
- id: header_marketing_hero_title
type: Title
properties:
content: Build Better Products, Faster
level: 1
- id: header_marketing_hero_subtitle
type: Paragraph
properties:
content: A Header for marketing pages with button navigation and call-to-action
buttons.
```
```yaml
- id: header_token_branded_layout
type: Layout
properties:
theme:
headerHeight: 56
headerPadding: 0 24px
blocks:
- id: header_token_branded
type: Header
properties:
color: "#0958d9"
blocks:
- id: header_token_branded_title
type: Html
layout:
flex: 0 0 auto
properties:
html: Branded Header
- id: header_token_branded_spacer
type: Box
layout:
flex: 1 1 0
- id: header_token_branded_subtitle
type: Html
layout:
flex: 0 0 auto
properties:
html: color property with Layout headerHeight and
headerPadding tokens
- id: header_token_compact_layout
type: Layout
properties:
theme:
headerHeight: 40
headerPadding: 0 16px
blocks:
- id: header_token_compact
type: Header
style:
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: header_token_compact_title
type: Html
properties:
html: Compact Header (40px height)
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `color` | string | - | Header background color. Accepts any CSS color value. Defaults to the antd container background color (light in light mode, dark in dark mode). |
| `iconsColor` | string | - | Color for the notification, profile, and dark mode toggle icons. Use when the header has a dark background color. |
| `notifications` | object | - | Notification bell icon with badge in the header. Renders when configured. Use the link property to navigate when clicked. |
| `notifications.link` | object | - | Link to navigate to when the notification bell is clicked. |
| `notifications.link.pageId` | string | - | Page to link to. |
| `notifications.link.url` | string | - | External URL to link to. |
| `notifications.link.newTab` | boolean | - | Open link in new tab. |
| `notifications.count` | number | - | Number to display on the badge. Set to 0 to hide the badge (unless showZero is true). |
| `notifications.dot` | boolean | `false` | Show a dot instead of a count number. |
| `notifications.showZero` | boolean | `false` | Show badge when count is zero. |
| `notifications.overflowCount` | number | `99` | Max count to show. Values above this display as "N+". |
| `notifications.color` | string | - | Badge color. |
| `notifications.icon` | string \| object | - | Icon for the notification button. Defaults to `bell`. |
| `notifications.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `notifications.icon.color` | string | - | Icon color. |
| `notifications.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `notifications.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `notifications.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `notifications.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `notifications.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `notifications.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `notifications.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `notifications.size` | string | `"small"` | Size of the notification button. Enum: `small`, `default`, `large`. |
| `profile` | object | - | Profile avatar with optional dropdown menu in the header. Renders when configured. Use with the _user operator to populate from the authenticated user. |
| `profile.avatar` | object | - | Avatar display properties. |
| `profile.avatar.src` | string | - | Image URL for the avatar. Typically bound to _user: image. |
| `profile.avatar.content` | string | - | Text content inside the avatar (e.g. user initials). Shown when no src is provided. |
| `profile.avatar.icon` | string \| object | - | Icon to display in avatar when no src or content is set. Defaults to `user`. |
| `profile.avatar.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `profile.avatar.icon.color` | string | - | Icon color. |
| `profile.avatar.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `profile.avatar.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `profile.avatar.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `profile.avatar.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `profile.avatar.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `profile.avatar.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `profile.avatar.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `profile.avatar.color` | string | - | Background color of the avatar when not using src. |
| `profile.avatar.size` | string \| number | `"small"` | Size of the avatar: default, small, large or a pixel number. |
| `profile.avatar.shape` | string | `"circle"` | Shape of the avatar. Enum: `circle`, `square`. |
| `profile.links` | array | - | Dropdown menu items. Uses the same MenuLink/MenuGroup/MenuDivider pattern as DropdownMenu. When links are provided, clicking the avatar opens a dropdown menu. |
| `profile.links.$.id` | string | - | Menu item id. |
| `profile.links.$.type` | string | `"MenuLink"` | Menu item type. Enum: `MenuDivider`, `MenuLink`, `MenuGroup`. |
| `profile.links.$.pageId` | string | - | Page to link to. |
| `profile.links.$.url` | string | - | External URL to link to. |
| `profile.links.$.newTab` | boolean | - | Open link in new tab. |
| `profile.links.$.properties` | object | - | Properties for the menu item. |
| `profile.links.$.properties.title` | string | - | Menu item title. |
| `profile.links.$.properties.icon` | string \| object | - | Icon for the menu item. |
| `profile.links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `profile.links.$.properties.icon.color` | string | - | Icon color. |
| `profile.links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `profile.links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `profile.links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `profile.links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `profile.links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `profile.links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `profile.links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `profile.links.$.properties.danger` | boolean | `false` | Apply danger style to menu item. |
| `profile.links.$.properties.disabled` | boolean | `false` | Disable the menu item. |
| `profile.trigger` | string | `"hover"` | How the profile dropdown opens. Enum: `click`, `hover`. |
| `profile.placement` | string | `"bottomRight"` | Dropdown placement relative to the avatar. Enum: `bottomLeft`, `bottom`, `bottomRight`, `topLeft`, `top`, `topRight`. |
| `profile.arrow` | boolean \| object | `false` | Show arrow on the dropdown. |
| `profile.arrow.pointAtCenter` | boolean | - | |
| `darkModeToggle` | boolean | `false` | Show a dark mode toggle icon in the header. Toggles the Ant Design dark theme for the entire page. Preference is persisted to localStorage. |
| `theme` | object | - | Not applied: antd scopes Layout design tokens to the Layout element, so set tokens such as headerHeight or footerBg on the parent Layout block theme. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onProfileMenuClick` | `{ key, keyPath, pageId, url }` | Trigger action when a profile dropdown menu item is clicked. |
| `onProfileMenuOpen` | `{ open }` | Trigger action when the profile dropdown opens or closes. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Header element. |
| `/headerActions` | The header actions container (notifications, profile, dark mode toggle). |
| `/notifications` | The notification bell wrapper. |
| `/notificationsBadge` | The notification badge. |
| `/notificationsIcon` | The notification bell icon. |
| `/profile` | The profile avatar and dropdown wrapper. |
| `/profileAvatar` | The profile avatar element. |
| `/profileMenu` | The profile dropdown menu popup. |
| `/darkModeToggle` | The dark mode toggle wrapper. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks in the header. |
---
url: https://docs.lowdefy.com/md/container-blocks/label.md
---
# Label
Form label wrapper with title, description, and validation feedback.
```yaml
- id: label_basic
type: Label
properties:
title: Field Label
blocks:
- id: label_basic_input
type: TextInput
- id: label_no_title
type: Label
blocks:
- id: label_no_title_input
type: TextInput
```
```yaml
- id: label_html_title
type: Label
properties:
title: 'Blue Label '
blocks:
- id: label_html_title_input
type: TextInput
- id: label_html_bold
type: Label
properties:
title: Bold with italic
blocks:
- id: label_html_bold_input
type: TextInput
```
```yaml
- id: label_colon_true
type: Label
properties:
title: With Colon (default)
colon: true
blocks:
- id: label_colon_true_input
type: TextInput
- id: label_colon_false
type: Label
properties:
title: Without Colon
colon: false
blocks:
- id: label_colon_false_input
type: TextInput
```
```yaml
- id: label_disabled
type: Label
properties:
title: This title is hidden
disabled: true
blocks:
- id: label_disabled_input
type: TextInput
- id: label_disabled_extra
type: Label
properties:
title: Also hidden
disabled: true
extra: Extra text still appears when label is disabled.
blocks:
- id: label_disabled_extra_input
type: TextInput
```
```yaml
- id: label_extra_short
type: Label
properties:
title: Username
extra: Must be between 3 and 20 characters.
blocks:
- id: label_extra_short_input
type: TextInput
- id: label_extra_html
type: Label
properties:
title: Website
extra: Enter a full URL, e.g. https://example.com
blocks:
- id: label_extra_html_input
type: TextInput
```
```yaml
- id: label_required
type: Label
required: true
properties:
title: Email Address
blocks:
- id: label_required_input
type: TextInput
- id: label_required_extra
type: Label
required: true
properties:
title: Password
extra: Minimum 8 characters.
blocks:
- id: label_required_extra_input
type: TextInput
```
```yaml
- id: label_size_small
type: Label
properties:
title: Small
size: small
blocks:
- id: label_size_small_input
type: TextInput
properties:
size: small
- id: label_size_default
type: Label
properties:
title: Default
size: default
blocks:
- id: label_size_default_input
type: TextInput
- id: label_size_large
type: Label
properties:
title: Large
size: large
blocks:
- id: label_size_large_input
type: TextInput
properties:
size: large
```
```yaml
- id: label_align_left
type: Label
properties:
title: Left Aligned (default)
align: left
inline: true
span: 6
blocks:
- id: label_align_left_input
type: TextInput
- id: label_align_right
type: Label
properties:
title: Right Aligned
align: right
inline: true
span: 6
blocks:
- id: label_align_right_input
type: TextInput
```
```yaml
- id: label_inline
type: Label
properties:
title: Inline Label
inline: true
blocks:
- id: label_inline_input
type: TextInput
- id: label_inline_span4
type: Label
properties:
title: Span 4
inline: true
span: 4
blocks:
- id: label_inline_span4_input
type: TextInput
- id: label_inline_span8
type: Label
properties:
title: Span 8
inline: true
span: 8
blocks:
- id: label_inline_span8_input
type: TextInput
- id: label_inline_extra
type: Label
properties:
title: Inline with Extra
inline: true
span: 6
extra: Helper text shown below the input.
blocks:
- id: label_inline_extra_input
type: TextInput
```
```yaml
- id: label_wrap_inline
type: Label
layout:
span: 12
properties:
title: A long inline label that wraps onto a second line when space runs out
inline: true
wrap: true
blocks:
- id: label_wrap_inline_input
type: TextInput
```
```yaml
- id: label_inline_small
type: Label
properties:
title: Small Inline
size: small
inline: true
span: 6
blocks:
- id: label_inline_small_input
type: TextInput
properties:
size: small
- id: label_inline_default
type: Label
properties:
title: Default Inline
size: default
inline: true
span: 6
blocks:
- id: label_inline_default_input
type: TextInput
- id: label_inline_large
type: Label
properties:
title: Large Inline
size: large
inline: true
span: 6
blocks:
- id: label_inline_large_input
type: TextInput
properties:
size: large
```
```yaml
- id: label_wrap_number
type: Label
properties:
title: Quantity
blocks:
- id: label_wrap_number_input
type: NumberInput
properties:
min: 0
max: 100
- id: label_wrap_switch
type: Label
properties:
title: Enable Notifications
blocks:
- id: label_wrap_switch_input
type: Switch
- id: label_wrap_select
type: Label
properties:
title: Country
blocks:
- id: label_wrap_select_input
type: Selector
properties:
options:
- label: United States
value: us
- label: United Kingdom
value: uk
- label: Germany
value: de
```
```yaml
- id: label_theme_purple
type: Label
required: true
properties:
title: Purple Label Theme
extra: Extra text inherits theme
theme:
labelColor: "#722ed1"
labelFontSize: 16
labelRequiredMarkColor: "#722ed1"
blocks:
- id: label_theme_purple_input
type: TextInput
- id: label_theme_green_mark
type: Label
required: true
properties:
title: Green Required Mark
theme:
labelRequiredMarkColor: "#52c41a"
blocks:
- id: label_theme_green_mark_input
type: TextInput
- id: label_theme_colon_spacing
type: Label
properties:
title: Wide Colon Spacing
theme:
labelColonMarginInlineStart: 8
labelColonMarginInlineEnd: 16
blocks:
- id: label_theme_colon_input
type: TextInput
- id: label_theme_error_colors
type: Label
properties:
title: Custom Feedback Colors
theme:
colorError: "#cf1322"
colorWarning: "#d48806"
colorSuccess: "#389e0d"
blocks:
- id: label_theme_error_colors_input
type: TextInput
- id: label_theme_description
type: Label
properties:
title: Custom Description Color
extra: This extra text uses a custom description color.
theme:
colorTextDescription: "#722ed1"
fontSize: 13
blocks:
- id: label_theme_description_input
type: TextInput
```
```yaml
- id: label_css_label
type: Label
properties:
title: Styled Label Text
extra: Styled extra text
class:
.label: text-purple-600 font-bold
.extra: text-purple-400 italic
blocks:
- id: label_css_label_input
type: TextInput
- id: label_css_element
type: Label
properties:
title: Bordered Container
class:
.element: border border-border p-3 rounded-lg
blocks:
- id: label_css_element_input
type: TextInput
- id: label_css_feedback
type: Label
properties:
title: Feedback Styling
class:
.feedback: font-semibold text-xs
blocks:
- id: label_css_feedback_input
type: TextInput
- id: label_style_inline
type: Label
properties:
title: Inline Style Overrides
extra: Styled with inline CSS
style:
.label:
color: "#d46b08"
fontWeight: bold
fontSize: 16px
.extra:
color: "#d48806"
fontStyle: italic
.element:
border: "1px solid #ffd591"
padding: 12px
borderRadius: 8px
blocks:
- id: label_style_inline_input
type: TextInput
```
```yaml
- id: label_reg_card
type: Card
properties:
title: Create Account
blocks:
- id: label_reg_name
type: Label
required: true
properties:
title: Full Name
blocks:
- id: label_reg_name_input
type: TextInput
- id: label_reg_email
type: Label
required: true
properties:
title: Email Address
extra: We will never share your email with anyone.
blocks:
- id: label_reg_email_input
type: TextInput
- id: label_reg_password
type: Label
required: true
properties:
title: Password
extra: Minimum 8 characters with at least one number.
blocks:
- id: label_reg_password_input
type: PasswordInput
- id: label_reg_age
type: Label
properties:
title: Age
blocks:
- id: label_reg_age_input
type: NumberInput
properties:
min: 18
max: 120
- id: label_reg_bio
type: Label
properties:
title: Bio
extra: Optional short description about yourself.
colon: false
blocks:
- id: label_reg_bio_input
type: TextArea
properties:
rows: 3
- id: label_reg_actions_row
type: Box
layout:
gap: 8
justify: flex-end
blocks:
- id: label_reg_cancel
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel
color: default
variant: outlined
events:
onClick:
- id: label_reg_cancel_link
type: Link
params:
home: true
- id: label_reg_submit
type: Button
layout:
flex: 0 0 auto
properties:
title: Register
color: primary
variant: solid
events:
onClick:
- id: label_reg_submit_validate
type: Validate
params:
- label_reg_name
- label_reg_email
- label_reg_password
- id: label_reg_submit_msg
type: DisplayMessage
params:
content: Account created successfully!
status: success
```
```yaml
- id: label_settings_card
type: Card
properties:
title: Notification Settings
size: small
blocks:
- id: label_settings_email_notif
type: Label
properties:
title: Email Notifications
inline: true
span: 8
align: right
extra: Receive updates about your account activity.
blocks:
- id: label_settings_email_notif_input
type: Switch
- id: label_settings_frequency
type: Label
properties:
title: Frequency
inline: true
span: 8
align: right
blocks:
- id: label_settings_frequency_input
type: Selector
properties:
options:
- label: Immediately
value: immediate
- label: Daily Digest
value: daily
- label: Weekly Summary
value: weekly
- id: label_settings_sms
type: Label
properties:
title: SMS Alerts
inline: true
span: 8
align: right
extra: Standard messaging rates may apply.
blocks:
- id: label_settings_sms_input
type: Switch
- id: label_settings_phone
type: Label
properties:
title: Phone Number
inline: true
span: 8
align: right
blocks:
- id: label_settings_phone_input
type: PhoneNumberInput
- id: label_settings_save_row
type: Box
layout:
justify: flex-end
gap: 8
blocks:
- id: label_settings_save
type: Button
layout:
flex: 0 0 auto
properties:
title: Save Preferences
color: primary
variant: solid
events:
onClick:
- id: label_settings_save_state
type: SetState
params:
settingsSaved: true
- id: label_settings_save_msg
type: DisplayMessage
params:
content: Preferences saved.
status: success
```
```yaml
- id: label_data_card
type: Card
properties:
title: Add Product
blocks:
- id: label_data_name
type: Label
required: true
properties:
title: Product Name
size: large
blocks:
- id: label_data_name_input
type: TextInput
properties:
size: large
- id: label_data_row
type: Box
layout:
gap: 16
blocks:
- id: label_data_price
type: Label
layout:
flex: 1 1 0
required: true
properties:
title: Price
blocks:
- id: label_data_price_input
type: NumberInput
properties:
min: 0
- id: label_data_category
type: Label
layout:
flex: 1 1 0
required: true
properties:
title: Category
blocks:
- id: label_data_category_input
type: Selector
properties:
options:
- label: Electronics
value: electronics
- label: Clothing
value: clothing
- label: Home & Garden
value: home
- id: label_data_stock
type: Label
layout:
flex: 1 1 0
properties:
title: Stock Quantity
blocks:
- id: label_data_stock_input
type: NumberInput
properties:
min: 0
- id: label_data_desc
type: Label
properties:
title: Description
extra: Markdown formatting is supported.
colon: false
blocks:
- id: label_data_desc_input
type: TextArea
properties:
rows: 4
- id: label_data_active
type: Label
properties:
title: Active Listing
inline: true
span: 6
extra: Toggle off to save as draft.
blocks:
- id: label_data_active_input
type: Switch
- id: label_data_actions_row
type: Box
layout:
gap: 8
justify: flex-end
blocks:
- id: label_data_save_draft
type: Button
layout:
flex: 0 0 auto
properties:
title: Save Draft
color: default
variant: outlined
events:
onClick:
- id: label_data_draft_msg
type: DisplayMessage
params:
content: Draft saved.
status: info
- id: label_data_publish
type: Button
layout:
flex: 0 0 auto
properties:
title: Publish Product
color: primary
variant: solid
events:
onClick:
- id: label_data_publish_validate
type: Validate
params:
- label_data_name
- label_data_price
- label_data_category
- id: label_data_publish_msg
type: DisplayMessage
params:
content: Product published successfully!
status: success
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `xs` | object | - | Label width on extra small screens (below 576px) when the label is not inline. |
| `xs.span` | number | - | Label width in columns, out of 24. The content takes the remaining columns. |
| `sm` | object | - | Label width on small screens (576px and up) when the label is not inline. Also applies below 576px unless `xs` is set. |
| `sm.span` | number | - | Label width in columns, out of 24. The content takes the remaining columns. |
| `md` | object | - | Label width on medium screens (768px and up) when the label is not inline. Overrides `span`. |
| `md.span` | number | - | Label width in columns, out of 24. The content takes the remaining columns. |
| `lg` | object | - | Label width on large screens (992px and up) when the label is not inline. |
| `lg.span` | number | - | Label width in columns, out of 24. The content takes the remaining columns. |
| `xl` | object | - | Label width on extra large screens (1200px and up) when the label is not inline. |
| `xl.span` | number | - | Label width in columns, out of 24. The content takes the remaining columns. |
| `xxl` | object | - | Label width on extra extra large screens (1600px and up) when the label is not inline. |
| `xxl.span` | number | - | Label width in columns, out of 24. The content takes the remaining columns. |
| `align` | string | `"left"` | Align label left or right when inline. Enum: `left`, `right`. |
| `colon` | boolean | `true` | Append label with colon. |
| `disabled` | boolean | `false` | Disable to not render a label title. |
| `extra` | string | - | Extra text to display beneath the content - supports html. |
| `size` | string | `"default"` | Size of the block. Enum: `small`, `default`, `large`. |
| `title` | string | - | Label title - supports html. |
| `tooltip` | string \| object | - | Help tooltip shown via an icon beside the label. A string sets the tooltip text (supports html), or an object to also customize the icon and color. Use the block's onTooltipClick event to respond to clicks on the icon. |
| `tooltip.title` | string | - | Tooltip text shown on hover - supports html. |
| `tooltip.icon` | string | `"help"` | Icon name to show beside the label: a semantic name like `help`, a Lucide icon name like `CircleQuestionMark`, or a set-qualified name like `tabler:HelpCircle`. |
| `tooltip.color` | string | - | Color of the tooltip icon. |
| `span` | number | - | Label width in columns, out of 24, on medium screens (768px) and up when the label is not inline. The content takes the remaining columns. |
| `inline` | boolean | `false` | Render input and label inline. |
| `wrap` | boolean | `false` | Wrap long label text onto multiple lines when the label is inline. Labels above their content always wrap. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design form tokens](https://ant.design/components/form#design-token). |
| `theme.labelFontSize` | number | `14` | Font size of the label text. |
| `theme.labelColor` | string | `"rgba(0,0,0,0.88)"` | Text color of the label. |
| `theme.labelRequiredMarkColor` | string | `"#ff4d4f"` | Color of the required asterisk mark. |
| `theme.labelColonMarginInlineStart` | number | `2` | Inline start margin of the colon after the label. |
| `theme.labelColonMarginInlineEnd` | number | `8` | Inline end margin of the colon after the label. |
| `theme.colorError` | string | `"#ff4d4f"` | Color used for error validation feedback. |
| `theme.colorWarning` | string | `"#faad14"` | Color used for warning validation feedback. |
| `theme.colorSuccess` | string | `"#52c41a"` | Color used for success validation feedback. |
| `theme.colorText` | string | - | Text color for the extra and feedback text. |
| `theme.colorTextDescription` | string | - | Color for the extra description text. |
| `theme.fontSize` | number | `14` | Base font size. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onTooltipClick` | \- | Trigger actions when the tooltip icon is clicked. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Label element. |
| `/label` | The Label label. |
| `/extra` | The Label extra content. |
| `/feedback` | The Label validation feedback. |
| Slot | Description |
| --- | --- |
| `content` | The labeled input or content blocks. |
---
url: https://docs.lowdefy.com/md/container-blocks/layout.md
---
# Layout
Ant Design layout container for structuring page sections.
This is the main content area. The Layout block wraps Header, Content, and Footer to create a standard page structure.
Footer - Copyright 2026
```yaml
- id: layout_basic
type: Layout
style:
minHeight: 300px
blocks:
- id: layout_basic_header
type: Header
style:
paddingInline: 24px
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: layout_basic_header_text
type: Html
properties:
html: Header
- id: layout_basic_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: layout_basic_content_text
type: Paragraph
properties:
content: This is the main content area. The Layout block wraps Header, Content,
and Footer to create a standard page structure.
- id: layout_basic_footer
type: Footer
style:
textAlign: center
blocks:
- id: layout_basic_footer_text
type: Paragraph
properties:
content: Footer - Copyright 2026
```
Layout blocks compose together to create complex page structures. Here, an outer Layout wraps a Header, and an inner Layout contains a Sider and Content side by side.
Footer
```yaml
- id: layout_sider_outer
type: Layout
style:
minHeight: 350px
blocks:
- id: layout_sider_header
type: Header
style:
paddingInline: 24px
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: layout_sider_header_text
type: Html
properties:
html: Header
- id: layout_sider_inner
type: Layout
properties:
hasSider: true
blocks:
- id: layout_sider_side
type: Sider
layout:
flex: 0 0 auto
properties:
theme: light
width: 200
blocks:
- id: layout_sider_side_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: layout_sider_nav_1
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: layout_sider_nav_2
type: MenuLink
properties:
title: Settings
icon: settings
- id: layout_sider_content
type: Content
layout:
flex: 1 1 auto
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: layout_sider_content_text
type: Paragraph
properties:
content: Layout blocks compose together to create complex page structures. Here,
an outer Layout wraps a Header, and an inner Layout contains a
Sider and Content side by side.
- id: layout_sider_footer
type: Footer
style:
textAlign: center
blocks:
- id: layout_sider_footer_text
type: Paragraph
properties:
content: Footer
```
Main content area with a right-side panel. The Sider is placed after Content to render on the right.
Right side panel for supplementary content, filters, or navigation.
```yaml
- id: layout_right_sider_outer
type: Layout
style:
minHeight: 300px
blocks:
- id: layout_right_sider_inner
type: Layout
properties:
hasSider: true
blocks:
- id: layout_right_sider_content
type: Content
layout:
flex: 1 1 auto
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: layout_right_sider_content_text
type: Paragraph
properties:
content: Main content area with a right-side panel. The Sider is placed after
Content to render on the right.
- id: layout_right_sider_side
type: Sider
layout:
flex: 0 0 auto
properties:
theme: light
width: 250
reverseArrow: true
style:
borderLeft: "1px solid #f0f0f0"
blocks:
- id: layout_right_sider_side_text
type: Paragraph
style:
padding: 16px
properties:
content: Right side panel for supplementary content, filters, or navigation.
```
The collapse trigger uses the lightTriggerBg and lightTriggerColor tokens.
The Layout theme property accepts antd Layout design tokens like bodyBg, headerHeight, footerBg and the Sider trigger tokens. They apply to the Header, Footer and Sider blocks inside the layout.
Footer styled with the footerBg and footerPadding tokens
```yaml
- id: layout_theme_outer
type: Layout
style:
minHeight: 280px
properties:
theme:
bodyBg: "#f0f5ff"
headerHeight: 48
headerColor: "#1d39c4"
footerBg: "#d6e4ff"
footerPadding: 12px 24px
lightTriggerBg: "#adc6ff"
lightTriggerColor: "#1d39c4"
blocks:
- id: layout_theme_header
type: Header
style:
paddingInline: 24px
blocks:
- id: layout_theme_header_text
type: Html
properties:
html: 48px header from the headerHeight
token
- id: layout_theme_inner
type: Layout
properties:
hasSider: true
blocks:
- id: layout_theme_sider
type: Sider
layout:
flex: 0 0 auto
properties:
theme: light
width: 180
collapsible: true
initialCollapsed: false
blocks:
- id: layout_theme_sider_text
type: Paragraph
style:
padding: 16px
properties:
content: The collapse trigger uses the lightTriggerBg and lightTriggerColor
tokens.
- id: layout_theme_content
type: Content
layout:
flex: 1 1 auto
style:
padding: 24px
blocks:
- id: layout_theme_content_text
type: Paragraph
properties:
content: The Layout theme property accepts antd Layout design tokens like
bodyBg, headerHeight, footerBg and the Sider trigger tokens.
They apply to the Header, Footer and Sider blocks inside the
layout.
- id: layout_theme_footer
type: Footer
style:
textAlign: center
blocks:
- id: layout_theme_footer_text
type: Paragraph
properties:
content: Footer styled with the footerBg and footerPadding tokens
```
The Layout block has a single cssKey called "element". Use the class property to apply Tailwind utility classes directly to the Layout wrapper. Here the outer Layout uses rounded corners, shadow, and a border. Child blocks like Header, Content, and Footer can each have their own class applied.
Footer with Tailwind background
```yaml
- id: layout_tailwind_outer
type: Layout
class: rounded-lg overflow-hidden shadow-lg border border-border
style:
minHeight: 280px
blocks:
- id: layout_tailwind_header
type: Header
properties:
color: "#4338ca"
style:
paddingInline: 24px
color: white
blocks:
- id: layout_tailwind_header_text
type: Html
properties:
html: Tailwind-styled
Layout
- id: layout_tailwind_content
type: Content
class:
.element: bg-bg-layout
style:
padding: 24px
blocks:
- id: layout_tailwind_content_text
type: Paragraph
properties:
content: The Layout block has a single cssKey called "element". Use the class
property to apply Tailwind utility classes directly to the Layout
wrapper. Here the outer Layout uses rounded corners, shadow, and a
border. Child blocks like Header, Content, and Footer can each
have their own class applied.
- id: layout_tailwind_footer
type: Footer
class:
.element: bg-bg-layout text-center
blocks:
- id: layout_tailwind_footer_text
type: Paragraph
properties:
content: Footer with Tailwind background
```
This is where a data table or chart would display recent order information. The Layout block provides the overall page structure with a dark sidebar, top header, and scrollable content area.
Acme Corp Admin Panel - Version 3.2.1
```yaml
- id: layout_admin_outer
type: Layout
style:
minHeight: 450px
blocks:
- id: layout_admin_header
type: Header
properties:
notifications:
count: 5
profile:
avatar:
icon: user
style:
paddingInline: 24px
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: layout_admin_header_title
type: Html
layout:
flex: 0 0 auto
properties:
html: Acme Admin
- id: layout_admin_inner
type: Layout
properties:
hasSider: true
blocks:
- id: layout_admin_sider
type: Sider
layout:
flex: 0 0 auto
properties:
theme: dark
width: 220
breakpoint: lg
blocks:
- id: layout_admin_menu
type: Menu
properties:
mode: inline
theme: dark
links:
- id: layout_admin_menu_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: layout_admin_menu_users
type: MenuLink
properties:
title: Users
icon: users
- id: layout_admin_menu_orders
type: MenuLink
properties:
title: Orders
icon: ShoppingCart
- id: layout_admin_menu_reports
type: MenuLink
properties:
title: Reports
icon: chart
- id: layout_admin_menu_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: layout_admin_content_area
type: Content
layout:
flex: 1 1 auto
style:
padding: 24px
background: var(--ant-color-bg-layout)
blocks:
- id: layout_admin_breadcrumb
type: Breadcrumb
properties:
list:
- Home
- Dashboard
- id: layout_admin_stats_row
type: Box
layout:
gap: 16
blocks:
- id: layout_admin_stat_users
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: layout_admin_stat_users_val
type: Statistic
properties:
title: Total Users
value: 12480
- id: layout_admin_stat_orders
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: layout_admin_stat_orders_val
type: Statistic
properties:
title: Orders Today
value: 342
- id: layout_admin_stat_revenue
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: layout_admin_stat_revenue_val
type: Statistic
properties:
title: Revenue
value: 58200
prefix: $
- id: layout_admin_main_card
type: Card
properties:
title: Recent Orders
blocks:
- id: layout_admin_table_placeholder
type: Paragraph
properties:
content: This is where a data table or chart would display recent order
information. The Layout block provides the overall page
structure with a dark sidebar, top header, and scrollable
content area.
- id: layout_admin_footer
type: Footer
style:
textAlign: center
blocks:
- id: layout_admin_footer_text
type: Paragraph
properties:
content: Acme Corp Admin Panel - Version 3.2.1
```
DevDocs
Getting Started
Introduction
Welcome to DevDocs. This guide walks you through setting up your first project. The page uses a Layout with a light-themed Sider for documentation navigation, a white Header with logo and search, and a Content area with comfortable reading width.
> Tip
```yaml
- id: layout_docs_outer
type: Layout
style:
minHeight: 450px
blocks:
- id: layout_docs_header
type: Header
style:
paddingInline: 24px
borderBottom: 1px solid var(--ant-color-border)
background: var(--ant-color-bg-container)
blocks:
- id: layout_docs_logo
type: Title
layout:
flex: 0 0 auto
properties:
content: DevDocs
level: 4
style:
.element:
margin: 0
- id: layout_docs_version_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: v4.2
color: blue
- id: layout_docs_spacer
type: Box
layout:
flex: 1 1 0
- id: layout_docs_search_btn
type: Button
layout:
flex: 0 0 auto
properties:
icon: search
title: Search docs...
color: default
variant: outlined
- id: layout_docs_github_btn
type: Button
layout:
flex: 0 0 auto
properties:
icon: GitBranch
color: default
variant: text
hideTitle: true
- id: layout_docs_inner
type: Layout
properties:
hasSider: true
blocks:
- id: layout_docs_sider
type: Sider
layout:
flex: 0 0 auto
properties:
theme: light
width: 260
breakpoint: md
style:
borderRight: "1px solid #f0f0f0"
blocks:
- id: layout_docs_nav_title
type: Paragraph
style:
padding: 16px 24px 8px
fontWeight: 600
properties:
content: Getting Started
- id: layout_docs_nav_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: layout_docs_nav_intro
type: MenuLink
properties:
title: Introduction
icon: BookOpen
- id: layout_docs_nav_install
type: MenuLink
properties:
title: Installation
icon: download
- id: layout_docs_nav_config
type: MenuLink
properties:
title: Configuration
icon: Wrench
- id: layout_docs_nav_deploy
type: MenuLink
properties:
title: Deployment
icon: CloudUpload
- id: layout_docs_content_area
type: Content
layout:
flex: 1 1 auto
style:
padding: 32px 48px
background: var(--ant-color-bg-container)
blocks:
- id: layout_docs_content_breadcrumb
type: Breadcrumb
properties:
list:
- Docs
- Getting Started
- Introduction
- id: layout_docs_content_title
type: Title
properties:
content: Introduction
level: 2
- id: layout_docs_content_paragraph
type: Paragraph
properties:
content: Welcome to DevDocs. This guide walks you through setting up your first
project. The page uses a Layout with a light-themed Sider for
documentation navigation, a white Header with logo and search,
and a Content area with comfortable reading width.
- id: layout_docs_content_alert
type: Alert
properties:
type: info
message: Tip
description: The Layout block is the top-level structural container. Nest
Header, Content, Footer, and Sider blocks inside to build any
page structure.
showIcon: true
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `hasSider` | boolean | `false` | Lay the child blocks out in a row when the layout contains a Sider. |
| `theme` | object | - | Antd Layout design token overrides for this block. Header, Footer and Sider blocks inside the layout use them too. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design layout tokens](https://ant.design/components/layout#design-token). |
| `theme.bodyBg` | string | `"#f5f5f5"` | Background color of the layout. |
| `theme.headerHeight` | number | `64` | Height of Header blocks. |
| `theme.headerPadding` | string | `"0 50px"` | Padding of Header blocks. |
| `theme.headerColor` | string | `"rgba(0, 0, 0, 0.88)"` | Text color of Header blocks. |
| `theme.footerBg` | string | `"#f5f5f5"` | Background color of Footer blocks. |
| `theme.footerPadding` | string | `"24px 50px"` | Padding of Footer blocks. |
| `theme.triggerHeight` | number | `48` | Height of the collapse trigger of a collapsible Sider. |
| `theme.triggerBg` | string | `"#002140"` | Background color of the collapse trigger of a dark Sider. |
| `theme.triggerColor` | string | `"#fff"` | Color of the collapse trigger of a dark Sider. |
| `theme.lightTriggerBg` | string | `"#ffffff"` | Background color of the collapse trigger of a light Sider. |
| `theme.lightTriggerColor` | string | `"rgba(0, 0, 0, 0.88)"` | Color of the collapse trigger of a light Sider. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Layout element. |
| Slot | Description |
| --- | --- |
| `content` | Layout child blocks (Header, Sider, Content, Footer). |
---
url: https://docs.lowdefy.com/md/container-blocks/masonry.md
---
# Masonry
Masonry-style grid layout container.
+12.5% vs last month
Target is 5%. Campaigns are underperforming in APAC.
```yaml
- id: mas_3col
type: Masonry
properties:
columns: 3
gutter: 12
blocks:
- id: mas_3col_c1
type: Card
properties:
size: small
title: Revenue
blocks:
- id: mas_3col_c1_stat
type: Statistic
properties:
value: 128450
prefix: $
- id: mas_3col_c2
type: Card
properties:
size: small
title: Active Users
blocks:
- id: mas_3col_c2_stat
type: Statistic
properties:
value: 3842
- id: mas_3col_c2_p
type: Paragraph
properties:
content: +12.5% vs last month
- id: mas_3col_c3
type: Card
properties:
size: small
title: Uptime
blocks:
- id: mas_3col_c3_stat
type: Statistic
properties:
value: 99.97
suffix: "%"
- id: mas_3col_c4
type: Card
properties:
size: small
title: Top Region
blocks:
- id: mas_3col_c4_tags
type: Box
layout:
gap: 8
wrap: wrap
blocks:
- id: mas_3col_c4_t1
type: Tag
properties:
title: North America
color: blue
- id: mas_3col_c4_t2
type: Tag
properties:
title: Europe
color: green
- id: mas_3col_c4_t3
type: Tag
properties:
title: Asia Pacific
color: orange
- id: mas_3col_c5
type: Card
properties:
size: small
title: Conversion Rate
blocks:
- id: mas_3col_c5_stat
type: Statistic
properties:
value: 4.2
suffix: "%"
- id: mas_3col_c5_p1
type: Paragraph
properties:
content: Target is 5%. Campaigns are underperforming in APAC.
- id: mas_3col_c5_p2
type: Progress
properties:
percent: 84
```
> Deployment completed
> Disk usage at 85%
```yaml
- id: mas_2col
type: Masonry
properties:
columns: 2
gutter: 12
blocks:
- id: mas_2col_c1
type: Card
properties:
size: small
title: Notifications
blocks:
- id: mas_2col_c1_alert
type: Alert
properties:
type: success
showIcon: true
message: Deployment completed
- id: mas_2col_c1_alert2
type: Alert
properties:
type: warning
showIcon: true
message: Disk usage at 85%
- id: mas_2col_c2
type: Card
properties:
size: small
title: Quick Stats
blocks:
- id: mas_2col_c2_stat
type: Statistic
properties:
value: 1024
suffix: requests/s
```
Resize browser to see columns change at each breakpoint.
Stacks to a single column on small screens.
```yaml
- id: mas_resp
type: Masonry
properties:
columns:
xs: 1
sm: 2
md: 3
gutter: 12
blocks:
- id: mas_resp_c1
type: Card
properties:
size: small
title: xs:1 sm:2 md:3
blocks:
- id: mas_resp_c1_p
type: Paragraph
properties:
content: Resize browser to see columns change at each breakpoint.
- id: mas_resp_c2
type: Card
properties:
size: small
title: Responsive
blocks:
- id: mas_resp_c2_stat
type: Statistic
properties:
value: 3
suffix: breakpoints
- id: mas_resp_c3
type: Card
properties:
size: small
title: Mobile
blocks:
- id: mas_resp_c3_p
type: Paragraph
properties:
content: Stacks to a single column on small screens.
```
32px gap between items in both directions.
```yaml
- id: mas_gutter
type: Masonry
properties:
columns: 2
gutter: 32
blocks:
- id: mas_gutter_c1
type: Card
properties:
size: small
title: Spacious
blocks:
- id: mas_gutter_c1_p
type: Paragraph
properties:
content: 32px gap between items in both directions.
- id: mas_gutter_c2
type: Card
properties:
size: small
title: Airy Layout
blocks:
- id: mas_gutter_c2_stat
type: Statistic
properties:
value: 32
suffix: px
```
32px horizontal, 8px vertical. Compact rows, wide columns.
Notice the asymmetric spacing.
```yaml
- id: mas_hv
type: Masonry
properties:
columns: 2
gutter:
- 32
- 8
blocks:
- id: mas_hv_c1
type: Card
properties:
size: small
title: Wide Horizontal
blocks:
- id: mas_hv_c1_p
type: Paragraph
properties:
content: 32px horizontal, 8px vertical. Compact rows, wide columns.
- id: mas_hv_c2
type: Card
properties:
size: small
title: Tight Vertical
blocks:
- id: mas_hv_c2_stat
type: Statistic
properties:
value: 8
suffix: px vertical
- id: mas_hv_c3
type: Card
properties:
size: small
title: Third
blocks:
- id: mas_hv_c3_p
type: Paragraph
properties:
content: Notice the asymmetric spacing.
```
Theme tokens cascade to all child blocks within this Masonry.
```yaml
- id: mas_blue
type: Masonry
properties:
columns: 2
gutter: 12
theme:
colorBorderSecondary: "#adc6ff"
borderRadiusLG: 16
blocks:
- id: mas_blue_c1
type: Card
properties:
size: small
title: Themed Card
blocks:
- id: mas_blue_c1_p
type: Paragraph
properties:
content: Theme tokens cascade to all child blocks within this Masonry.
- id: mas_blue_c2
type: Card
properties:
size: small
title: Rounded Corners
blocks:
- id: mas_blue_c2_stat
type: Statistic
properties:
value: 16
suffix: px radius
```
Warm-toned cards using gold design tokens.
Text, borders, and backgrounds all harmonized.
```yaml
- id: mas_warm
type: Masonry
properties:
columns: 2
gutter: 12
theme:
colorBorderSecondary: "#ffd591"
colorTextHeading: "#d46b08"
colorText: "#874d00"
blocks:
- id: mas_warm_c1
type: Card
properties:
size: small
title: Orange Palette
blocks:
- id: mas_warm_c1_p
type: Paragraph
properties:
content: Warm-toned cards using gold design tokens.
- id: mas_warm_c2
type: Card
properties:
size: small
title: Consistent
blocks:
- id: mas_warm_c2_p
type: Paragraph
properties:
content: Text, borders, and backgrounds all harmonized.
```
Tailwind classes on the element CSS key style the Masonry wrapper.
White cards against gray create visual separation.
```yaml
- id: mas_tw
type: Masonry
class:
.element: bg-bg-layout p-6 rounded-xl
properties:
columns: 2
gutter: 12
blocks:
- id: mas_tw_c1
type: Card
properties:
size: small
title: Gray Background
blocks:
- id: mas_tw_c1_p
type: Paragraph
properties:
content: Tailwind classes on the element CSS key style the Masonry wrapper.
- id: mas_tw_c2
type: Card
properties:
size: small
title: Contrast
blocks:
- id: mas_tw_c2_p
type: Paragraph
properties:
content: White cards against gray create visual separation.
```
Resize browser to see slow item repositioning.
ease-in-out instead of the default cubic-bezier.
```yaml
- id: mas_motion
type: Masonry
properties:
columns: 2
gutter: 12
theme:
motionDurationSlow: 2s
motionDurationFast: 1s
motionEaseOut: ease-in-out
blocks:
- id: mas_motion_c1
type: Card
properties:
size: small
title: 2s Transitions
blocks:
- id: mas_motion_c1_p
type: Paragraph
properties:
content: Resize browser to see slow item repositioning.
- id: mas_motion_c2
type: Card
properties:
size: small
title: Custom Easing
blocks:
- id: mas_motion_c2_p
type: Paragraph
properties:
content: ease-in-out instead of the default cubic-bezier.
```
Mountain Sunrise
A stunning view of the morning light breaking over the peaks.
City at Night
Urban skyline illuminated by thousands of city lights reflecting off the river below.
Autumn Forest
Ocean Waves
Crashing waves along the rocky coastline during golden hour.
Desert Dunes
Rolling sand dunes stretching to the horizon under a clear blue sky. The patterns in the sand are shaped by the wind.
```yaml
- id: mas_gallery
type: Masonry
properties:
columns: 3
gutter: 12
blocks:
- id: mas_gallery_c1
type: Card
properties:
hoverable: true
size: small
slots:
cover:
blocks:
- id: mas_gallery_img1
type: Html
properties:
html:
blocks:
- id: mas_gallery_c1_title
type: Title
properties:
content: Mountain Sunrise
level: 5
- id: mas_gallery_c1_p
type: Paragraph
properties:
content: A stunning view of the morning light breaking over the peaks.
- id: mas_gallery_c1_tags
type: Box
layout:
gap: 8
blocks:
- id: mas_gallery_c1_t1
type: Tag
properties:
title: Nature
color: green
- id: mas_gallery_c1_t2
type: Tag
properties:
title: Featured
color: gold
- id: mas_gallery_c2
type: Card
properties:
hoverable: true
size: small
slots:
cover:
blocks:
- id: mas_gallery_img2
type: Html
properties:
html:
blocks:
- id: mas_gallery_c2_title
type: Title
properties:
content: City at Night
level: 5
- id: mas_gallery_c2_p
type: Paragraph
properties:
content: Urban skyline illuminated by thousands of city lights reflecting off
the river below.
- id: mas_gallery_c3
type: Card
properties:
hoverable: true
size: small
slots:
cover:
blocks:
- id: mas_gallery_img3
type: Html
properties:
html:
blocks:
- id: mas_gallery_c3_title
type: Title
properties:
content: Autumn Forest
level: 5
- id: mas_gallery_c4
type: Card
properties:
hoverable: true
size: small
slots:
cover:
blocks:
- id: mas_gallery_img4
type: Html
properties:
html:
blocks:
- id: mas_gallery_c4_title
type: Title
properties:
content: Ocean Waves
level: 5
- id: mas_gallery_c4_p
type: Paragraph
properties:
content: Crashing waves along the rocky coastline during golden hour.
- id: mas_gallery_c4_tags
type: Box
layout:
gap: 8
blocks:
- id: mas_gallery_c4_t1
type: Tag
properties:
title: Seascape
color: blue
- id: mas_gallery_c5
type: Card
properties:
hoverable: true
size: small
slots:
cover:
blocks:
- id: mas_gallery_img5
type: Html
properties:
html:
blocks:
- id: mas_gallery_c5_title
type: Title
properties:
content: Desert Dunes
level: 5
- id: mas_gallery_c5_p
type: Paragraph
properties:
content: Rolling sand dunes stretching to the horizon under a clear blue sky.
The patterns in the sand are shaped by the wind.
```
Sarah Chen
Lead Designer
Marcus Johnson
Senior Backend Engineer
Priya Patel
Product Manager
```yaml
- id: mas_team
type: Masonry
properties:
columns:
xs: 1
sm: 2
lg: 3
gutter: 16
blocks:
- id: mas_team_c1
type: Card
properties:
size: small
hoverable: true
blocks:
- id: mas_team_c1_row
type: Box
layout:
gap: 12
align: center
blocks:
- id: mas_team_c1_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 48
color: "#1677ff"
- id: mas_team_c1_info
type: Box
layout:
flex: 1 1 0
direction: column
gap: 2
blocks:
- id: mas_team_c1_name
type: Title
properties:
content: Sarah Chen
level: 5
- id: mas_team_c1_role
type: Paragraph
properties:
content: Lead Designer
- id: mas_team_c1_divider
type: Divider
- id: mas_team_c1_desc
type: Descriptions
properties:
size: small
column: 1
items:
- label: Email
value: sarah.chen@example.com
- label: Location
value: San Francisco, CA
- label: Team
value: Design Systems
- id: mas_team_c1_btn
type: Button
properties:
title: View Profile
color: primary
variant: outlined
block: true
size: small
events:
onClick:
- id: mas_team_c1_msg
type: DisplayMessage
params:
content: Viewing Sarah Chen's profile
status: info
- id: mas_team_c2
type: Card
properties:
size: small
hoverable: true
blocks:
- id: mas_team_c2_row
type: Box
layout:
gap: 12
align: center
blocks:
- id: mas_team_c2_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 48
color: "#52c41a"
- id: mas_team_c2_info
type: Box
layout:
flex: 1 1 0
direction: column
gap: 2
blocks:
- id: mas_team_c2_name
type: Title
properties:
content: Marcus Johnson
level: 5
- id: mas_team_c2_role
type: Paragraph
properties:
content: Senior Backend Engineer
- id: mas_team_c2_divider
type: Divider
- id: mas_team_c2_desc
type: Descriptions
properties:
size: small
column: 1
items:
- label: Email
value: marcus.j@example.com
- label: Location
value: Austin, TX
- id: mas_team_c2_btn
type: Button
properties:
title: View Profile
color: primary
variant: outlined
block: true
size: small
events:
onClick:
- id: mas_team_c2_msg
type: DisplayMessage
params:
content: Viewing Marcus Johnson's profile
status: info
- id: mas_team_c3
type: Card
properties:
size: small
hoverable: true
blocks:
- id: mas_team_c3_row
type: Box
layout:
gap: 12
align: center
blocks:
- id: mas_team_c3_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 48
color: "#722ed1"
- id: mas_team_c3_info
type: Box
layout:
flex: 1 1 0
direction: column
gap: 2
blocks:
- id: mas_team_c3_name
type: Title
properties:
content: Priya Patel
level: 5
- id: mas_team_c3_role
type: Paragraph
properties:
content: Product Manager
- id: mas_team_c3_divider
type: Divider
- id: mas_team_c3_desc
type: Descriptions
properties:
size: small
column: 1
items:
- label: Email
value: priya.p@example.com
- label: Location
value: London, UK
- label: Team
value: Product
- label: Projects
value: 12 active
- id: mas_team_c3_btn
type: Button
properties:
title: View Profile
color: primary
variant: outlined
block: true
size: small
events:
onClick:
- id: mas_team_c3_msg
type: DisplayMessage
params:
content: Viewing Priya Patel's profile
status: info
```
Wireless Headphones
Leather Notebook
Ceramic Mug Set
Handcrafted set of 4 ceramic mugs in earth-tone glazes. Dishwasher and microwave safe.
Desk Lamp
```yaml
- id: mas_products
type: Masonry
class:
.element: bg-bg-layout p-6 rounded-xl
properties:
columns:
xs: 1
sm: 2
md: 3
lg: 4
gutter: 16
blocks:
- id: mas_prod_c1
type: Card
properties:
hoverable: true
size: small
slots:
cover:
blocks:
- id: mas_prod_img1
type: Html
properties:
html:
blocks:
- id: mas_prod_c1_name
type: Title
properties:
content: Wireless Headphones
level: 5
- id: mas_prod_c1_price
type: Statistic
properties:
value: 79.99
prefix: $
- id: mas_prod_c1_tags
type: Box
layout:
gap: 8
blocks:
- id: mas_prod_c1_t1
type: Tag
properties:
title: Electronics
color: blue
- id: mas_prod_c1_t2
type: Tag
properties:
title: Best Seller
color: red
- id: mas_prod_c1_btn
type: Button
properties:
title: Add to Cart
color: primary
variant: solid
block: true
size: small
icon: ShoppingCart
events:
onClick:
- id: mas_prod_c1_add
type: DisplayMessage
params:
content: Wireless Headphones added to cart
status: success
- id: mas_prod_c2
type: Card
properties:
hoverable: true
size: small
slots:
cover:
blocks:
- id: mas_prod_img2
type: Html
properties:
html:
blocks:
- id: mas_prod_c2_name
type: Title
properties:
content: Leather Notebook
level: 5
- id: mas_prod_c2_price
type: Statistic
properties:
value: 24.5
prefix: $
- id: mas_prod_c2_btn
type: Button
properties:
title: Add to Cart
color: primary
variant: solid
block: true
size: small
icon: ShoppingCart
events:
onClick:
- id: mas_prod_c2_add
type: DisplayMessage
params:
content: Leather Notebook added to cart
status: success
- id: mas_prod_c3
type: Card
properties:
hoverable: true
size: small
slots:
cover:
blocks:
- id: mas_prod_img3
type: Html
properties:
html:
blocks:
- id: mas_prod_c3_name
type: Title
properties:
content: Ceramic Mug Set
level: 5
- id: mas_prod_c3_desc
type: Paragraph
properties:
content: Handcrafted set of 4 ceramic mugs in earth-tone glazes. Dishwasher and
microwave safe.
- id: mas_prod_c3_price
type: Statistic
properties:
value: 45
prefix: $
- id: mas_prod_c3_tags
type: Box
layout:
gap: 8
blocks:
- id: mas_prod_c3_t1
type: Tag
properties:
title: Home
color: orange
- id: mas_prod_c3_t2
type: Tag
properties:
title: New
color: green
- id: mas_prod_c3_btn
type: Button
properties:
title: Add to Cart
color: primary
variant: solid
block: true
size: small
icon: ShoppingCart
events:
onClick:
- id: mas_prod_c3_add
type: DisplayMessage
params:
content: Ceramic Mug Set added to cart
status: success
- id: mas_prod_c4
type: Card
properties:
hoverable: true
size: small
slots:
cover:
blocks:
- id: mas_prod_img4
type: Html
properties:
html:
blocks:
- id: mas_prod_c4_name
type: Title
properties:
content: Desk Lamp
level: 5
- id: mas_prod_c4_price
type: Statistic
properties:
value: 59.99
prefix: $
- id: mas_prod_c4_btn
type: Button
properties:
title: Add to Cart
color: primary
variant: solid
block: true
size: small
icon: ShoppingCart
events:
onClick:
- id: mas_prod_c4_add
type: DisplayMessage
params:
content: Desk Lamp added to cart
status: success
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `columns` | integer \| object | `3` | Number of columns, or responsive breakpoint object (e.g. { xs: 1, sm: 2, md: 3 }). |
| `fresh` | boolean | `false` | Keep watching the size of each item and re-layout when it changes, for items whose height changes after they render (images loading, expanding content). |
| `gutter` | number \| array \| object | `0` | Gap between items in pixels. A number, a responsive breakpoint object (e.g. { xs: 8, md: 16 }), or a [horizontal, vertical] array of either. |
| `sequential` | boolean | `false` | Has no effect: antd Masonry always places each item in the shortest column. Kept so existing configs stay valid. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design masonry tokens](https://ant.design/components/masonry#design-token). |
| `theme.motionDurationSlow` | string | `"0.3s"` | Duration for item position transitions and appear animations. |
| `theme.motionDurationFast` | string | `"0.1s"` | Duration for item leave animations. |
| `theme.motionEaseOut` | string | `"cubic-bezier(0.215, 0.61, 0.355, 1)"` | Easing function for item transitions. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Masonry element. |
| `/item` | Each item in the masonry grid. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks arranged in a masonry grid. |
---
url: https://docs.lowdefy.com/md/container-blocks/mobilemenu.md
---
# MobileMenu
Responsive mobile navigation menu with drawer.
```yaml
- id: basic_simple
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: bs_home
type: MenuLink
properties:
title: Home
- id: bs_about
type: MenuLink
properties:
title: About
- id: bs_contact
type: MenuLink
properties:
title: Contact
- id: basic_icons
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: bi_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: bi_users
type: MenuLink
properties:
title: Users
icon: user
- id: bi_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: basic_page_links
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: bpl_docs
type: MenuLink
pageId: docs
properties:
title: Documentation
icon: document
- id: bpl_api
type: MenuLink
pageId: api-reference
properties:
title: API Reference
icon: Plug
- id: bpl_changelog
type: MenuLink
pageId: changelog
properties:
title: Changelog
icon: history
```
```yaml
- id: groups_single
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: gs_overview
type: MenuLink
properties:
title: Overview
icon: home
- id: gs_management
type: MenuGroup
properties:
title: Management
icon: grid
links:
- id: gs_projects
type: MenuLink
properties:
title: Projects
- id: gs_tasks
type: MenuLink
properties:
title: Tasks
- id: groups_nested
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: gn_content
type: MenuGroup
properties:
title: Content
icon: document
links:
- id: gn_posts
type: MenuLink
properties:
title: Posts
- id: gn_pages
type: MenuLink
properties:
title: Pages
- id: gn_users
type: MenuGroup
properties:
title: Users
icon: users
links:
- id: gn_all
type: MenuLink
properties:
title: All Users
- id: gn_roles
type: MenuLink
properties:
title: Roles
- id: groups_deep
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: gd_products
type: MenuGroup
properties:
title: Products
icon: Store
links:
- id: gd_electronics
type: MenuGroup
properties:
title: Electronics
links:
- id: gd_phones
type: MenuLink
properties:
title: Phones
- id: gd_laptops
type: MenuLink
properties:
title: Laptops
```
```yaml
- id: divider_basic
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: db_home
type: MenuLink
properties:
title: Home
icon: home
- id: db_divider
type: MenuDivider
- id: db_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: divider_dashed
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: dd_profile
type: MenuLink
properties:
title: Profile
icon: user
- id: dd_divider
type: MenuDivider
properties:
dashed: true
- id: dd_help
type: MenuLink
properties:
title: Help Center
icon: help
- id: divider_danger
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: dg_account
type: MenuLink
properties:
title: Account
icon: user
- id: dg_divider
type: MenuDivider
- id: dg_delete
type: MenuLink
properties:
title: Delete Account
icon: delete
danger: true
- id: dg_logout
type: MenuLink
properties:
title: Sign Out
icon: logout
danger: true
```
```yaml
- id: theme_light
type: MobileMenu
layout:
flex: 0 0 auto
properties:
theme: light
links:
- id: tl_home
type: MenuLink
properties:
title: Home
icon: home
- id: tl_explore
type: MenuLink
properties:
title: Explore
icon: Compass
- id: tl_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: theme_dark
type: MobileMenu
layout:
flex: 0 0 auto
properties:
theme: dark
links:
- id: td_home
type: MenuLink
properties:
title: Home
icon: home
- id: td_explore
type: MenuLink
properties:
title: Explore
icon: Compass
- id: td_settings
type: MenuLink
properties:
title: Settings
icon: settings
```
```yaml
- id: selected_single
type: MobileMenu
layout:
flex: 0 0 auto
properties:
selectedKeys:
- sk_users
links:
- id: sk_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: sk_users
type: MenuLink
properties:
title: Users
icon: user
- id: sk_reports
type: MenuLink
properties:
title: Reports
icon: chart
- id: selected_multiple
type: MobileMenu
layout:
flex: 0 0 auto
properties:
selectedKeys:
- sm_inbox
- sm_sent
links:
- id: sm_inbox
type: MenuLink
properties:
title: Inbox
icon: Inbox
- id: sm_sent
type: MenuLink
properties:
title: Sent
icon: send
- id: sm_drafts
type: MenuLink
properties:
title: Drafts
icon: edit
- id: selected_in_group
type: MobileMenu
layout:
flex: 0 0 auto
properties:
selectedKeys:
- sig_tasks
links:
- id: sig_overview
type: MenuLink
properties:
title: Overview
icon: home
- id: sig_project
type: MenuGroup
properties:
title: Project
icon: SquareKanban
links:
- id: sig_tasks
type: MenuLink
properties:
title: Tasks
- id: sig_timeline
type: MenuLink
properties:
title: Timeline
```
```yaml
- id: toggle_default_type
type: MobileMenu
layout:
flex: 0 0 auto
properties:
toggleMenuButton:
type: default
icon: menu
links:
- id: tdt_home
type: MenuLink
properties:
title: Home
- id: tdt_about
type: MenuLink
properties:
title: About
- id: toggle_text_variant
type: MobileMenu
layout:
flex: 0 0 auto
properties:
toggleMenuButton:
type: text
icon: list
links:
- id: ttv_home
type: MenuLink
properties:
title: Home
- id: ttv_about
type: MenuLink
properties:
title: About
- id: toggle_danger_style
type: MobileMenu
layout:
flex: 0 0 auto
properties:
toggleMenuButton:
type: primary
icon: menu
danger: true
links:
- id: tds_home
type: MenuLink
properties:
title: Home
- id: tds_about
type: MenuLink
properties:
title: About
```
```yaml
- id: drawer_titled
type: MobileMenu
layout:
flex: 0 0 auto
properties:
drawer:
title: Navigation
width: 280
links:
- id: dt_home
type: MenuLink
properties:
title: Home
icon: home
- id: dt_profile
type: MenuLink
properties:
title: Profile
icon: user
- id: drawer_left
type: MobileMenu
layout:
flex: 0 0 auto
properties:
drawer:
title: Menu
placement: left
width: 240
links:
- id: dl_home
type: MenuLink
properties:
title: Home
icon: home
- id: dl_search
type: MenuLink
properties:
title: Search
icon: search
- id: drawer_wide
type: MobileMenu
layout:
flex: 0 0 auto
properties:
drawer:
title: Browse
width: 360
closable: true
mask: true
maskClosable: true
links:
- id: dw_categories
type: MenuGroup
properties:
title: Categories
icon: grid
links:
- id: dw_electronics
type: MenuLink
properties:
title: Electronics
- id: dw_clothing
type: MenuLink
properties:
title: Clothing
```
```yaml
- id: delay_fast
type: MobileMenu
layout:
flex: 0 0 auto
properties:
subMenuOpenDelay: 0
subMenuCloseDelay: 0
links:
- id: df_tools
type: MenuGroup
properties:
title: Tools
icon: Wrench
links:
- id: df_editor
type: MenuLink
properties:
title: Editor
- id: df_terminal
type: MenuLink
properties:
title: Terminal
- id: delay_slow
type: MobileMenu
layout:
flex: 0 0 auto
properties:
subMenuOpenDelay: 0.5
subMenuCloseDelay: 1
links:
- id: ds_tools
type: MenuGroup
properties:
title: Tools
icon: Wrench
links:
- id: ds_editor
type: MenuLink
properties:
title: Editor
- id: ds_terminal
type: MenuLink
properties:
title: Terminal
```
```yaml
- id: events_toggle
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: et_home
type: MenuLink
properties:
title: Home
icon: home
- id: et_about
type: MenuLink
properties:
title: About
icon: info
events:
onToggleDrawer:
- id: toggle_msg
type: DisplayMessage
params:
content: Drawer toggled
status: info
- id: events_open_close
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: eoc_home
type: MenuLink
properties:
title: Home
icon: home
- id: eoc_profile
type: MenuLink
properties:
title: Profile
icon: user
events:
onOpen:
- id: open_msg
type: DisplayMessage
params:
content: Menu opened
status: success
onClose:
- id: close_msg
type: DisplayMessage
params:
content: Menu closed
status: warning
- id: events_item_click
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: eic_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: eic_reports
type: MenuLink
properties:
title: Reports
icon: chart
events:
onMenuItemClick:
- id: click_msg
type: DisplayMessage
params:
content: Menu item clicked
status: info
onMenuItemSelect:
- id: select_msg
type: DisplayMessage
params:
content: Menu item selected
status: success
- id: events_group_toggle
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: egt_tools
type: MenuGroup
properties:
title: Tools
icon: Wrench
links:
- id: egt_editor
type: MenuLink
properties:
title: Editor
- id: egt_terminal
type: MenuLink
properties:
title: Terminal
events:
onToggleMenuGroup:
- id: group_toggle_msg
type: DisplayMessage
params:
content: Menu group toggled
status: info
```
```yaml
- id: link_style_custom
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: lsc_featured
type: MenuLink
style:
fontWeight: bold
color: "#1677ff"
properties:
title: Featured
icon: star
- id: lsc_regular
type: MenuLink
properties:
title: Regular Item
icon: file
- id: lsc_muted
type: MenuLink
style:
opacity: 0.6
fontStyle: italic
properties:
title: Archived
icon: folder
- id: link_style_icon_object
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: lsi_alert
type: MenuLink
properties:
title: Alerts
icon:
name: bell
color: "#faad14"
- id: lsi_success
type: MenuLink
properties:
title: Completed
icon:
name: check-circle
color: "#52c41a"
- id: lsi_error
type: MenuLink
properties:
title: Errors
icon:
name: close-circle
color: "#ff4d4f"
```
```yaml
- id: css_tailwind_shadow
type: MobileMenu
layout:
flex: 0 0 auto
class: shadow-md rounded-lg
properties:
links:
- id: cts_home
type: MenuLink
properties:
title: Home
icon: home
- id: cts_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: css_tailwind_bg
type: MobileMenu
layout:
flex: 0 0 auto
class: bg-bg-layout p-1 rounded-md
properties:
links:
- id: ctb_home
type: MenuLink
properties:
title: Home
icon: home
- id: ctb_explore
type: MenuLink
properties:
title: Explore
icon: Compass
- id: css_inline_style
type: MobileMenu
layout:
flex: 0 0 auto
style:
.element:
padding: 4px
borderRadius: 8
border: "1px solid #d6e4ff"
properties:
links:
- id: cis_home
type: MenuLink
properties:
title: Home
icon: home
- id: cis_help
type: MenuLink
properties:
title: Help
icon: help
- id: css_dark_context
type: Box
class: bg-gradient-to-r from-slate-900 to-slate-700 p-4 rounded-lg
layout:
gap: 8
blocks:
- id: css_on_dark
type: MobileMenu
layout:
flex: 0 0 auto
properties:
theme: dark
toggleMenuButton:
type: primary
ghost: true
icon: menu
links:
- id: cod_home
type: MenuLink
properties:
title: Home
icon: home
- id: cod_settings
type: MenuLink
properties:
title: Settings
icon: settings
```
```yaml
- id: mobile_shortcut
type: MobileMenu
layout:
flex: 0 0 auto
properties:
drawer:
title: Navigation
links:
- id: ms_home
type: MenuLink
properties:
title: Home
icon: home
shortcut: mod+1
- id: ms_search
type: MenuLink
properties:
title: Search
icon: search
shortcut: mod+k
- id: ms_settings
type: MenuLink
properties:
title: Settings
icon: settings
shortcut: mod+,
```
```yaml
- id: mm_logo_example
type: MobileMenu
layout:
flex: 0 0 auto
properties:
logo:
src: logo-square-dark-theme.png
alt: Lowdefy
style:
width: 60
links:
- id: ml_home
type: MenuLink
properties:
title: Home
icon: home
- id: ml_settings
type: MenuLink
properties:
title: Settings
icon: settings
```
Content above the menu items.
```yaml
- id: mm_drawer_header_example
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: mdh_home
type: MenuLink
properties:
title: Home
- id: mdh_about
type: MenuLink
properties:
title: About
slots:
drawerHeader:
blocks:
- id: mdh_workspace
type: Paragraph
properties:
content: Content above the menu items.
style:
.element:
padding: 0 24px
margin: 0
fontWeight: 600
```
Additional content below the menu items.
```yaml
- id: mm_drawer_content_example
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: mdc_home
type: MenuLink
properties:
title: Home
- id: mdc_about
type: MenuLink
properties:
title: About
slots:
drawerContent:
blocks:
- id: mdc_extra
type: Paragraph
properties:
content: Additional content below the menu items.
style:
.element:
padding: 16px
color: "#999"
```
App v2.1.0
```yaml
- id: mm_drawer_footer_example
type: MobileMenu
layout:
flex: 0 0 auto
properties:
links:
- id: mdf_home
type: MenuLink
properties:
title: Home
slots:
drawerFooter:
blocks:
- id: mdf_footer
type: Paragraph
properties:
content: App v2.1.0
style:
.element:
textAlign: center
margin: 0
color: "#aaa"
fontSize: 12
```
**Admin Panel**
You have **12** new orders, **3** pending reviews, and **5** unread messages.
Use the navigation menu to manage your application.
```yaml
- id: admin_header
type: Box
class: bg-bg-container border-b border-border px-4 py-3
layout:
direction: row
align: center
justify: space-between
blocks:
- id: admin_left
type: Box
layout:
direction: row
align: center
gap: 12
flex: 0 0 auto
blocks:
- id: admin_nav
type: MobileMenu
layout:
flex: 0 0 auto
properties:
toggleMenuButton:
type: text
icon: menu
drawer:
title: Admin Panel
width: 280
links:
- id: an_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: an_content
type: MenuGroup
properties:
title: Content
icon: document
links:
- id: an_posts
type: MenuLink
properties:
title: Posts
- id: an_media
type: MenuLink
properties:
title: Media Library
- id: an_users
type: MenuGroup
properties:
title: Users
icon: users
links:
- id: an_all_users
type: MenuLink
properties:
title: All Users
- id: an_roles
type: MenuLink
properties:
title: Roles
- id: an_divider
type: MenuDivider
- id: an_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: an_divider2
type: MenuDivider
properties:
dashed: true
- id: an_logout
type: MenuLink
properties:
title: Sign Out
icon: logout
danger: true
events:
onMenuItemClick:
- id: admin_click_msg
type: DisplayMessage
params:
content: Navigating...
status: info
- id: admin_title
type: Markdown
layout:
flex: 0 0 auto
properties:
content: "**Admin Panel**"
- id: admin_actions
type: Box
layout:
direction: row
align: center
gap: 8
flex: 0 0 auto
blocks:
- id: admin_bell
type: Button
layout:
flex: 0 0 auto
properties:
icon: bell
hideTitle: true
variant: text
color: default
- id: admin_avatar
type: Button
layout:
flex: 0 0 auto
properties:
icon: user
hideTitle: true
shape: circle
variant: filled
color: primary
- id: admin_body
type: Card
properties:
title: Welcome Back
size: small
blocks:
- id: admin_stats
type: Markdown
properties:
content: >
You have **12** new orders, **3** pending reviews, and **5** unread
messages.
Use the navigation menu to manage your application.
```
**ShopNow**
Browse our latest collection across all categories.
**Free shipping** on orders over $50. Use the menu to explore departments.
```yaml
- id: shop_header
type: Box
class: bg-gradient-to-r from-indigo-600 to-purple-600 px-4 py-3
layout:
direction: row
align: center
justify: space-between
blocks:
- id: shop_left
type: Box
layout:
direction: row
align: center
gap: 12
flex: 0 0 auto
blocks:
- id: shop_nav
type: MobileMenu
layout:
flex: 0 0 auto
properties:
toggleMenuButton:
type: primary
ghost: true
icon: menu
drawer:
title: Shop Categories
width: 300
theme: light
selectedKeys:
- sn_clothing
links:
- id: sn_home
type: MenuLink
url: /
properties:
title: Home
icon: home
- id: sn_divider_top
type: MenuDivider
- id: sn_clothing
type: MenuGroup
properties:
title: Clothing
icon: Shirt
links:
- id: sn_mens
type: MenuLink
properties:
title: Men's Wear
- id: sn_womens
type: MenuLink
properties:
title: Women's Wear
- id: sn_kids
type: MenuLink
properties:
title: Kids
- id: sn_electronics
type: MenuGroup
properties:
title: Electronics
icon: Laptop
links:
- id: sn_phones
type: MenuLink
properties:
title: Phones & Tablets
- id: sn_computers
type: MenuLink
properties:
title: Computers
- id: sn_divider_bottom
type: MenuDivider
properties:
dashed: true
- id: sn_deals
type: MenuLink
properties:
title: Today's Deals
icon: Zap
- id: sn_orders
type: MenuLink
pageId: orders
properties:
title: My Orders
icon: ShoppingCart
events:
onMenuItemSelect:
- id: shop_select_msg
type: DisplayMessage
params:
content: Loading category...
status: info
onToggleDrawer:
- id: shop_toggle_state
type: SetState
params:
menuOpen:
_not:
_state: menuOpen
- id: shop_brand
type: Markdown
layout:
flex: 0 0 auto
style:
.element:
color: white
properties:
content: "**ShopNow**"
- id: shop_right
type: Box
layout:
direction: row
align: center
gap: 8
flex: 0 0 auto
blocks:
- id: shop_search
type: Button
layout:
flex: 0 0 auto
properties:
icon: search
hideTitle: true
variant: text
ghost: true
color: default
- id: shop_cart
type: Button
layout:
flex: 0 0 auto
properties:
icon: ShoppingCart
hideTitle: true
variant: text
ghost: true
color: default
- id: shop_content
type: Card
properties:
title: Featured Products
size: small
blocks:
- id: shop_desc
type: Markdown
properties:
content: >
Browse our latest collection across all categories.
**Free shipping** on orders over $50. Use the menu to explore
departments.
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `toggleMenuButton` | object | - | Toggle menu button properties. |
| `drawer` | object | - | Menu drawer properties. |
| `logo` | object | - | Logo settings for the mobile menu drawer header. |
| `logo.src` | string | - | Logo source url. |
| `logo.srcMobile` | string | - | Mobile logo source url. |
| `logo.alt` | string | `"Lowdefy"` | Logo alternative text. |
| `logo.style` | object | - | Css style object to apply to logo. |
| `menuId` | string | - | App menu id used to get menu links. |
| `selectedKeys` | array | - | Array with the keys of currently selected menu items. |
| `subMenuCloseDelay` | number | - | Delay time to hide submenu when mouse leaves (in seconds). |
| `subMenuOpenDelay` | number | - | Delay time to show submenu when mouse enters (in seconds). |
| `theme` | string | `"light"` | Color theme of menu. Enum: `dark`, `light`. |
| `links` | array | - | |
| `links.$.id` | string | - | Menu item id. |
| `links.$.type` | string | `"MenuLink"` | Menu item type. Enum: `MenuDivider`, `MenuLink`, `MenuGroup`. |
| `links.$.pageId` | string | - | Page to link to. |
| `links.$.style` | object | - | Css style to applied to link. |
| `links.$.properties` | object | - | properties from menu item. |
| `links.$.properties.title` | string | - | Menu item title. |
| `links.$.properties.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize icon on menu item. |
| `links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `links.$.properties.icon.color` | string | - | Icon color. |
| `links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `links.$.properties.danger` | boolean | `false` | Apply danger style to menu item. |
| `links.$.properties.dashed` | boolean | `false` | Whether the divider line is dashed. |
| `links.$.links` | array | - | |
| `links.$.links.$.id` | string | - | Menu item id. |
| `links.$.links.$.type` | string | `"MenuLink"` | Menu item type. Enum: `MenuDivider`, `MenuLink`, `MenuGroup`. |
| `links.$.links.$.style` | object | - | Css style to applied to sub-link. |
| `links.$.links.$.pageId` | string | - | Page to link to. |
| `links.$.links.$.properties` | object | - | properties from menu item. |
| `links.$.links.$.properties.title` | string | - | Menu item title. |
| `links.$.links.$.properties.danger` | boolean | `false` | Apply danger style to menu item. |
| `links.$.links.$.properties.dashed` | boolean | `false` | Whether the divider line is dashed. |
| `links.$.links.$.links` | array | - | |
| `links.$.links.$.links.$.id` | string | - | Menu item id. |
| `links.$.links.$.links.$.type` | string | `"MenuLink"` | Menu item type. Enum: `MenuDivider`, `MenuLink`. |
| `links.$.links.$.links.$.style` | object | - | Css style to applied to sub-link. |
| `links.$.links.$.links.$.pageId` | string | - | Page to link to. |
| `links.$.links.$.links.$.properties` | object | - | properties from menu item. |
| `links.$.links.$.links.$.properties.title` | string | - | Menu item title. |
| `links.$.links.$.links.$.properties.danger` | boolean | `false` | Apply danger style to menu item. |
| `links.$.links.$.links.$.properties.dashed` | boolean | `false` | Whether the divider line is dashed. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onToggleDrawer` | \- | Trigger action when mobile menu drawer is toggled. |
| `onClose` | \- | Trigger action when mobile menu is closed. |
| `onOpen` | \- | Trigger action when mobile menu is opened. |
| `onMenuItemSelect` | \- | Trigger action when menu item is selected. |
| `onMenuItemClick` | \- | Trigger action when menu item is clicked. |
| `onToggleMenuGroup` | \- | Trigger action when mobile menu group is opened. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The MobileMenu element. |
| Slot | Description |
| --- | --- |
| `drawerHeader` | Content above the menu in the drawer. |
| `drawerContent` | Additional content below the menu in the drawer. |
| `drawerFooter` | Footer content in the drawer. |
---
url: https://docs.lowdefy.com/md/container-blocks/modal.md
---
# Modal
Modal dialog overlay for focused content. Add `shortcut: Escape` to the `onClose` event to run custom actions when Escape is pressed. Ant Design's Modal already closes on Escape by default — the shortcut triggers your custom actions in addition to the built-in close.
This is a basic modal dialog with a title, content area, and default Ok/Cancel buttons.
Click Ok to confirm or Cancel to dismiss.
```yaml
- id: modal_basic_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal
color: primary
variant: solid
events:
onClick:
- id: modal_basic_open
type: CallMethod
params:
blockId: modal_basic
method: setOpen
args:
- open: true
- id: modal_basic
type: Modal
properties:
title: Basic Modal
blocks:
- id: modal_basic_p1
type: Paragraph
properties:
content: This is a basic modal dialog with a title, content area, and default
Ok/Cancel buttons.
- id: modal_basic_p2
type: Paragraph
properties:
content: Click Ok to confirm or Cancel to dismiss.
```
The modal title supports HTML markup for rich text formatting.
```yaml
- id: modal_html_title_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal with HTML Title
color: primary
variant: outlined
events:
onClick:
- id: modal_html_title_open
type: CallMethod
params:
blockId: modal_html_title
method: setOpen
args:
- open: true
- id: modal_html_title
type: Modal
properties:
title: Bold and italic title
blocks:
- id: modal_html_title_content
type: Paragraph
properties:
content: The modal title supports HTML markup for rich text formatting.
```
```yaml
- id: modal_padding_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal with padding none
events:
onClick:
- id: modal_padding_open
type: CallMethod
params:
blockId: modal_padding
method: setOpen
args:
- open: true
- id: modal_padding
type: Modal
properties:
title: Recent invoices
padding: none
blocks:
- id: modal_padding_rows
type: Html
properties:
html: >
INV-1042 $1,280.00
INV-1041 $640.00
INV-1040 $2,115.50
INV-1039 $96.00
```
The okText and cancelText properties customize the footer button labels. This modal uses "Save Changes" and "Discard" instead of "Ok" and "Cancel".
```yaml
- id: modal_btn_text_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal
color: primary
variant: outlined
events:
onClick:
- id: modal_btn_text_open
type: CallMethod
params:
blockId: modal_btn_text
method: setOpen
args:
- open: true
- id: modal_btn_text
type: Modal
properties:
title: Custom Button Text
okText: Save Changes
cancelText: Discard
blocks:
- id: modal_btn_text_content
type: Paragraph
properties:
content: The okText and cancelText properties customize the footer button
labels. This modal uses "Save Changes" and "Discard" instead of "Ok"
and "Cancel".
```
Custom button props allow fine-grained control over the footer buttons. Here the Ok button is styled as a danger button, and the Cancel button uses primary styling.
```yaml
- id: modal_btn_props_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal with Custom Buttons
color: primary
variant: outlined
events:
onClick:
- id: modal_btn_props_open
type: CallMethod
params:
blockId: modal_btn_props
method: setOpen
args:
- open: true
- id: modal_btn_props
type: Modal
properties:
title: Danger Confirmation
okText: Delete
cancelText: Keep
okButtonProps:
danger: true
cancelButtonProps:
type: primary
blocks:
- id: modal_btn_props_content
type: Paragraph
properties:
content: Custom button props allow fine-grained control over the footer buttons.
Here the Ok button is styled as a danger button, and the Cancel button
uses primary styling.
```
This modal is vertically centered in the viewport. By default, modals appear near the top of the page.
```yaml
- id: modal_centered_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Centered Modal
color: primary
variant: outlined
events:
onClick:
- id: modal_centered_open
type: CallMethod
params:
blockId: modal_centered
method: setOpen
args:
- open: true
- id: modal_centered
type: Modal
properties:
title: Centered Modal
centered: true
blocks:
- id: modal_centered_content
type: Paragraph
properties:
content: This modal is vertically centered in the viewport. By default, modals
appear near the top of the page.
```
A compact 300px modal, suitable for simple confirmations.
An 800px wide modal with more room for complex content like forms, tables, or detail views.
Using a percentage width makes the modal responsive, taking up 80% of the viewport width.
```yaml
- id: modal_narrow_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Narrow (300px)
color: primary
variant: outlined
size: small
events:
onClick:
- id: modal_narrow_open
type: CallMethod
params:
blockId: modal_narrow
method: setOpen
args:
- open: true
- id: modal_wide_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Wide (800px)
color: primary
variant: outlined
size: small
events:
onClick:
- id: modal_wide_open
type: CallMethod
params:
blockId: modal_wide
method: setOpen
args:
- open: true
- id: modal_pct_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Percentage (80%)
color: primary
variant: outlined
size: small
events:
onClick:
- id: modal_pct_open
type: CallMethod
params:
blockId: modal_pct
method: setOpen
args:
- open: true
- id: modal_narrow
type: Modal
properties:
title: Narrow Modal
width: 300
blocks:
- id: modal_narrow_content
type: Paragraph
properties:
content: A compact 300px modal, suitable for simple confirmations.
- id: modal_wide
type: Modal
properties:
title: Wide Modal
width: 800
blocks:
- id: modal_wide_content
type: Paragraph
properties:
content: An 800px wide modal with more room for complex content like forms,
tables, or detail views.
- id: modal_pct
type: Modal
properties:
title: 80% Width Modal
width: 80%
blocks:
- id: modal_pct_content
type: Paragraph
properties:
content: Using a percentage width makes the modal responsive, taking up 80% of
the viewport width.
```
The close button is visible in the top right corner. This is the default behavior.
The close (x) button is hidden. Users must use the Ok or Cancel buttons to close this modal.
```yaml
- id: modal_closable_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Closable (default)
color: primary
variant: outlined
events:
onClick:
- id: modal_closable_open
type: CallMethod
params:
blockId: modal_closable
method: setOpen
args:
- open: true
- id: modal_not_closable_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: No Close Button
color: danger
variant: outlined
events:
onClick:
- id: modal_not_closable_open
type: CallMethod
params:
blockId: modal_not_closable
method: setOpen
args:
- open: true
- id: modal_closable
type: Modal
properties:
title: Closable Modal
closable: true
blocks:
- id: modal_closable_content
type: Paragraph
properties:
content: The close button is visible in the top right corner. This is the
default behavior.
- id: modal_not_closable
type: Modal
properties:
title: No Close Button
closable: false
blocks:
- id: modal_not_closable_content
type: Paragraph
properties:
content: The close (x) button is hidden. Users must use the Ok or Cancel buttons
to close this modal.
```
The mask is visible but clicking it does not close the modal. Users must use the buttons or close icon.
No mask overlay is shown behind the modal. The page content remains fully visible.
The page behind the mask is blurred, which keeps attention on the dialog.
```yaml
- id: modal_mask_not_closable_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Mask Not Closable
color: primary
variant: outlined
events:
onClick:
- id: modal_mask_not_closable_open
type: CallMethod
params:
blockId: modal_mask_not_closable
method: setOpen
args:
- open: true
- id: modal_no_mask_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: No Mask
color: primary
variant: outlined
events:
onClick:
- id: modal_no_mask_open
type: CallMethod
params:
blockId: modal_no_mask
method: setOpen
args:
- open: true
- id: modal_mask_not_closable
type: Modal
properties:
title: Mask Not Closable
maskClosable: false
blocks:
- id: modal_mask_not_closable_content
type: Paragraph
properties:
content: The mask is visible but clicking it does not close the modal. Users
must use the buttons or close icon.
- id: modal_no_mask
type: Modal
properties:
title: No Mask
mask: false
blocks:
- id: modal_no_mask_content
type: Paragraph
properties:
content: No mask overlay is shown behind the modal. The page content remains
fully visible.
- id: modal_blur_mask_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Blurred Mask
color: primary
variant: outlined
events:
onClick:
- id: modal_blur_mask_open
type: CallMethod
params:
blockId: modal_blur_mask
method: setOpen
args:
- open: true
- id: modal_blur_mask
type: Modal
properties:
title: Blurred Mask
mask:
blur: true
blocks:
- id: modal_blur_mask_content
type: Paragraph
properties:
content: The page behind the mask is blurred, which keeps attention on the
dialog.
```
The body shows a skeleton while loading is true, for example while a request that fills the modal is running.
```yaml
- id: modal_loading_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Loading Modal
color: primary
variant: outlined
events:
onClick:
- id: modal_loading_open
type: CallMethod
params:
blockId: modal_loading
method: setOpen
args:
- open: true
- id: modal_loading
type: Modal
properties:
title: Customer Details
loading: true
width:
xs: 90%
md: 600
blocks:
- id: modal_loading_content
type: Paragraph
properties:
content: The body shows a skeleton while loading is true, for example while a
request that fills the modal is running.
```
Setting footer to false removes the Ok and Cancel buttons entirely. This is useful for informational dialogs or when you provide your own action buttons in the content area.
```yaml
- id: modal_no_footer_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal (no footer)
color: primary
variant: outlined
events:
onClick:
- id: modal_no_footer_open
type: CallMethod
params:
blockId: modal_no_footer
method: setOpen
args:
- open: true
- id: modal_no_footer
type: Modal
properties:
title: No Footer Modal
footer: false
blocks:
- id: modal_no_footer_content
type: Paragraph
properties:
content: Setting footer to false removes the Ok and Cancel buttons entirely.
This is useful for informational dialogs or when you provide your own
action buttons in the content area.
- id: modal_no_footer_close_btn
type: Button
properties:
title: Close
color: primary
variant: solid
block: true
events:
onClick:
- id: modal_no_footer_close
type: CallMethod
params:
blockId: modal_no_footer
method: setOpen
args:
- open: false
```
The footer slot replaces the default Ok/Cancel buttons with custom content. This example shows a Delete button on the left and Save/Cancel on the right.
```yaml
- id: modal_footer_slot_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal with Custom Footer
color: primary
variant: solid
events:
onClick:
- id: modal_footer_slot_open
type: CallMethod
params:
blockId: modal_footer_slot
method: setOpen
args:
- open: true
- id: modal_footer_slot
type: Modal
properties:
title: Custom Footer
slots:
footer:
blocks:
- id: modal_footer_slot_row
type: Box
layout:
gap: 8
justify: space-between
blocks:
- id: modal_footer_delete_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Delete
color: danger
variant: text
icon: delete
- id: modal_footer_actions
type: Box
layout:
flex: 0 0 auto
gap: 8
blocks:
- id: modal_footer_cancel_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel
color: default
variant: outlined
events:
onClick:
- id: modal_footer_cancel_close
type: CallMethod
params:
blockId: modal_footer_slot
method: setOpen
args:
- open: false
- id: modal_footer_save_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Save
color: primary
variant: solid
icon: save
events:
onClick:
- id: modal_footer_save_close
type: CallMethod
params:
blockId: modal_footer_slot
method: setOpen
args:
- open: false
blocks:
- id: modal_footer_slot_content
type: Paragraph
properties:
content: The footer slot replaces the default Ok/Cancel buttons with custom
content. This example shows a Delete button on the left and
Save/Cancel on the right.
```
The style .wrapper key applies CSS to the modal wrapper element. This can control overflow, positioning, and other layout aspects of the wrapper container.
```yaml
- id: modal_wrapper_style_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal with Wrapper Style
color: primary
variant: outlined
events:
onClick:
- id: modal_wrapper_style_open
type: CallMethod
params:
blockId: modal_wrapper_style
method: setOpen
args:
- open: true
- id: modal_wrapper_style
type: Modal
properties:
title: Wrapper Style Modal
style:
.wrapper:
overflow: hidden
blocks:
- id: modal_wrapper_style_content
type: Paragraph
properties:
content: The style .wrapper key applies CSS to the modal wrapper element. This
can control overflow, positioning, and other layout aspects of the
wrapper container.
```
This modal uses a custom z-index of 2000 to ensure it appears above other overlays. The default is 1000.
```yaml
- id: modal_zindex_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal (z-index 2000)
color: primary
variant: outlined
events:
onClick:
- id: modal_zindex_open
type: CallMethod
params:
blockId: modal_zindex
method: setOpen
args:
- open: true
- id: modal_zindex
type: Modal
properties:
title: High Z-Index Modal
zIndex: 2000
blocks:
- id: modal_zindex_content
type: Paragraph
properties:
content: This modal uses a custom z-index of 2000 to ensure it appears above
other overlays. The default is 1000.
```
This modal uses the toggleOpen method. Each click of the button alternates between open and closed states.
```yaml
- id: modal_toggle_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Toggle Modal
color: primary
variant: solid
icon: ArrowRightLeft
events:
onClick:
- id: modal_toggle_call
type: CallMethod
params:
blockId: modal_toggle
method: toggleOpen
- id: modal_toggle
type: Modal
properties:
title: Toggle Modal
blocks:
- id: modal_toggle_content
type: Paragraph
properties:
content: This modal uses the toggleOpen method. Each click of the button
alternates between open and closed states.
```
This modal demonstrates all four events. onOpen fires when the modal opens, onOk when the Ok button is clicked, onCancel when Cancel is clicked, and onClose fires after either onOk or onCancel completes.
```yaml
- id: modal_events_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal with Events
color: primary
variant: solid
events:
onClick:
- id: modal_events_open
type: CallMethod
params:
blockId: modal_events
method: setOpen
args:
- open: true
- id: modal_events
type: Modal
properties:
title: Modal with Events
events:
onOpen:
- id: modal_events_on_open
type: DisplayMessage
params:
content: Modal opened.
status: info
onOk:
- id: modal_events_on_ok
type: DisplayMessage
params:
content: Ok button clicked.
status: success
onCancel:
- id: modal_events_on_cancel
type: DisplayMessage
params:
content: Cancel button clicked.
status: warning
onClose:
- id: modal_events_on_close
type: DisplayMessage
params:
content: Modal closed.
status: info
blocks:
- id: modal_events_content
type: Paragraph
properties:
content: This modal demonstrates all four events. onOpen fires when the modal
opens, onOk when the Ok button is clicked, onCancel when Cancel is
clicked, and onClose fires after either onOk or onCancel completes.
```
This modal overrides design tokens via the theme property. The header has a blue background, custom title color and size, and larger border radius.
A warm-toned modal using an extensive set of theme tokens including headerBg, contentBg, footerBg, titleColor, colorBgMask, headerBorderBottom, footerBorderTop, headerPadding, bodyPadding, footerPadding, and margin tokens.
```yaml
- id: modal_theme_blue_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Blue Themed Modal
color: primary
variant: solid
events:
onClick:
- id: modal_theme_blue_open
type: CallMethod
params:
blockId: modal_theme_blue
method: setOpen
args:
- open: true
- id: modal_theme_blue
type: Modal
properties:
title: Blue Theme Modal
theme:
titleColor: "#0958d9"
titleFontSize: 20
titleLineHeight: 1.8
borderRadiusLG: 16
blocks:
- id: modal_theme_blue_content
type: Paragraph
properties:
content: This modal overrides design tokens via the theme property. The header
has a blue background, custom title color and size, and larger border
radius.
- id: modal_theme_warm_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Warm Themed Modal
color: default
variant: solid
events:
onClick:
- id: modal_theme_warm_open
type: CallMethod
params:
blockId: modal_theme_warm
method: setOpen
args:
- open: true
- id: modal_theme_warm
type: Modal
properties:
title: Warm Theme Modal
theme:
titleColor: "#d46b08"
colorBgMask: rgba(250, 173, 20, 0.1)
borderRadiusLG: 20
headerBorderBottom: "1px solid #ffd591"
footerBorderTop: "1px solid #ffd591"
headerMarginBottom: 0
footerMarginTop: 0
headerPadding: 16px 24px
bodyPadding: 24
footerPadding: 16px 24px
blocks:
- id: modal_theme_warm_content
type: Paragraph
properties:
content: A warm-toned modal using an extensive set of theme tokens including
headerBg, contentBg, footerBg, titleColor, colorBgMask,
headerBorderBottom, footerBorderTop, headerPadding, bodyPadding,
footerPadding, and margin tokens.
```
This modal uses style.body and style.mask to apply custom background colors. The body has a green tint and the mask has a subtle green overlay.
The element, wrapper, header, body, footer, mask, and content CSS keys allow targeting different parts of the modal with inline styles or Tailwind classes.
```yaml
- id: modal_styled_body_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Styled Modal
color: primary
variant: solid
events:
onClick:
- id: modal_styled_body_open
type: CallMethod
params:
blockId: modal_styled_body
method: setOpen
args:
- open: true
- id: modal_styled_body
type: Modal
properties:
title: Styled Modal
style:
.body:
padding: 24px
.mask:
backgroundColor: rgba(0, 100, 0, 0.15)
blocks:
- id: modal_styled_body_content
type: Paragraph
properties:
content: This modal uses style.body and style.mask to apply custom background
colors. The body has a green tint and the mask has a subtle green
overlay.
- id: modal_styled_wrapper_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal with Wrapper Style
color: primary
variant: outlined
events:
onClick:
- id: modal_styled_wrapper_open
type: CallMethod
params:
blockId: modal_styled_wrapper
method: setOpen
args:
- open: true
- id: modal_styled_wrapper
type: Modal
properties:
title: Custom Wrapper Style
style:
.element:
borderRadius: 20px
.wrapper:
backdropFilter: blur(2px)
blocks:
- id: modal_styled_wrapper_content
type: Paragraph
properties:
content: The element, wrapper, header, body, footer, mask, and content CSS keys
allow targeting different parts of the modal with inline styles or
Tailwind classes.
```
Modal supports these CSS keys for Tailwind class targeting: element, header, body, footer, mask, wrapper, content. Use class as an object to apply Tailwind utilities to each area independently.
```yaml
- id: modal_css_keys_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Open Modal with Tailwind Classes
color: primary
variant: solid
events:
onClick:
- id: modal_css_keys_open
type: CallMethod
params:
blockId: modal_css_keys
method: setOpen
args:
- open: true
- id: modal_css_keys
type: Modal
properties:
title: Tailwind Styled Modal
class:
.header: bg-bg-layout
.body: bg-bg-layout p-8
.footer: bg-bg-layout
.content: rounded-2xl overflow-hidden
blocks:
- id: modal_css_keys_content
type: Paragraph
properties:
content: "Modal supports these CSS keys for Tailwind class targeting: element,
header, body, footer, mask, wrapper, content. Use class as an object
to apply Tailwind utilities to each area independently."
```
Jane Cooper
Senior Product Designer
```yaml
- id: modal_profile_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Edit Profile
color: primary
variant: solid
icon: edit
events:
onClick:
- id: modal_profile_open
type: CallMethod
params:
blockId: modal_profile
method: setOpen
args:
- open: true
- id: modal_profile
type: Modal
properties:
title: Edit Your Profile
width: 640
okText: Save Profile
cancelText: Cancel
centered: true
theme:
headerBorderBottom: "1px solid #f0f0f0"
headerMarginBottom: 0
events:
onOk:
- id: modal_profile_save
type: DisplayMessage
params:
content: Profile saved successfully.
status: success
blocks:
- id: modal_profile_avatar_row
type: Box
layout:
gap: 16
align: center
blocks:
- id: modal_profile_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 72
color: "#1677ff"
- id: modal_profile_info
type: Box
layout:
flex: 1 1 0
direction: column
gap: 4
blocks:
- id: modal_profile_name_title
type: Title
properties:
content: Jane Cooper
level: 4
- id: modal_profile_role_text
type: Paragraph
properties:
content: Senior Product Designer
- id: modal_profile_divider
type: Divider
- id: modal_profile_name_input
type: TextInput
properties:
title: Full Name
placeholder: Enter your full name
- id: modal_profile_email_input
type: TextInput
properties:
title: Email Address
placeholder: Enter your email
- id: modal_profile_bio_input
type: TextArea
properties:
title: Bio
placeholder: Tell us about yourself
rows: 3
```
This action cannot be undone. All project data, files, and team assignments will be permanently removed.
```yaml
- id: modal_confirm_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Delete Project
color: danger
variant: solid
icon: delete
events:
onClick:
- id: modal_confirm_open
type: CallMethod
params:
blockId: modal_confirm
method: setOpen
args:
- open: true
- id: modal_confirm
type: Modal
properties:
title: Delete Project?
width: 420
centered: true
okText: Delete Permanently
cancelText: Keep Project
okButtonProps:
danger: true
closable: false
maskClosable: false
theme:
titleColor: "#cf1322"
events:
onOk:
- id: modal_confirm_delete
type: DisplayMessage
params:
content: Project deleted.
status: success
onCancel:
- id: modal_confirm_keep
type: DisplayMessage
params:
content: Project kept.
status: info
blocks:
- id: modal_confirm_warning
type: Paragraph
properties:
content: This action cannot be undone. All project data, files, and team
assignments will be permanently removed.
- id: modal_confirm_details
type: Descriptions
properties:
column: 1
size: small
items:
- label: Project
value: Project Alpha
- label: Owner
value: Jane Cooper
- label: Files
value: 248 files (1.2 GB)
```
A serene mountain landscape captured at golden hour. Photography by John Doe.
```yaml
- id: modal_image_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Preview Image
color: primary
variant: outlined
icon: image
events:
onClick:
- id: modal_image_open
type: CallMethod
params:
blockId: modal_image
method: setOpen
args:
- open: true
- id: modal_image
type: Modal
properties:
title: Mountain Landscape
width: 720
footer: false
centered: true
theme:
bodyPadding: 0
headerMarginBottom: 0
blocks:
- id: modal_image_html
type: Html
properties:
html:
- id: modal_image_caption
type: Box
layout:
gap: 8
align: center
justify: space-between
class: p-4
blocks:
- id: modal_image_desc
type: Paragraph
layout:
flex: 1 1 0
properties:
content: A serene mountain landscape captured at golden hour. Photography by
John Doe.
- id: modal_image_tags
type: Box
layout:
flex: 0 0 auto
gap: 8
blocks:
- id: modal_image_tag1
type: Tag
properties:
title: Photography
color: blue
- id: modal_image_tag2
type: Tag
properties:
title: Featured
color: gold
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `centered` | boolean | `false` | Center the modal vertically. |
| `closable` | boolean \| object | `true` | Whether a close (x) button is visible on top right of the modal dialog or not. Set `{ disabled: true }` to show the button disabled. |
| `closable.disabled` | boolean | `false` | Show the close button, but disabled. |
| `destroyOnHidden` | boolean | `false` | Unmount the blocks inside the modal when it closes, so they mount again (and their onMount events run) each time it opens. Their state is kept. |
| `focusable` | object | - | Focus management of the dialog. |
| `focusable.trap` | boolean | `true` | Keep keyboard focus inside the dialog while it is open. |
| `focusable.focusTriggerAfterClose` | boolean | `true` | Return focus to the element that opened the dialog after it closes. |
| `forceRender` | boolean | `false` | Render the blocks inside the modal before it is first opened, so their methods can be called and their onMount events run while it is still closed. |
| `keyboard` | boolean | `true` | Whether pressing Esc closes the modal. |
| `loading` | boolean | `false` | Show a loading skeleton in place of the modal body. |
| `padding` | string | `"default"` | Space inside the modal. `compact` tightens it to 16px. `none` removes the body padding so content such as a table, list or image runs edge to edge; the header and footer keep their padding. Enum: `default`, `compact`, `none`. |
| `scrollLock` | boolean | `true` | Whether to lock page scrolling while the modal is open. |
| `title` | string | - | The modal dialog's title - supports html. |
| `footer` | boolean | `true` | Show footer area. |
| `mask` | boolean \| object | `true` | Whether to show the mask. Set an object to configure the mask with `enabled`, `blur` and `closable`. |
| `mask.enabled` | boolean | `true` | Whether to show the mask. |
| `mask.blur` | boolean | `false` | Blur the page behind the mask. |
| `mask.closable` | boolean | - | Whether clicking the mask closes the dialog. Takes precedence over `maskClosable`. |
| `maskClosable` | boolean | `true` | Whether to close the modal dialog when the mask (area outside the modal) is clicked. `mask.closable` takes precedence. |
| `okText` | string | - | Text of the Ok button. When unset, antd uses the localized default from ConfigProvider locale. |
| `okButtonProps` | object | - | Set additional properties for the ok button. |
| `cancelText` | string | - | Text of the Cancel button. When unset, antd uses the localized default from ConfigProvider locale. |
| `cancelButtonProps` | object | - | Set additional properties for the cancel button. |
| `width` | string \| number \| object | `520` | Width of the modal dialog. Set an object of breakpoints (`xs`, `sm`, `md`, `lg`, `xl`, `xxl`) for a responsive width. |
| `width.xs` | string \| number | - | Width on extra small screens. |
| `width.sm` | string \| number | - | Width on small screens. |
| `width.md` | string \| number | - | Width on medium screens. |
| `width.lg` | string \| number | - | Width on large screens. |
| `width.xl` | string \| number | - | Width on extra large screens. |
| `width.xxl` | string \| number | - | Width on extra extra large screens. |
| `zIndex` | integer | `1000` | The z-index of the modal. Useful when displaying two modals simultaneously. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design modal tokens](https://ant.design/components/modal#design-token). |
| `theme.headerBg` | string | - | Background color of the modal header. |
| `theme.titleLineHeight` | number | `1.5` | Line height of the modal title. |
| `theme.titleFontSize` | number | `16` | Font size of the modal title. |
| `theme.titleColor` | string | - | Color of the modal title text. |
| `theme.contentBg` | string | - | Background color of the modal content. |
| `theme.footerBg` | string | `"transparent"` | Background color of the modal footer. |
| `theme.contentPadding` | number \| string | - | Padding of the content area. |
| `theme.headerPadding` | number \| string | - | Padding of the header area. |
| `theme.headerBorderBottom` | string | - | Border bottom of the header. |
| `theme.headerMarginBottom` | number | `8` | Margin bottom of the header. |
| `theme.bodyPadding` | number | - | Padding of the body area. |
| `theme.footerPadding` | number \| string | - | Padding of the footer area. |
| `theme.footerBorderTop` | string | - | Border top of the footer. |
| `theme.footerBorderRadius` | number \| string | - | Border radius of the footer. |
| `theme.footerMarginTop` | number \| string | `8` | Margin top of the footer. |
| `theme.confirmBodyPadding` | number \| string | - | Padding of the confirm modal body. |
| `theme.confirmIconMarginInlineEnd` | number \| string | - | Inline end margin of the confirm modal icon. |
| `theme.confirmBtnsMarginTop` | number \| string | - | Margin top of the confirm modal buttons. |
| `theme.borderRadiusLG` | number | `8` | Border radius of the modal. |
| `theme.colorBgMask` | string | `"rgba(0, 0, 0, 0.45)"` | Background color of the modal mask. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onOk` | \- | Trigger actions when Ok button is clicked. |
| `onOpen` | \- | Trigger actions when modal is opened. |
| `onCancel` | \- | Trigger actions when Cancel button is clicked. |
| `onClose` | \- | Trigger actions after onOk or onCancel is completed. |
| `afterClose` | \- | Trigger actions after the modal has closed and its close animation has finished. |
| `afterOpenChange` | `{ open }` | Trigger actions after the open or close animation of the modal has finished. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Modal element. |
| `/header` | The Modal header. |
| `/title` | The Modal title. |
| `/body` | The Modal body. |
| `/footer` | The Modal footer. |
| `/mask` | The Modal mask. |
| `/wrapper` | The Modal wrapper. |
| `/content` | The Modal content. |
| Slot | Description |
| --- | --- |
| `content` | Main Modal body. |
| `footer` | Custom footer. Overrides default Ok/Cancel buttons. |
---
url: https://docs.lowdefy.com/md/container-blocks/pageheadermenu.md
---
# PageHeaderMenu
Page layout with a top header navigation menu.
Welcome
Follow the quick start guide to set up your first project in minutes.
Browse the full API reference and configuration guides.
```yaml
- id: phm_basic
type: PageHeaderMenu
properties:
menu:
links:
- id: phm_basic_home
type: MenuLink
properties:
title: Home
icon: home
- id: phm_basic_products
type: MenuLink
properties:
title: Products
icon: grid
- id: phm_basic_pricing
type: MenuLink
properties:
title: Pricing
- id: phm_basic_contact
type: MenuLink
properties:
title: Contact
blocks:
- id: phm_basic_title
type: Title
properties:
content: Welcome
level: 2
- id: phm_basic_cards
type: Box
layout:
gap: 16
blocks:
- id: phm_basic_card_1
type: Card
layout:
flex: 1 1 0
properties:
title: Getting Started
blocks:
- id: phm_basic_card_1_text
type: Paragraph
properties:
content: Follow the quick start guide to set up your first project in minutes.
- id: phm_basic_card_2
type: Card
layout:
flex: 1 1 0
properties:
title: Documentation
blocks:
- id: phm_basic_card_2_text
type: Paragraph
properties:
content: Browse the full API reference and configuration guides.
```
padding: compact trims the content padding from 40px to 16px, so data-heavy pages show more.
```yaml
- id: phm_compact
type: PageHeaderMenu
properties:
padding: compact
menu:
links:
- id: phm_compact_home
type: MenuLink
properties:
title: Home
- id: phm_compact_invoices
type: MenuLink
properties:
title: Invoices
blocks:
- id: phm_compact_text
type: Paragraph
properties:
content: "padding: compact trims the content padding from 40px to 16px, so
data-heavy pages show more."
- id: phm_compact_card
type: Card
properties:
title: Recent invoices
padding: none
blocks:
- id: phm_compact_card_rows
type: Html
properties:
html: >
INV-1042 $1,280.00
INV-1041 $640.00
INV-1040 $2,115.50
INV-1039 $96.00
```
Analytics Overview
```yaml
- id: phm_grouped
type: PageHeaderMenu
properties:
darkModeToggle: true
breadcrumb:
separator: /
list:
- label: Home
icon: home
- label: Analytics
- label: Overview
menu:
links:
- id: phm_g_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: phm_g_analytics
type: MenuGroup
properties:
title: Analytics
icon: chart
links:
- id: phm_g_overview
type: MenuLink
properties:
title: Overview
- id: phm_g_realtime
type: MenuLink
properties:
title: Real-time
- id: phm_g_funnel
type: MenuLink
properties:
title: Funnels
- id: phm_g_settings
type: MenuLink
properties:
title: Settings
icon: settings
blocks:
- id: phm_g_title
type: Title
properties:
content: Analytics Overview
level: 3
- id: phm_g_cards
type: Box
layout:
gap: 16
blocks:
- id: phm_g_card_visits
type: Card
layout:
flex: 1 1 200px
properties:
size: small
blocks:
- id: phm_g_stat_visits
type: Statistic
properties:
title: Page Views
value: 12847
- id: phm_g_card_users
type: Card
layout:
flex: 1 1 200px
properties:
size: small
blocks:
- id: phm_g_stat_users
type: Statistic
properties:
title: Active Users
value: 1024
- id: phm_g_card_rate
type: Card
layout:
flex: 1 1 200px
properties:
size: small
blocks:
- id: phm_g_stat_rate
type: Statistic
properties:
title: Bounce Rate
value: 23.4
suffix: "%"
```
Dashboard
```yaml
- id: phm_profile
type: PageHeaderMenu
properties:
darkModeToggle: true
notifications:
count: 3
profile:
avatar:
content: JD
color: "#1677ff"
links:
- id: phm_prof_my_profile
type: MenuLink
properties:
title: My Profile
icon: user
- id: phm_prof_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: phm_prof_divider
type: MenuDivider
- id: phm_prof_logout
type: MenuLink
properties:
title: Logout
icon: logout
danger: true
menu:
links:
- id: phm_prof_home
type: MenuLink
properties:
title: Home
icon: home
- id: phm_prof_projects
type: MenuLink
properties:
title: Projects
icon: SquareKanban
- id: phm_prof_reports
type: MenuLink
properties:
title: Reports
icon: chart
blocks:
- id: phm_prof_title
type: Title
properties:
content: Dashboard
level: 3
- id: phm_prof_cards
type: Box
layout:
gap: 16
blocks:
- id: phm_prof_card_1
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: phm_prof_stat_1
type: Statistic
properties:
title: Active Projects
value: 12
- id: phm_prof_card_2
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: phm_prof_stat_2
type: Statistic
properties:
title: Pending Tasks
value: 8
```
Welcome back, Jane
Office hours updated: Building opens at 7:00 AM starting next Monday.
Q1 All-Hands meeting scheduled for March 28 at 2:00 PM.
Submit a Time-Off Request
View Expense Reports
```yaml
- id: phm_full
type: PageHeaderMenu
properties:
darkModeToggle: true
logo:
alt: Acme Corp
notifications:
dot: true
profile:
avatar:
icon: user
breadcrumb:
list:
- Intranet
- Team Directory
menu:
links:
- id: phm_full_home
type: MenuLink
properties:
title: Home
icon: home
- id: phm_full_directory
type: MenuLink
properties:
title: Directory
icon: users
- id: phm_full_resources
type: MenuGroup
properties:
title: Resources
icon: Book
links:
- id: phm_full_policies
type: MenuLink
properties:
title: Company Policies
- id: phm_full_benefits
type: MenuLink
properties:
title: Benefits Guide
- id: phm_full_help
type: MenuLink
properties:
title: IT Support
icon: help
slots:
footer:
blocks:
- id: phm_full_footer_text
type: Paragraph
properties:
content: Acme Corp Intranet - Internal Use Only
style:
.element:
margin: 0
color: "#888"
textAlign: center
blocks:
- id: phm_full_welcome
type: Title
properties:
content: Welcome back, Jane
level: 3
- id: phm_full_cards
type: Box
layout:
gap: 16
blocks:
- id: phm_full_card_announce
type: Card
layout:
flex: 1 1 300px
properties:
title: Announcements
blocks:
- id: phm_full_announce_1
type: Paragraph
properties:
content: "Office hours updated: Building opens at 7:00 AM starting next Monday."
- id: phm_full_announce_2
type: Paragraph
properties:
content: Q1 All-Hands meeting scheduled for March 28 at 2:00 PM.
- id: phm_full_card_links
type: Card
layout:
flex: 1 1 300px
properties:
title: Quick Links
blocks:
- id: phm_full_link_1
type: Paragraph
properties:
content: Submit a Time-Off Request
- id: phm_full_link_2
type: Paragraph
properties:
content: View Expense Reports
```
Installation
Get started by installing the framework via npm or yarn. Follow the steps below to set up your development environment.
> Prerequisites
1. Initialize a new project directory and run the setup command.
2. Configure your lowdefy.yaml file with pages and connections.
3. Start the development server to preview your application.
```yaml
- id: phm_light
type: PageHeaderMenu
properties:
darkModeToggle: true
menu:
links:
- id: phm_light_guide
type: MenuLink
properties:
title: Guide
icon: Book
- id: phm_light_api
type: MenuLink
properties:
title: API Reference
icon: Plug
- id: phm_light_examples
type: MenuLink
properties:
title: Examples
icon: CodeXml
- id: phm_light_community
type: MenuLink
properties:
title: Community
icon: globe
breadcrumb:
separator: /
list:
- Docs
- Getting Started
- Installation
slots:
header:
blocks:
- id: phm_light_search_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Search
icon: search
color: default
variant: outlined
size: small
blocks:
- id: phm_light_title
type: Title
properties:
content: Installation
level: 2
- id: phm_light_intro
type: Paragraph
properties:
content: Get started by installing the framework via npm or yarn. Follow the
steps below to set up your development environment.
- id: phm_light_alert
type: Alert
properties:
message: Prerequisites
description: Make sure you have Node.js version 18 or higher installed before
proceeding.
type: info
showIcon: true
- id: phm_light_steps
type: Card
properties:
title: Setup Steps
size: small
blocks:
- id: phm_light_step_1
type: Paragraph
properties:
content: 1. Initialize a new project directory and run the setup command.
- id: phm_light_step_2
type: Paragraph
properties:
content: 2. Configure your lowdefy.yaml file with pages and connections.
- id: phm_light_step_3
type: Paragraph
properties:
content: 3. Start the development server to preview your application.
```
Profile from _menu
> The profile dropdown links are populated using _menu operator, pulling from the menus defined in lowdefy.yaml. Click the avatar to see the dropdown.
```yaml
- id: phm_menu_op
type: PageHeaderMenu
properties:
darkModeToggle: true
notifications:
count: 2
link:
pageId: home
profile:
avatar:
content: JD
color: "#6366f1"
links:
_menu: default
menu:
links:
- id: phm_mo_home
type: MenuLink
properties:
title: Home
icon: home
- id: phm_mo_settings
type: MenuLink
properties:
title: Settings
icon: settings
blocks:
- id: phm_mo_title
type: Title
properties:
content: Profile from _menu
level: 3
- id: phm_mo_info
type: Alert
properties:
message: The profile dropdown links are populated using _menu operator, pulling
from the menus defined in lowdefy.yaml. Click the avatar to see the
dropdown.
type: info
showIcon: true
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `logo` | object | - | Header logo settings. By default, images are served from the app public folder and auto-swap between light and dark variants based on dark mode. See [Hosting Files](/hosting-files) for details. |
| `logo.src` | string | - | Logo image URL for desktop. Defaults to logo-light-theme.png or logo-dark-theme.png from the public folder (~250x72px), auto-selected based on dark mode. |
| `logo.srcMobile` | string | - | Logo image URL for mobile. Defaults to logo-square-light-theme.png or logo-square-dark-theme.png from the public folder (~125x125px), auto-selected based on dark mode. |
| `logo.breakpoint` | number | - | Viewport width breakpoint (in px) for switching between mobile and desktop logo. Default is 577. |
| `logo.alt` | string | `"Lowdefy"` | Logo image alt text. |
| `header` | object | - | Header properties. |
| `footer` | object | - | Footer properties. |
| `padding` | string | `"default"` | Space around the page content. `compact` tightens it to 16px for dense, data-heavy pages. `none` removes it so content such as a table or grid runs edge to edge; the breadcrumb keeps its own inset. Enum: `default`, `compact`, `none`. |
| `content` | object | - | Content properties. |
| `breadcrumb` | object | - | Breadcrumb properties. |
| `breadcrumb.separator` | string | `"/"` | Use a custom separator string. |
| `breadcrumb.list` | array | - | List of breadcrumb links. |
| `breadcrumb.list.$.label` | string | - | Label of the breadcrumb link. |
| `breadcrumb.list.$.pageId` | string | - | Page id to link to when clicked. |
| `breadcrumb.list.$.url` | string | - | External url link. |
| `breadcrumb.list.$.style` | object | - | Css style to apply to link. |
| `breadcrumb.list.$.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to use an icon in breadcrumb link. |
| `breadcrumb.list.$.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `breadcrumb.list.$.icon.color` | string | - | Icon color. |
| `breadcrumb.list.$.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `breadcrumb.list.$.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `breadcrumb.list.$.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `breadcrumb.list.$.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `breadcrumb.list.$.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `breadcrumb.list.$.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `breadcrumb.list.$.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `breadcrumb.list.$.links` | array | - | Links shown in a dropdown menu on the breadcrumb item. |
| `breadcrumb.list.$.links.$.label` | string | - | Label of the dropdown link. |
| `breadcrumb.list.$.links.$.pageId` | string | - | Page id to link to when clicked. |
| `breadcrumb.list.$.links.$.url` | string | - | External url link. |
| `menu` | object | - | Menu properties. |
| `menu.links` | array | - | |
| `menu.links.$.id` | string | - | Menu item id. |
| `menu.links.$.pageId` | string | - | Page to link to. |
| `menu.links.$.properties` | object | - | properties from menu item. |
| `menu.links.$.properties.title` | string | - | Menu item title. |
| `menu.links.$.properties.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize icon on menu item. |
| `menu.links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `menu.links.$.properties.icon.color` | string | - | Icon color. |
| `menu.links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `menu.links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `menu.links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `menu.links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `menu.links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `menu.links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `menu.links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `menuLg` | object | - | Menu large screen properties. Overwrites menu properties on desktop screen sizes. |
| `menuMd` | object | - | Mobile menu properties. Overwrites menu properties on mobile screen sizes. |
| `notifications` | object | - | Notification bell icon with badge in the header. Renders when configured. Use the link property to navigate when clicked. |
| `notifications.link` | object | - | Link to navigate to when the notification bell is clicked. |
| `notifications.link.pageId` | string | - | Page to link to. |
| `notifications.link.url` | string | - | External URL to link to. |
| `notifications.link.newTab` | boolean | - | Open link in new tab. |
| `notifications.count` | number | - | Number to display on the badge. Set to 0 to hide the badge (unless showZero is true). |
| `notifications.dot` | boolean | `false` | Show a dot instead of a count number. |
| `notifications.showZero` | boolean | `false` | Show badge when count is zero. |
| `notifications.overflowCount` | number | `99` | Max count to show. Values above this display as "N+". |
| `notifications.color` | string | - | Badge color. |
| `notifications.icon` | string \| object | - | Icon for the notification button. Defaults to `bell`. |
| `notifications.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `notifications.icon.color` | string | - | Icon color. |
| `notifications.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `notifications.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `notifications.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `notifications.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `notifications.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `notifications.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `notifications.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `notifications.size` | string | `"small"` | Size of the notification button. Enum: `small`, `default`, `large`. |
| `profile` | object | - | Profile avatar with optional dropdown menu in the header. Renders when configured. Use with the _user operator to populate from the authenticated user. |
| `profile.avatar` | object | - | Avatar display properties. |
| `profile.avatar.src` | string | - | Image URL for the avatar. Typically bound to _user: image. |
| `profile.avatar.content` | string | - | Text content inside the avatar (e.g. user initials). Shown when no src is provided. |
| `profile.avatar.icon` | string \| object | - | Icon to display in avatar when no src or content is set. Defaults to `user`. |
| `profile.avatar.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `profile.avatar.icon.color` | string | - | Icon color. |
| `profile.avatar.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `profile.avatar.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `profile.avatar.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `profile.avatar.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `profile.avatar.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `profile.avatar.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `profile.avatar.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `profile.avatar.color` | string | - | Background color of the avatar when not using src. |
| `profile.avatar.size` | string \| number | `"small"` | Size of the avatar: default, small, large or a pixel number. |
| `profile.avatar.shape` | string | `"circle"` | Shape of the avatar. Enum: `circle`, `square`. |
| `profile.links` | array | - | Dropdown menu items. Uses the same MenuLink/MenuGroup/MenuDivider schema as Menu. Compatible with _menu operator output for access-filtered menus. |
| `profile.links.$.id` | string | - | Menu item id. |
| `profile.links.$.type` | string | `"MenuLink"` | Menu item type. Enum: `MenuDivider`, `MenuLink`, `MenuGroup`. |
| `profile.links.$.pageId` | string | - | Page to link to. |
| `profile.links.$.url` | string | - | External URL to link to. |
| `profile.links.$.newTab` | boolean | - | Open link in new tab. |
| `profile.links.$.style` | object | - | CSS style applied to the link. |
| `profile.links.$.properties` | object | - | Properties for the menu item. |
| `profile.links.$.properties.title` | string | - | Menu item title. |
| `profile.links.$.properties.icon` | string \| object | - | Icon for the menu item. |
| `profile.links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `profile.links.$.properties.icon.color` | string | - | Icon color. |
| `profile.links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `profile.links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `profile.links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `profile.links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `profile.links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `profile.links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `profile.links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `profile.links.$.properties.danger` | boolean | `false` | Apply danger style to menu item. |
| `profile.links.$.properties.disabled` | boolean | `false` | Disable the menu item. |
| `profile.links.$.properties.dashed` | boolean | `false` | Whether the divider line is dashed. |
| `profile.links.$.properties.shortcut` | string | - | Keyboard shortcut. Renders a kbd badge floated to the far right and wires the key handler. Use "mod" for Cmd/Ctrl. |
| `profile.links.$.links` | array | - | Nested menu items for MenuGroup. |
| `profile.trigger` | string | `"hover"` | How the profile dropdown opens. Enum: `click`, `hover`. |
| `profile.placement` | string | `"bottomRight"` | Dropdown placement relative to the avatar. Enum: `bottomLeft`, `bottom`, `bottomRight`, `topLeft`, `top`, `topRight`. |
| `profile.arrow` | boolean \| object | `false` | Show arrow on the dropdown. |
| `profile.arrow.pointAtCenter` | boolean | - | |
| `darkModeToggle` | boolean | `false` | Show a dark mode toggle button in the header. Toggles the Ant Design dark theme for the entire page. Preference is persisted to localStorage. |
| `localeSelector` | boolean | `false` | Show a locale picker dropdown in the header. Lists locales declared in `config.i18n.locales` and dispatches `SetLocale` on selection. Renders nothing when `config.i18n` is not configured. |
| `theme` | object | - | Antd global design token overrides, such as colorPrimary or borderRadius, applied to everything in the page layout. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design component tokens](https://ant.design/docs/react/customize-theme#seedtoken). |
| Event | Event Data | Description |
| --- | --- | --- |
| `onBreadcrumbClick` | \- | Trigger action when a breadcrumb item is clicked. |
| `onClose` | \- | Trigger action when mobile menu is closed. |
| `onMenuItemClick` | \- | Trigger action when menu item is clicked. |
| `onMenuItemSelect` | \- | Trigger action when menu item is selected. |
| `onOpen` | \- | Trigger action when mobile menu is open. |
| `onProfileMenuClick` | `{ key, keyPath, pageId, url }` | Trigger action when a profile dropdown menu item is clicked. |
| `onProfileMenuOpen` | `{ open }` | Trigger action when the profile dropdown opens or closes. |
| `onToggleDrawer` | \- | Trigger action when mobile menu drawer is toggled. |
| `onToggleMenuGroup` | \- | Trigger action when mobile menu group is opened. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The PageHeaderMenu element. |
| `/header` | The PageHeaderMenu header. |
| `/headerActions` | The header actions container (notifications, profile, dark mode toggle). |
| `/headerContent` | The PageHeaderMenu header content area. |
| `/logo` | The PageHeaderMenu logo. |
| `/notifications` | The notification bell button. |
| `/notificationsBadge` | The notification badge wrapper. |
| `/notificationsIcon` | The notification bell icon. |
| `/profile` | The profile avatar and dropdown wrapper. |
| `/profileAvatar` | The profile avatar element. |
| `/profileMenu` | The profile dropdown menu popup. |
| `/darkModeToggle` | The PageHeaderMenu dark mode toggle button. |
| `/localeSelector` | The PageHeaderMenu locale selector trigger. |
| `/localeSelectorMenu` | The PageHeaderMenu locale selector dropdown popup. |
| `/mobileMenu` | The PageHeaderMenu mobile menu. |
| `/menu` | The PageHeaderMenu menu. |
| `/content` | The PageHeaderMenu content. |
| `/breadcrumb` | The PageHeaderMenu breadcrumb. |
| `/footer` | The PageHeaderMenu footer. |
| Slot | Description |
| --- | --- |
| `content` | Main page content. |
| `footer` | Page footer. |
| `header` | Additional header content. |
---
url: https://docs.lowdefy.com/md/container-blocks/pagesidebarlayout.md
---
# PageSidebarLayout
Full-page layout with a full-height sidebar and no top-level header. The sider spans the entire viewport height with the logo affixed at the bottom. A mobile drawer menu appears on small screens. Sider collapse state is persisted in localStorage.
PageSidebarLayout provides a full-page layout with a full-height sidebar. The sider spans the entire viewport height with the logo at the bottom. On mobile screens, a hamburger menu with a full-width drawer replaces the sider.
```yaml
- id: psl_basic
type: PageSidebarLayout
properties:
siderStorageKey: psl_basic
sider:
initialCollapsed: false
width: 220
menu:
links:
- id: psl_basic_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: psl_basic_users
type: MenuLink
properties:
title: Users
icon: user
- id: psl_basic_settings
type: MenuLink
properties:
title: Settings
icon: settings
blocks:
- id: psl_basic_content
type: Paragraph
properties:
content: PageSidebarLayout provides a full-page layout with a full-height
sidebar. The sider spans the entire viewport height with the logo at
the bottom. On mobile screens, a hamburger menu with a full-width
drawer replaces the sider.
```
padding: none removes the content padding, so tables and grids can run edge to edge. Blocks set their own spacing.
```yaml
- id: psl_flush
type: PageSidebarLayout
properties:
siderStorageKey: psl_flush
padding: none
menu:
links:
- id: psl_flush_dashboard
type: MenuLink
properties:
title: Dashboard
- id: psl_flush_invoices
type: MenuLink
properties:
title: Invoices
blocks:
- id: psl_flush_text
type: Paragraph
class: px-4
properties:
content: "padding: none removes the content padding, so tables and grids can run
edge to edge. Blocks set their own spacing."
- id: psl_flush_card
type: Card
properties:
title: Recent invoices
padding: none
variant: borderless
blocks:
- id: psl_flush_card_rows
type: Html
properties:
html: >
INV-1042 $1,280.00
INV-1041 $640.00
INV-1040 $2,115.50
INV-1039 $96.00
```
Sider starts collapsed. Click the toggle button to expand. The collapsed state is persisted in localStorage.
```yaml
- id: psl_collapsed
type: PageSidebarLayout
properties:
siderStorageKey: psl_collapsed
sider:
initialCollapsed: true
menu:
links:
- id: psl_collapsed_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: psl_collapsed_users
type: MenuLink
properties:
title: Users
icon: user
blocks:
- id: psl_collapsed_content
type: Paragraph
properties:
content: Sider starts collapsed. Click the toggle button to expand. The
collapsed state is persisted in localStorage.
```
Optional desktop header with custom content. The header sits inside the content area, not above the sider.
```yaml
- id: psl_header
type: PageSidebarLayout
properties:
siderStorageKey: psl_header
sider:
width: 220
header:
contentStyle:
justifyContent: flex-end
menu:
links:
- id: psl_header_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: psl_header_settings
type: MenuLink
properties:
title: Settings
icon: settings
slots:
header:
blocks:
- id: psl_header_search_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Search
icon: search
color: default
variant: outlined
size: small
blocks:
- id: psl_header_content
type: Paragraph
properties:
content: Optional desktop header with custom content. The header sits inside the
content area, not above the sider.
```
The siderHeader slot sits above the menu and stays in place while a long menu scrolls. siderHeaderClosed takes its place while the sider is collapsed, and mobileDrawerHeader puts content above the menu in the mobile drawer.
Acme Inc
```yaml
- id: psl_sider_header
type: PageSidebarLayout
properties:
siderStorageKey: psl_sider_header
sider:
width: 240
menu:
links:
- id: psl_sider_header_general
type: MenuLink
properties:
title: General
icon: settings
- id: psl_sider_header_members
type: MenuLink
properties:
title: Members
icon: users
- id: psl_sider_header_billing
type: MenuLink
properties:
title: Billing
icon: CreditCard
slots:
siderHeader:
blocks:
- id: psl_sider_header_open
type: Box
style:
padding: 8px 16px
blocks:
- id: psl_sider_header_back
type: Button
properties:
title: Back to app
icon: arrow-left
type: link
size: small
- id: psl_sider_header_title
type: Title
properties:
content: Acme Inc
level: 5
siderHeaderClosed:
blocks:
- id: psl_sider_header_closed
type: Box
style:
padding: 8px
textAlign: center
blocks:
- id: psl_sider_header_back_icon
type: Button
properties:
hideTitle: true
title: Back to app
icon: arrow-left
type: link
mobileDrawerHeader:
blocks:
- id: psl_sider_header_drawer
type: Box
style:
padding: 0 24px
blocks:
- id: psl_sider_header_drawer_back
type: Button
properties:
title: Back to app
icon: arrow-left
type: link
size: small
blocks:
- id: psl_sider_header_content
type: Paragraph
properties:
content: The siderHeader slot sits above the menu and stays in place while a
long menu scrolls. siderHeaderClosed takes its place while the sider
is collapsed, and mobileDrawerHeader puts content above the menu in
the mobile drawer.
```
Custom logo with style overrides. The full logo (src) shows when the sider is expanded, and the square logo (srcMobile) shows when collapsed.
```yaml
- id: psl_logo
type: PageSidebarLayout
properties:
siderStorageKey: psl_logo
logo:
src: /logo_example.png
srcMobile: /logo_example.png
alt: Custom Logo
style:
width: 80
menu:
links:
- id: psl_logo_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
blocks:
- id: psl_logo_content
type: Paragraph
properties:
content: Custom logo with style overrides. The full logo (src) shows when the
sider is expanded, and the square logo (srcMobile) shows when
collapsed.
```
Dashboard Overview
```yaml
- id: psl_admin
type: PageSidebarLayout
properties:
siderStorageKey: psl_admin
darkModeToggle: true
notifications:
count: 3
profile:
avatar:
content: AU
color: "#1677ff"
links:
- id: psl_admin_prof_profile
type: MenuLink
properties:
title: My Profile
icon: user
- id: psl_admin_prof_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: psl_admin_prof_divider
type: MenuDivider
- id: psl_admin_prof_logout
type: MenuLink
properties:
title: Sign Out
icon: logout
danger: true
sider:
width: 240
breadcrumb:
list:
- Admin
- Dashboard
menu:
defaultOpenKeys:
- psl_admin_users_group
links:
- id: psl_admin_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: psl_admin_users_group
type: MenuGroup
properties:
title: User Management
icon: users
links:
- id: psl_admin_all_users
type: MenuLink
properties:
title: All Users
- id: psl_admin_user_roles
type: MenuLink
properties:
title: Roles & Permissions
- id: psl_admin_analytics
type: MenuLink
properties:
title: Analytics
icon: chart
- id: psl_admin_settings
type: MenuLink
properties:
title: Settings
icon: settings
slots:
siderOpen:
blocks:
- id: psl_admin_sider_open
type: Box
style:
padding: 8px 12px
blocks:
- id: psl_admin_env_tag
type: Tag
properties:
title: Production
color: green
icon: Server
siderClosed:
blocks:
- id: psl_admin_sider_closed
type: Box
style:
padding: 8px
textAlign: center
blocks:
- id: psl_admin_env_tag_sm
type: Tag
properties:
title: Prod
color: green
footer:
blocks:
- id: psl_admin_footer_text
type: Paragraph
properties:
content: Admin Panel v2.4.1
style:
.element:
textAlign: center
margin: 0
color: "#999"
fontSize: 12
blocks:
- id: psl_admin_title
type: Title
properties:
content: Dashboard Overview
level: 3
- id: psl_admin_stats_row
type: Box
layout:
gap: 16
blocks:
- id: psl_admin_stat_users
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psl_admin_stat_users_val
type: Statistic
properties:
title: Total Users
value: 2847
prefixIcon: user
- id: psl_admin_stat_revenue
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psl_admin_stat_revenue_val
type: Statistic
properties:
title: Revenue
value: 58420
prefix: $
- id: psl_admin_stat_orders
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psl_admin_stat_orders_val
type: Statistic
properties:
title: Orders
value: 384
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `title` | string | - | Page title. Accepted for compatibility. |
| `theme` | object | - | Antd global design token overrides, such as colorPrimary or borderRadius, applied to everything in the page layout. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design component tokens](https://ant.design/docs/react/customize-theme#seedtoken). |
| `logo` | object | - | Header logo settings. By default, images are served from the app public folder and auto-swap between light and dark variants based on dark mode. See [Hosting Files](/hosting-files) for details. |
| `logo.src` | string | - | Logo image URL for desktop. Defaults to logo-light-theme.png or logo-dark-theme.png from the public folder (~250x72px), auto-selected based on dark mode. |
| `logo.srcMobile` | string | - | Logo image URL for mobile. Defaults to logo-square-light-theme.png or logo-square-dark-theme.png from the public folder (~125x125px), auto-selected based on dark mode. |
| `logo.alt` | string | `"Lowdefy"` | Logo alternative text. |
| `logo.style` | object | - | Css style object to apply to logo. |
| `sider` | object | - | Sider properties. |
| `sider.collapsedWidth` | integer | - | Width of the collapsed sidebar, by setting to 0 a special trigger will appear. |
| `sider.collapsible` | boolean | `false` | Show a trigger at the bottom of the sider that collapses and expands it, like the toggle button. |
| `sider.initialCollapsed` | boolean | `false` | Set the initial collapsed state. |
| `sider.width` | string \| number | - | Width of the sidebar. |
| `sider.hideToggleButton` | boolean | `false` | Hide toggle button in sider. |
| `siderStorageKey` | string | `"sider"` | localStorage key suffix for sider state persistence. Produces key 'lf-{siderStorageKey}-open', kept per app. |
| `header` | object | - | Header properties. |
| `header.contentStyle` | object | - | Header content css style object. |
| `toggleSiderButton` | object | - | Toggle sider button properties. |
| `footer` | object | - | Footer properties. |
| `footer.style` | object | - | Footer css style object. |
| `padding` | string | `"default"` | Space around the page content. `compact` tightens it to 16px for dense, data-heavy pages. `none` removes it so content such as a table or grid runs edge to edge; the breadcrumb keeps its own inset. Enum: `default`, `compact`, `none`. |
| `content` | object | - | Content properties. |
| `content.style` | object | - | Content css style object. |
| `breadcrumb` | object | - | Breadcrumb properties. |
| `breadcrumb.separator` | string | `"/"` | Use a custom separator string. |
| `breadcrumb.list` | array | - | List of breadcrumb links. |
| `breadcrumb.list.$.label` | string | - | Label of the breadcrumb link. |
| `breadcrumb.list.$.pageId` | string | - | Page id to link to when clicked. |
| `breadcrumb.list.$.url` | string | - | External url link. |
| `breadcrumb.list.$.style` | object | - | Css style to apply to link. |
| `breadcrumb.list.$.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to use an icon in breadcrumb link. |
| `breadcrumb.list.$.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `breadcrumb.list.$.icon.color` | string | - | Icon color. |
| `breadcrumb.list.$.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `breadcrumb.list.$.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `breadcrumb.list.$.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `breadcrumb.list.$.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `breadcrumb.list.$.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `breadcrumb.list.$.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `breadcrumb.list.$.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `breadcrumb.list.$.links` | array | - | Links shown in a dropdown menu on the breadcrumb item. |
| `breadcrumb.list.$.links.$.label` | string | - | Label of the dropdown link. |
| `breadcrumb.list.$.links.$.pageId` | string | - | Page id to link to when clicked. |
| `breadcrumb.list.$.links.$.url` | string | - | External url link. |
| `menu` | object | - | Menu properties. |
| `menu.links` | array | - | |
| `menu.links.$.id` | string | - | Menu item id. |
| `menu.links.$.pageId` | string | - | Page to link to. |
| `menu.links.$.properties` | object | - | properties from menu item. |
| `menu.links.$.properties.title` | string | - | Menu item title. |
| `menu.links.$.properties.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize icon on menu item. |
| `menu.links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `menu.links.$.properties.icon.color` | string | - | Icon color. |
| `menu.links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `menu.links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `menu.links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `menu.links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `menu.links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `menu.links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `menu.links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `menuLg` | object | - | Menu large screen properties. Overwrites menu properties on desktop screen sizes. |
| `menuMd` | object | - | Mobile menu properties. Overwrites menu properties on mobile screen sizes. |
| `notifications` | object | - | Notification bell icon with badge. Shown in the sider on desktop and the mobile header on small screens. Renders when configured. Use the link property to navigate when clicked. |
| `notifications.title` | string | `"Notifications"` | Label shown next to the bell icon when the sider is expanded. Hidden on mobile header and collapsed sider. |
| `notifications.link` | object | - | Link to navigate to when the notification bell is clicked. |
| `notifications.link.pageId` | string | - | Page to link to. |
| `notifications.link.url` | string | - | External URL to link to. |
| `notifications.link.newTab` | boolean | - | Open link in new tab. |
| `notifications.count` | number | - | Number to display on the badge. Set to 0 to hide the badge (unless showZero is true). |
| `notifications.dot` | boolean | `false` | Show a dot instead of a count number. |
| `notifications.showZero` | boolean | `false` | Show badge when count is zero. |
| `notifications.overflowCount` | number | `99` | Max count to show. Values above this display as "N+". |
| `notifications.color` | string | - | Badge color. |
| `notifications.icon` | string \| object | - | Icon for the notification button. Defaults to `bell`. |
| `notifications.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `notifications.icon.color` | string | - | Icon color. |
| `notifications.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `notifications.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `notifications.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `notifications.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `notifications.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `notifications.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `notifications.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `notifications.size` | string | `"small"` | Size of the notification button. Enum: `small`, `default`, `large`. |
| `profile` | object | - | Profile avatar with optional dropdown menu. Shown in the sider on desktop and the mobile header on small screens. Renders when configured. Use with the _user operator to populate from the authenticated user. |
| `profile.title` | string | `"Profile"` | Label shown next to the avatar when the sider is expanded. Hidden on mobile header and collapsed sider. |
| `profile.avatar` | object | - | Avatar display properties. |
| `profile.avatar.src` | string | - | Image URL for the avatar. Typically bound to _user: image. |
| `profile.avatar.content` | string | - | Text content inside the avatar (e.g. user initials). Shown when no src is provided. |
| `profile.avatar.icon` | string \| object | - | Icon to display in avatar when no src or content is set. Defaults to `user`. |
| `profile.avatar.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `profile.avatar.icon.color` | string | - | Icon color. |
| `profile.avatar.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `profile.avatar.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `profile.avatar.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `profile.avatar.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `profile.avatar.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `profile.avatar.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `profile.avatar.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `profile.avatar.color` | string | - | Background color of the avatar when not using src. |
| `profile.avatar.size` | string \| number | `"small"` | Size of the avatar: default, small, large or a pixel number. |
| `profile.avatar.shape` | string | `"circle"` | Shape of the avatar. Enum: `circle`, `square`. |
| `profile.links` | array | - | Dropdown menu items. Uses the same MenuLink/MenuGroup/MenuDivider schema as Menu. Compatible with _menu operator output for access-filtered menus. |
| `profile.links.$.id` | string | - | Menu item id. |
| `profile.links.$.type` | string | `"MenuLink"` | Menu item type. Enum: `MenuDivider`, `MenuLink`, `MenuGroup`. |
| `profile.links.$.pageId` | string | - | Page to link to. |
| `profile.links.$.url` | string | - | External URL to link to. |
| `profile.links.$.newTab` | boolean | - | Open link in new tab. |
| `profile.links.$.style` | object | - | CSS style applied to the link. |
| `profile.links.$.properties` | object | - | Properties for the menu item. |
| `profile.links.$.properties.title` | string | - | Menu item title. |
| `profile.links.$.properties.icon` | string \| object | - | Icon for the menu item. |
| `profile.links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `profile.links.$.properties.icon.color` | string | - | Icon color. |
| `profile.links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `profile.links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `profile.links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `profile.links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `profile.links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `profile.links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `profile.links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `profile.links.$.properties.danger` | boolean | `false` | Apply danger style to menu item. |
| `profile.links.$.properties.disabled` | boolean | `false` | Disable the menu item. |
| `profile.links.$.properties.dashed` | boolean | `false` | Whether the divider line is dashed. |
| `profile.links.$.properties.shortcut` | string | - | Keyboard shortcut. Renders a kbd badge floated to the far right and wires the key handler. Use "mod" for Cmd/Ctrl. |
| `profile.links.$.links` | array | - | Nested menu items for MenuGroup. |
| `profile.trigger` | string | `"hover"` | How the profile dropdown opens. Enum: `click`, `hover`. |
| `profile.placement` | string | `"bottomRight"` | Dropdown placement relative to the avatar. Enum: `bottomLeft`, `bottom`, `bottomRight`, `topLeft`, `top`, `topRight`. |
| `profile.arrow` | boolean \| object | `false` | Show arrow on the dropdown. |
| `profile.arrow.pointAtCenter` | boolean | - | |
| `darkModeToggle` | boolean | `false` | Show a dark mode toggle button in the sider and mobile header. Toggles the Ant Design dark theme for the entire page. Preference is persisted to localStorage. |
| `localeSelector` | boolean | `false` | Show a locale picker dropdown in the sider and mobile header. Lists locales declared in `config.i18n.locales` and dispatches `SetLocale` on selection. Renders nothing when `config.i18n` is not configured. |
| `iconsColor` | string | - | Color for notification and dark mode toggle icons. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onToggleSider` | \- | Trigger action when sider toggle button is clicked. |
| `onMenuItemClick` | \- | Trigger action when menu item is clicked. |
| `onMenuItemSelect` | \- | Trigger action when menu item is selected. |
| `onToggleMenuGroup` | \- | Trigger action when menu group is opened. |
| `onBreadcrumbClick` | \- | Trigger action when a breadcrumb item is clicked. |
| `onMobileMenuOpen` | \- | Trigger action when mobile menu is opened. |
| `onMobileMenuClose` | \- | Trigger action when mobile menu is closed. |
| `onToggleDrawer` | \- | Trigger action when mobile menu drawer is toggled. |
| `onProfileMenuClick` | `{ key, keyPath, pageId, url }` | Trigger action when a profile dropdown menu item is clicked. |
| `onProfileMenuOpen` | `{ open }` | Trigger action when the profile dropdown opens or closes. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The PageSidebarLayout element. |
| `/sider` | The PageSidebarLayout sider. |
| `/siderBody` | The box inside the sider that holds the toggle button, menu and sider slots. |
| `/siderHeader` | The box above the sider menu that holds the siderHeader or siderHeaderClosed slot. |
| `/menu` | The PageSidebarLayout menu. |
| `/mobileHeader` | The PageSidebarLayout mobile header. |
| `/mobileMenu` | The PageSidebarLayout mobile menu. |
| `/header` | The PageSidebarLayout header. |
| `/headerActions` | The header actions container (notifications, profile, dark mode toggle). |
| `/headerContent` | The PageSidebarLayout header content area (the header slot row). |
| `/logo` | The PageSidebarLayout logo. |
| `/notifications` | The notification bell button. |
| `/notificationsBadge` | The notification badge wrapper. |
| `/notificationsIcon` | The notification bell icon. |
| `/profile` | The profile avatar and dropdown wrapper. |
| `/profileAvatar` | The profile avatar element. |
| `/profileMenu` | The profile dropdown menu popup. |
| `/darkModeToggle` | The dark mode toggle button. |
| `/localeSelector` | The locale selector trigger. |
| `/localeSelectorMenu` | The locale selector dropdown popup. |
| `/content` | The PageSidebarLayout content. |
| `/breadcrumb` | The PageSidebarLayout breadcrumb. |
| `/footer` | The PageSidebarLayout footer. |
| `/toggleButton` | The PageSidebarLayout sider toggle button. |
| Slot | Description |
| --- | --- |
| `content` | Main page content. |
| `footer` | Page footer. |
| `header` | Additional header content. |
| `mobileDrawerContent` | Content in the mobile menu drawer. |
| `mobileDrawerFooter` | Footer in the mobile menu drawer. |
| `mobileDrawerHeader` | Content above the menu in the mobile menu drawer. |
| `mobileExtra` | Extra content in the mobile header bar. |
| `siderClosed` | Content shown in the sider when collapsed. |
| `siderHeader` | Content above the sider menu when expanded. It stays in place while the menu scrolls. |
| `siderHeaderClosed` | Content above the sider menu when collapsed. |
| `siderOpen` | Content shown in the sider when expanded. |
---
url: https://docs.lowdefy.com/md/container-blocks/pagesidermenu.md
---
# PageSiderMenu
Page layout with a sidebar navigation menu.
Dashboard
```yaml
- id: psm_basic
type: PageSiderMenu
properties:
sider:
width: 220
hideToggleButton: true
menu:
links:
- id: psm_basic_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: psm_basic_orders
type: MenuLink
properties:
title: Orders
icon: ShoppingCart
- id: psm_basic_products
type: MenuLink
properties:
title: Products
icon: grid
- id: psm_basic_settings
type: MenuLink
properties:
title: Settings
icon: settings
blocks:
- id: psm_basic_title
type: Title
properties:
content: Dashboard
level: 3
- id: psm_basic_stats
type: Box
layout:
gap: 16
blocks:
- id: psm_basic_stat_1
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psm_basic_stat_1_val
type: Statistic
properties:
title: Orders Today
value: 128
- id: psm_basic_stat_2
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psm_basic_stat_2_val
type: Statistic
properties:
title: Revenue
value: 4820
prefix: $
```
padding: compact trims the content padding from 40px to 16px, so data-heavy pages show more.
```yaml
- id: psm_compact
type: PageSiderMenu
properties:
padding: compact
menu:
links:
- id: psm_compact_dashboard
type: MenuLink
properties:
title: Dashboard
- id: psm_compact_invoices
type: MenuLink
properties:
title: Invoices
blocks:
- id: psm_compact_text
type: Paragraph
properties:
content: "padding: compact trims the content padding from 40px to 16px, so
data-heavy pages show more."
- id: psm_compact_card
type: Card
properties:
title: Recent invoices
padding: none
blocks:
- id: psm_compact_card_rows
type: Html
properties:
html: >
INV-1042 $1,280.00
INV-1041 $640.00
INV-1040 $2,115.50
INV-1039 $96.00
```
Website Redesign
Breadcrumb items support both simple strings and objects with label, icon, pageId, and url properties. Toggle dark mode to see the layout adapt automatically.
> 3 tasks due this week
```yaml
- id: psm_light
type: PageSiderMenu
properties:
darkModeToggle: true
sider:
width: 230
hideToggleButton: true
breadcrumb:
list:
- label: Home
icon: home
- label: Projects
- label: Website Redesign
menu:
links:
- id: psm_light_overview
type: MenuLink
properties:
title: Overview
icon: SquareKanban
- id: psm_light_tasks
type: MenuLink
properties:
title: Tasks
icon: SquareCheck
- id: psm_light_files
type: MenuLink
properties:
title: Files
icon: file
- id: psm_light_team
type: MenuLink
properties:
title: Team
icon: users
blocks:
- id: psm_light_title
type: Title
properties:
content: Website Redesign
level: 3
- id: psm_light_desc
type: Paragraph
properties:
content: Breadcrumb items support both simple strings and objects with label,
icon, pageId, and url properties. Toggle dark mode to see the layout
adapt automatically.
- id: psm_light_alert
type: Alert
properties:
message: 3 tasks due this week
type: warning
showIcon: true
```
All Users
Jane Cooper
Tom Wilson
```yaml
- id: psm_groups
type: PageSiderMenu
properties:
sider:
width: 240
hideToggleButton: false
menu:
links:
- id: psm_grp_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: psm_grp_users_group
type: MenuGroup
properties:
title: User Management
icon: users
links:
- id: psm_grp_all_users
type: MenuLink
properties:
title: All Users
- id: psm_grp_roles
type: MenuLink
properties:
title: Roles & Permissions
- id: psm_grp_content_group
type: MenuGroup
properties:
title: Content
icon: edit
links:
- id: psm_grp_articles
type: MenuLink
properties:
title: Articles
- id: psm_grp_categories
type: MenuLink
properties:
title: Categories
- id: psm_grp_settings
type: MenuLink
properties:
title: Settings
icon: settings
blocks:
- id: psm_grp_title
type: Title
properties:
content: All Users
level: 3
- id: psm_grp_card
type: Card
properties:
title: User List
blocks:
- id: psm_grp_user_1
type: Box
layout:
gap: 8
align: center
style:
padding: 8px 0
borderBottom: 1px solid var(--ant-color-border)
blocks:
- id: psm_grp_avatar_1
type: Avatar
layout:
flex: 0 0 auto
properties:
size: small
color: "#1677ff"
icon: user
- id: psm_grp_name_1
type: Paragraph
layout:
flex: 1 1 0
properties:
content: Jane Cooper
style:
.element:
margin: 0
- id: psm_grp_tag_1
type: Tag
layout:
flex: 0 0 auto
properties:
title: Admin
color: blue
- id: psm_grp_user_2
type: Box
layout:
gap: 8
align: center
style:
padding: 8px 0
blocks:
- id: psm_grp_avatar_2
type: Avatar
layout:
flex: 0 0 auto
properties:
size: small
color: "#52c41a"
icon: user
- id: psm_grp_name_2
type: Paragraph
layout:
flex: 1 1 0
properties:
content: Tom Wilson
style:
.element:
margin: 0
- id: psm_grp_tag_2
type: Tag
layout:
flex: 0 0 auto
properties:
title: Editor
color: green
```
Admin Dashboard
```yaml
- id: psm_profile
type: PageSiderMenu
properties:
darkModeToggle: true
sider:
width: 220
hideToggleButton: true
notifications:
count: 5
profile:
avatar:
content: JC
color: "#1677ff"
links:
- id: psm_prof_my_profile
type: MenuLink
properties:
title: My Profile
icon: user
- id: psm_prof_settings
type: MenuLink
properties:
title: Account Settings
icon: settings
- id: psm_prof_divider
type: MenuDivider
- id: psm_prof_logout
type: MenuLink
properties:
title: Sign Out
icon: logout
danger: true
menu:
links:
- id: psm_prof_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: psm_prof_users
type: MenuLink
properties:
title: Users
icon: users
- id: psm_prof_reports
type: MenuLink
properties:
title: Reports
icon: chart
blocks:
- id: psm_prof_title
type: Title
properties:
content: Admin Dashboard
level: 3
- id: psm_prof_stats
type: Box
layout:
gap: 16
blocks:
- id: psm_prof_stat_1
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psm_prof_stat_1_val
type: Statistic
properties:
title: Active Users
value: 1284
- id: psm_prof_stat_2
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psm_prof_stat_2_val
type: Statistic
properties:
title: Pending Requests
value: 23
```
Dashboard Overview
Sprint Progress
```yaml
- id: psm_full
type: PageSiderMenu
properties:
darkModeToggle: true
sider:
width: 240
hideToggleButton: true
notifications:
dot: true
profile:
avatar:
icon: user
color: "#1677ff"
breadcrumb:
separator: /
list:
- Admin
- Dashboard
menu:
links:
- id: psm_full_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: psm_full_analytics
type: MenuLink
properties:
title: Analytics
icon: chart
- id: psm_full_settings
type: MenuLink
properties:
title: Settings
icon: settings
slots:
sider:
blocks:
- id: psm_full_sider_box
type: Box
style:
padding: 12px
blocks:
- id: psm_full_progress_label
type: Paragraph
properties:
content: Sprint Progress
style:
.element:
margin: 0 0 8px 0
fontSize: 12
color: "#999"
- id: psm_full_progress
type: Progress
properties:
percent: 68
size: small
footer:
blocks:
- id: psm_full_footer_text
type: Paragraph
properties:
content: Admin Panel v2.4.1
style:
.element:
textAlign: center
margin: 0
color: "#999"
fontSize: 12
blocks:
- id: psm_full_title
type: Title
properties:
content: Dashboard Overview
level: 3
- id: psm_full_stats_row
type: Box
layout:
gap: 16
blocks:
- id: psm_full_stat_users
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psm_full_stat_users_val
type: Statistic
properties:
title: Total Users
value: 2847
prefixIcon: user
- id: psm_full_stat_revenue
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psm_full_stat_revenue_val
type: Statistic
properties:
title: Revenue
value: 58420
prefix: $
- id: psm_full_stat_orders
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: psm_full_stat_orders_val
type: Statistic
properties:
title: Orders
value: 384
```
Profile from _menu
> The profile dropdown links are populated using _menu operator, pulling from the menus defined in lowdefy.yaml. Click the avatar to see the dropdown.
```yaml
- id: psm_menu_op
type: PageSiderMenu
properties:
darkModeToggle: true
sider:
width: 220
hideToggleButton: true
notifications:
count: 4
link:
pageId: home
profile:
avatar:
content: JC
color: "#6366f1"
links:
_menu: default
menu:
links:
- id: psm_mo_dash
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: psm_mo_users
type: MenuLink
properties:
title: Users
icon: users
blocks:
- id: psm_mo_title
type: Title
properties:
content: Profile from _menu
level: 3
- id: psm_mo_info
type: Alert
properties:
message: The profile dropdown links are populated using _menu operator, pulling
from the menus defined in lowdefy.yaml. Click the avatar to see the
dropdown.
type: info
showIcon: true
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `logo` | object | - | Header logo settings. By default, images are served from the app public folder and auto-swap between light and dark variants based on dark mode. See [Hosting Files](/hosting-files) for details. |
| `logo.src` | string | - | Logo image URL for desktop. Defaults to logo-light-theme.png or logo-dark-theme.png from the public folder (~250x72px), auto-selected based on dark mode. |
| `logo.srcMobile` | string | - | Logo image URL for mobile. Defaults to logo-square-light-theme.png or logo-square-dark-theme.png from the public folder (~125x125px), auto-selected based on dark mode. |
| `logo.breakpoint` | number | - | Viewport width breakpoint (in px) for switching between mobile and desktop logo. Default is 577. |
| `logo.alt` | string | `"Lowdefy"` | Logo image alt text. |
| `header` | object | - | Header properties. |
| `sider` | object | - | Sider properties. |
| `sider.breakpoint` | string | `"sm"` | Breakpoint of the responsive layout. Enum: `xs`, `sm`, `md`, `lg`, `xl`. |
| `sider.collapsedWidth` | integer | - | Width of the collapsed sidebar, by setting to 0 a special trigger will appear. |
| `sider.collapsible` | boolean | `false` | Show a trigger at the bottom of the sider that collapses and expands it, like the toggle button. |
| `sider.initialCollapsed` | boolean | `false` | Set the initial collapsed state. Used as the fallback when no persisted preference exists in localStorage. |
| `sider.reverseArrow` | boolean | `false` | Direction of arrow, for a sider that expands from the right. |
| `sider.width` | string \| number | - | Width of the sidebar. |
| `sider.hideToggleButton` | boolean | `false` | Hide toggle button in sider. |
| `siderStorageKey` | string | `"sider"` | localStorage key suffix for sider state persistence. Produces key 'lf-{siderStorageKey}-open', kept per app. |
| `toggleSiderButton` | object | - | Toggle sider button properties. |
| `footer` | object | - | Footer properties. |
| `padding` | string | `"default"` | Space around the page content. `compact` tightens it to 16px for dense, data-heavy pages. `none` removes it so content such as a table or grid runs edge to edge; the breadcrumb keeps its own inset. Enum: `default`, `compact`, `none`. |
| `content` | object | - | Content properties. |
| `breadcrumb` | object | - | Breadcrumb properties. |
| `breadcrumb.separator` | string | `"/"` | Use a custom separator string. |
| `breadcrumb.list` | array | - | List of breadcrumb links. |
| `breadcrumb.list.$.label` | string | - | Label of the breadcrumb link. |
| `breadcrumb.list.$.pageId` | string | - | Page id to link to when clicked. |
| `breadcrumb.list.$.url` | string | - | External url link. |
| `breadcrumb.list.$.style` | object | - | Css style to apply to link. |
| `breadcrumb.list.$.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to use an icon in breadcrumb link. |
| `breadcrumb.list.$.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `breadcrumb.list.$.icon.color` | string | - | Icon color. |
| `breadcrumb.list.$.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `breadcrumb.list.$.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `breadcrumb.list.$.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `breadcrumb.list.$.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `breadcrumb.list.$.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `breadcrumb.list.$.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `breadcrumb.list.$.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `breadcrumb.list.$.links` | array | - | Links shown in a dropdown menu on the breadcrumb item. |
| `breadcrumb.list.$.links.$.label` | string | - | Label of the dropdown link. |
| `breadcrumb.list.$.links.$.pageId` | string | - | Page id to link to when clicked. |
| `breadcrumb.list.$.links.$.url` | string | - | External url link. |
| `menu` | object | - | Menu properties. |
| `menu.links` | array | - | |
| `menu.links.$.id` | string | - | Menu item id. |
| `menu.links.$.pageId` | string | - | Page to link to. |
| `menu.links.$.properties` | object | - | properties from menu item. |
| `menu.links.$.properties.title` | string | - | Menu item title. |
| `menu.links.$.properties.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize icon on menu item. |
| `menu.links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `menu.links.$.properties.icon.color` | string | - | Icon color. |
| `menu.links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `menu.links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `menu.links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `menu.links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `menu.links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `menu.links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `menu.links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `menuLg` | object | - | Menu large screen properties. Overwrites menu properties on desktop screen sizes. |
| `menuMd` | object | - | Mobile menu properties. Overwrites menu properties on mobile screen sizes. |
| `notifications` | object | - | Notification bell icon with badge in the header. Renders when configured. Use the link property to navigate when clicked. |
| `notifications.link` | object | - | Link to navigate to when the notification bell is clicked. |
| `notifications.link.pageId` | string | - | Page to link to. |
| `notifications.link.url` | string | - | External URL to link to. |
| `notifications.link.newTab` | boolean | - | Open link in new tab. |
| `notifications.count` | number | - | Number to display on the badge. Set to 0 to hide the badge (unless showZero is true). |
| `notifications.dot` | boolean | `false` | Show a dot instead of a count number. |
| `notifications.showZero` | boolean | `false` | Show badge when count is zero. |
| `notifications.overflowCount` | number | `99` | Max count to show. Values above this display as "N+". |
| `notifications.color` | string | - | Badge color. |
| `notifications.icon` | string \| object | - | Icon for the notification button. Defaults to `bell`. |
| `notifications.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `notifications.icon.color` | string | - | Icon color. |
| `notifications.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `notifications.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `notifications.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `notifications.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `notifications.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `notifications.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `notifications.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `notifications.size` | string | `"small"` | Size of the notification button. Enum: `small`, `default`, `large`. |
| `profile` | object | - | Profile avatar with optional dropdown menu in the header. Renders when configured. Use with the _user operator to populate from the authenticated user. |
| `profile.avatar` | object | - | Avatar display properties. |
| `profile.avatar.src` | string | - | Image URL for the avatar. Typically bound to _user: image. |
| `profile.avatar.content` | string | - | Text content inside the avatar (e.g. user initials). Shown when no src is provided. |
| `profile.avatar.icon` | string \| object | - | Icon to display in avatar when no src or content is set. Defaults to `user`. |
| `profile.avatar.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `profile.avatar.icon.color` | string | - | Icon color. |
| `profile.avatar.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `profile.avatar.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `profile.avatar.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `profile.avatar.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `profile.avatar.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `profile.avatar.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `profile.avatar.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `profile.avatar.color` | string | - | Background color of the avatar when not using src. |
| `profile.avatar.size` | string \| number | `"small"` | Size of the avatar: default, small, large or a pixel number. |
| `profile.avatar.shape` | string | `"circle"` | Shape of the avatar. Enum: `circle`, `square`. |
| `profile.links` | array | - | Dropdown menu items. Uses the same MenuLink/MenuGroup/MenuDivider schema as Menu. Compatible with _menu operator output for access-filtered menus. |
| `profile.links.$.id` | string | - | Menu item id. |
| `profile.links.$.type` | string | `"MenuLink"` | Menu item type. Enum: `MenuDivider`, `MenuLink`, `MenuGroup`. |
| `profile.links.$.pageId` | string | - | Page to link to. |
| `profile.links.$.url` | string | - | External URL to link to. |
| `profile.links.$.newTab` | boolean | - | Open link in new tab. |
| `profile.links.$.style` | object | - | CSS style applied to the link. |
| `profile.links.$.properties` | object | - | Properties for the menu item. |
| `profile.links.$.properties.title` | string | - | Menu item title. |
| `profile.links.$.properties.icon` | string \| object | - | Icon for the menu item. |
| `profile.links.$.properties.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `profile.links.$.properties.icon.color` | string | - | Icon color. |
| `profile.links.$.properties.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `profile.links.$.properties.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `profile.links.$.properties.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `profile.links.$.properties.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `profile.links.$.properties.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `profile.links.$.properties.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `profile.links.$.properties.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `profile.links.$.properties.danger` | boolean | `false` | Apply danger style to menu item. |
| `profile.links.$.properties.disabled` | boolean | `false` | Disable the menu item. |
| `profile.links.$.properties.dashed` | boolean | `false` | Whether the divider line is dashed. |
| `profile.links.$.properties.shortcut` | string | - | Keyboard shortcut. Renders a kbd badge floated to the far right and wires the key handler. Use "mod" for Cmd/Ctrl. |
| `profile.links.$.links` | array | - | Nested menu items for MenuGroup. |
| `profile.trigger` | string | `"hover"` | How the profile dropdown opens. Enum: `click`, `hover`. |
| `profile.placement` | string | `"bottomRight"` | Dropdown placement relative to the avatar. Enum: `bottomLeft`, `bottom`, `bottomRight`, `topLeft`, `top`, `topRight`. |
| `profile.arrow` | boolean \| object | `false` | Show arrow on the dropdown. |
| `profile.arrow.pointAtCenter` | boolean | - | |
| `darkModeToggle` | boolean | `false` | Show a dark mode toggle button in the header. Toggles the Ant Design dark theme for the entire page. Preference is persisted to localStorage. |
| `localeSelector` | boolean | `false` | Show a locale picker dropdown in the header. Lists locales declared in `config.i18n.locales` and dispatches `SetLocale` on selection. Renders nothing when `config.i18n` is not configured. |
| `theme` | object | - | Antd global design token overrides, such as colorPrimary or borderRadius, applied to everything in the page layout. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design component tokens](https://ant.design/docs/react/customize-theme#seedtoken). |
| Event | Event Data | Description |
| --- | --- | --- |
| `onBreadcrumbClick` | \- | Trigger action when a breadcrumb item is clicked. |
| `onChangeToggleSiderAffix` | \- | Trigger action when sider collapse button affix triggers a onChange event. |
| `onClose` | \- | Trigger action when menu is closed. |
| `onMenuItemSelect` | \- | Trigger action when menu item is selected. |
| `onMenuItemClick` | \- | Trigger action when menu item is clicked. |
| `onOpen` | \- | Trigger action when menu is open. |
| `onProfileMenuClick` | `{ key, keyPath, pageId, url }` | Trigger action when a profile dropdown menu item is clicked. |
| `onProfileMenuOpen` | `{ open }` | Trigger action when the profile dropdown opens or closes. |
| `onToggleDrawer` | \- | Trigger action when mobile menu drawer is toggled. |
| `onToggleMenuGroup` | \- | Trigger action when mobile menu group is opened. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The PageSiderMenu element. |
| `/header` | The PageSiderMenu header. |
| `/headerActions` | The header actions container (notifications, profile, dark mode toggle). |
| `/headerContent` | The PageSiderMenu header content area. |
| `/logo` | The PageSiderMenu logo. |
| `/notifications` | The notification bell button. |
| `/notificationsBadge` | The notification badge wrapper. |
| `/notificationsIcon` | The notification bell icon. |
| `/profile` | The profile avatar and dropdown wrapper. |
| `/profileAvatar` | The profile avatar element. |
| `/profileMenu` | The profile dropdown menu popup. |
| `/darkModeToggle` | The PageSiderMenu dark mode toggle button. |
| `/localeSelector` | The PageSiderMenu locale selector trigger. |
| `/localeSelectorMenu` | The PageSiderMenu locale selector dropdown popup. |
| `/mobileMenu` | The PageSiderMenu mobile menu. |
| `/layout` | The PageSiderMenu inner layout. |
| `/sider` | The PageSiderMenu sider. |
| `/siderBody` | The box inside the sider that holds the menu, sider slot and toggle button. |
| `/menu` | The PageSiderMenu menu. |
| `/content` | The PageSiderMenu content. |
| `/breadcrumb` | The PageSiderMenu breadcrumb. |
| `/footer` | The PageSiderMenu footer. |
| Slot | Description |
| --- | --- |
| `content` | Main page content. |
| `footer` | Page footer. |
| `header` | Additional header content. |
| `sider` | Sider content below the menu. |
---
url: https://docs.lowdefy.com/md/container-blocks/popover.md
---
# Popover
Popup card appearing when hovering or clicking a trigger element.
This is the popover body content. You can place any blocks here.
A popover without a title - just body content.
```yaml
- id: popover_basic
type: Popover
layout:
flex: 0 0 auto
properties:
title: Popover Title
slots:
popover:
blocks:
- id: popover_basic_content
type: Paragraph
properties:
content: This is the popover body content. You can place any blocks here.
blocks:
- id: popover_basic_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Hover me
color: primary
variant: solid
- id: popover_no_title
type: Popover
layout:
flex: 0 0 auto
slots:
popover:
blocks:
- id: popover_no_title_content
type: Paragraph
properties:
content: A popover without a title - just body content.
blocks:
- id: popover_no_title_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No title
color: default
variant: outlined
```
Popover placed at top.
Popover placed at topLeft.
Popover placed at topRight.
Popover placed at left.
Popover placed at right.
Popover placed at bottom (default).
```yaml
- id: popover_place_row_top
type: Box
layout:
gap: 8
justify: center
blocks:
- id: popover_pl_top
type: Popover
layout:
flex: 0 0 auto
properties:
title: Top
placement: top
slots:
popover:
blocks:
- id: popover_pl_top_msg
type: Paragraph
properties:
content: Popover placed at top.
blocks:
- id: popover_pl_top_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: top
color: primary
variant: solid
size: small
- id: popover_pl_topLeft
type: Popover
layout:
flex: 0 0 auto
properties:
title: Top Left
placement: topLeft
slots:
popover:
blocks:
- id: popover_pl_topLeft_msg
type: Paragraph
properties:
content: Popover placed at topLeft.
blocks:
- id: popover_pl_topLeft_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: topLeft
color: default
variant: outlined
size: small
- id: popover_pl_topRight
type: Popover
layout:
flex: 0 0 auto
properties:
title: Top Right
placement: topRight
slots:
popover:
blocks:
- id: popover_pl_topRight_msg
type: Paragraph
properties:
content: Popover placed at topRight.
blocks:
- id: popover_pl_topRight_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: topRight
color: default
variant: outlined
size: small
- id: popover_place_row_sides
type: Box
layout:
gap: 8
blocks:
- id: popover_pl_left
type: Popover
layout:
flex: 0 0 auto
properties:
title: Left
placement: left
slots:
popover:
blocks:
- id: popover_pl_left_msg
type: Paragraph
properties:
content: Popover placed at left.
blocks:
- id: popover_pl_left_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: left
color: primary
variant: solid
size: small
- id: popover_pl_right
type: Popover
layout:
flex: 0 0 auto
properties:
title: Right
placement: right
slots:
popover:
blocks:
- id: popover_pl_right_msg
type: Paragraph
properties:
content: Popover placed at right.
blocks:
- id: popover_pl_right_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: right
color: primary
variant: outlined
size: small
- id: popover_pl_bottom
type: Popover
layout:
flex: 0 0 auto
properties:
title: Bottom
placement: bottom
slots:
popover:
blocks:
- id: popover_pl_bottom_msg
type: Paragraph
properties:
content: Popover placed at bottom (default).
blocks:
- id: popover_pl_bottom_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: bottom (default)
color: default
variant: outlined
size: small
```
This popover appears on hover (default).
This popover appears on click. Click outside to close.
This popover appears on focus. Tab to the button or click it.
```yaml
- id: popover_trig_hover
type: Popover
layout:
flex: 0 0 auto
properties:
title: Hover Popover
trigger: hover
slots:
popover:
blocks:
- id: popover_trig_hover_msg
type: Paragraph
properties:
content: This popover appears on hover (default).
blocks:
- id: popover_trig_hover_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Hover (default)
color: primary
variant: solid
- id: popover_trig_click
type: Popover
layout:
flex: 0 0 auto
properties:
title: Click Popover
trigger: click
slots:
popover:
blocks:
- id: popover_trig_click_msg
type: Paragraph
properties:
content: This popover appears on click. Click outside to close.
blocks:
- id: popover_trig_click_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Click me
color: primary
variant: outlined
- id: popover_trig_focus
type: Popover
layout:
flex: 0 0 auto
properties:
title: Focus Popover
trigger: focus
slots:
popover:
blocks:
- id: popover_trig_focus_msg
type: Paragraph
properties:
content: This popover appears on focus. Tab to the button or click it.
blocks:
- id: popover_trig_focus_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Focus (tab to me)
color: primary
variant: dashed
```
Default background color.
A warm light yellow background.
A cool light blue background.
```yaml
- id: popover_col_row
type: Box
layout:
gap: 8
blocks:
- id: popover_col_default
type: Popover
layout:
flex: 0 0 auto
properties:
title: Default Color
slots:
popover:
blocks:
- id: popover_col_default_msg
type: Paragraph
properties:
content: Default background color.
blocks:
- id: popover_col_default_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Default
color: default
variant: outlined
size: small
- id: popover_col_yellow
type: Popover
layout:
flex: 0 0 auto
properties:
title: Light Yellow
color: "#fffbe6"
slots:
popover:
blocks:
- id: popover_col_yellow_msg
type: Paragraph
properties:
content: A warm light yellow background.
blocks:
- id: popover_col_yellow_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Light Yellow
color: gold
variant: outlined
size: small
- id: popover_col_blue
type: Popover
layout:
flex: 0 0 auto
properties:
title: Light Blue
color: "#e6f4ff"
slots:
popover:
blocks:
- id: popover_col_blue_msg
type: Paragraph
properties:
content: A cool light blue background.
blocks:
- id: popover_col_blue_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Light Blue
color: blue
variant: outlined
size: small
```
This popover is open by default when the page loads.
```yaml
- id: popover_defopen
type: Popover
layout:
flex: 0 0 auto
properties:
title: Open by Default
defaultOpen: true
placement: right
slots:
popover:
blocks:
- id: popover_defopen_msg
type: Paragraph
properties:
content: This popover is open by default when the page loads.
blocks:
- id: popover_defopen_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Open by default
color: green
variant: solid
```
Repositions automatically near viewport edges (default behavior).
Stays in the specified position even near edges.
```yaml
- id: popover_adj_on
type: Popover
layout:
flex: 0 0 auto
properties:
title: Auto Adjust
autoAdjustOverflow: true
placement: top
slots:
popover:
blocks:
- id: popover_adj_on_msg
type: Paragraph
properties:
content: Repositions automatically near viewport edges (default behavior).
blocks:
- id: popover_adj_on_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Auto adjust (default)
color: primary
variant: solid
- id: popover_adj_off
type: Popover
layout:
flex: 0 0 auto
properties:
title: Fixed Position
autoAdjustOverflow: false
placement: top
slots:
popover:
blocks:
- id: popover_adj_off_msg
type: Paragraph
properties:
content: Stays in the specified position even near edges.
blocks:
- id: popover_adj_off_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No auto adjust
color: default
variant: outlined
```
No delay on enter or leave.
1 second delay before showing.
Stays visible for 2 seconds after mouse leaves.
```yaml
- id: popover_del_fast
type: Popover
layout:
flex: 0 0 auto
properties:
title: Instant
mouseEnterDelay: 0
mouseLeaveDelay: 0
slots:
popover:
blocks:
- id: popover_del_fast_msg
type: Paragraph
properties:
content: No delay on enter or leave.
blocks:
- id: popover_del_fast_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No delay
color: primary
variant: solid
- id: popover_del_slow
type: Popover
layout:
flex: 0 0 auto
properties:
title: Slow Enter
mouseEnterDelay: 1
slots:
popover:
blocks:
- id: popover_del_slow_msg
type: Paragraph
properties:
content: 1 second delay before showing.
blocks:
- id: popover_del_slow_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: 1s enter delay
color: primary
variant: outlined
- id: popover_del_sticky
type: Popover
layout:
flex: 0 0 auto
properties:
title: Sticky
mouseLeaveDelay: 2
slots:
popover:
blocks:
- id: popover_del_sticky_msg
type: Paragraph
properties:
content: Stays visible for 2 seconds after mouse leaves.
blocks:
- id: popover_del_sticky_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: 2s leave delay
color: primary
variant: dashed
```
This popover has a custom z-index of 2000, useful when layering over modals or drawers.
```yaml
- id: popover_zindex
type: Popover
layout:
flex: 0 0 auto
properties:
title: Custom Z-Index
zIndex: 2000
slots:
popover:
blocks:
- id: popover_zindex_msg
type: Paragraph
properties:
content: This popover has a custom z-index of 2000, useful when layering over
modals or drawers.
blocks:
- id: popover_zindex_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Z-index 2000
color: primary
variant: solid
```
Custom inner style with larger border radius and a stronger shadow.
This popover has a fixed width of 400px and extra padding, useful for displaying larger content like forms or details.
```yaml
- id: popover_overlay_style
type: Popover
layout:
flex: 0 0 auto
properties:
title: Styled Overlay
overlayInnerStyle:
borderRadius: 16
boxShadow: 0 6px 16px rgba(0, 0, 0, 0.2)
slots:
popover:
blocks:
- id: popover_overlay_style_msg
type: Paragraph
properties:
content: Custom inner style with larger border radius and a stronger shadow.
blocks:
- id: popover_overlay_style_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom overlay style
color: primary
variant: solid
- id: popover_overlay_wide
type: Popover
layout:
flex: 0 0 auto
properties:
title: Wide Popover
overlayInnerStyle:
width: 400
padding: 20
slots:
popover:
blocks:
- id: popover_overlay_wide_msg
type: Paragraph
properties:
content: This popover has a fixed width of 400px and extra padding, useful for
displaying larger content like forms or details.
blocks:
- id: popover_overlay_wide_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Wide overlay
color: primary
variant: outlined
```
Opening or closing this popover triggers a DisplayMessage action.
This popover uses SetState to track that it was opened.
```yaml
- id: popover_event_open
type: Popover
layout:
flex: 0 0 auto
properties:
title: Event Popover
trigger: click
events:
onOpenChange:
- id: popover_event_open_msg
type: DisplayMessage
params:
content: Popover visibility changed!
duration: 2
slots:
popover:
blocks:
- id: popover_event_open_content
type: Paragraph
properties:
content: Opening or closing this popover triggers a DisplayMessage action.
blocks:
- id: popover_event_open_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Click to toggle
color: primary
variant: solid
icon: bell
- id: popover_event_state
type: Popover
layout:
flex: 0 0 auto
properties:
title: Track State
trigger: click
events:
onOpenChange:
- id: popover_event_state_set
type: SetState
params:
popover_was_opened: true
slots:
popover:
blocks:
- id: popover_event_state_content
type: Paragraph
properties:
content: This popover uses SetState to track that it was opened.
blocks:
- id: popover_event_state_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Track open state
color: primary
variant: outlined
```
JD
Jane Doe
jane.doe@example.com
```yaml
- id: popover_rich_profile
type: Popover
layout:
flex: 0 0 auto
properties:
title: User Profile
trigger: click
slots:
popover:
blocks:
- id: popover_rich_profile_row
type: Box
layout:
gap: 8
blocks:
- id: popover_rich_profile_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
content: JD
color: blue
- id: popover_rich_profile_info
type: Box
blocks:
- id: popover_rich_profile_name
type: Title
properties:
content: Jane Doe
level: 5
- id: popover_rich_profile_email
type: Paragraph
properties:
content: jane.doe@example.com
blocks:
- id: popover_rich_profile_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: View Profile
color: primary
variant: solid
icon: user
- id: popover_rich_actions
type: Popover
layout:
flex: 0 0 auto
properties:
title: Actions
trigger: click
slots:
popover:
blocks:
- id: popover_rich_actions_col
type: Box
layout:
gap: 4
direction: column
blocks:
- id: popover_rich_act_edit
type: Button
properties:
title: Edit
icon: edit
color: primary
variant: text
block: true
- id: popover_rich_act_copy
type: Button
properties:
title: Duplicate
icon: copy
color: default
variant: text
block: true
- id: popover_rich_act_del
type: Button
properties:
title: Delete
icon: delete
color: danger
variant: text
block: true
blocks:
- id: popover_rich_actions_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: More
icon: more
color: default
variant: outlined
```
This popover has a wider minimum title width of 300px using the titleMinWidth token.
Custom border radius of 20px for a softer appearance.
Custom elevated background color using the colorBgElevated theme token.
Increased inner padding (24px), custom title padding, and larger title margin bottom.
A visible border under the title using titleBorderBottom, plus innerContentPadding for spacing.
The zIndexPopup theme token sets the popover z-index at the theme level (default 1030).
```yaml
- id: popover_theme_wide
type: Popover
layout:
flex: 0 0 auto
properties:
title: Wide Title
theme:
titleMinWidth: 300
slots:
popover:
blocks:
- id: popover_theme_wide_msg
type: Paragraph
properties:
content: This popover has a wider minimum title width of 300px using the
titleMinWidth token.
blocks:
- id: popover_theme_wide_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Wide title (300px)
color: primary
variant: solid
- id: popover_theme_radius
type: Popover
layout:
flex: 0 0 auto
properties:
title: Large Radius
theme:
borderRadiusLG: 20
slots:
popover:
blocks:
- id: popover_theme_radius_msg
type: Paragraph
properties:
content: Custom border radius of 20px for a softer appearance.
blocks:
- id: popover_theme_radius_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Large radius
color: primary
variant: outlined
- id: popover_theme_bg
type: Popover
layout:
flex: 0 0 auto
properties:
title: Custom Background
slots:
popover:
blocks:
- id: popover_theme_bg_msg
type: Paragraph
properties:
content: Custom elevated background color using the colorBgElevated theme token.
blocks:
- id: popover_theme_bg_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom background
color: primary
variant: dashed
- id: popover_theme_padding
type: Popover
layout:
flex: 0 0 auto
properties:
title: Extra Padding
theme:
innerPadding: 24
titlePadding: 16px 24px
titleMarginBottom: 16
slots:
popover:
blocks:
- id: popover_theme_padding_msg
type: Paragraph
properties:
content: Increased inner padding (24px), custom title padding, and larger title
margin bottom.
blocks:
- id: popover_theme_padding_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Extra padding
color: default
variant: outlined
- id: popover_theme_border
type: Popover
layout:
flex: 0 0 auto
properties:
title: Title Border
theme:
titleBorderBottom: "1px solid #d9d9d9"
titleMarginBottom: 12
innerContentPadding: 8px 0
slots:
popover:
blocks:
- id: popover_theme_border_msg
type: Paragraph
properties:
content: A visible border under the title using titleBorderBottom, plus
innerContentPadding for spacing.
blocks:
- id: popover_theme_border_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Title border
color: default
variant: outlined
- id: popover_theme_zindex
type: Popover
layout:
flex: 0 0 auto
properties:
title: Custom Z-Index Token
theme:
zIndexPopup: 2050
slots:
popover:
blocks:
- id: popover_theme_zindex_msg
type: Paragraph
properties:
content: The zIndexPopup theme token sets the popover z-index at the theme level
(default 1030).
blocks:
- id: popover_theme_zindex_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Z-index token
color: default
variant: dashed
```
The element CSS key targets the outer Popover wrapper. Here it adds a pointer cursor on the trigger area.
The inner CSS key targets the popover inner container. Here it applies extra shadow and rounded corners.
The title CSS key styles the popover title area with blue text, bold weight, and a bottom border.
The content CSS key targets the popover content area. Here it adds a gray background, padding, and rounded corners.
```yaml
- id: popover_css_element
type: Popover
layout:
flex: 0 0 auto
class:
.element: cursor-pointer
properties:
title: Element CSS Key
trigger: click
slots:
popover:
blocks:
- id: popover_css_element_msg
type: Paragraph
properties:
content: The element CSS key targets the outer Popover wrapper. Here it adds a
pointer cursor on the trigger area.
blocks:
- id: popover_css_element_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Element key
color: primary
variant: solid
- id: popover_css_inner
type: Popover
layout:
flex: 0 0 auto
class:
.inner: shadow-xl rounded-xl
properties:
title: Inner CSS Key
slots:
popover:
blocks:
- id: popover_css_inner_msg
type: Paragraph
properties:
content: The inner CSS key targets the popover inner container. Here it applies
extra shadow and rounded corners.
blocks:
- id: popover_css_inner_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Inner key
color: primary
variant: outlined
- id: popover_css_title
type: Popover
layout:
flex: 0 0 auto
class:
.title: font-bold text-blue-600 border-b border-border pb-2
properties:
title: Title CSS Key
slots:
popover:
blocks:
- id: popover_css_title_msg
type: Paragraph
properties:
content: The title CSS key styles the popover title area with blue text, bold
weight, and a bottom border.
blocks:
- id: popover_css_title_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Title key
color: blue
variant: outlined
- id: popover_css_content
type: Popover
layout:
flex: 0 0 auto
class:
.content: bg-bg-layout p-4 rounded-md
properties:
title: Content CSS Key
slots:
popover:
blocks:
- id: popover_css_content_msg
type: Paragraph
properties:
content: The content CSS key targets the popover content area. Here it adds a
gray background, padding, and rounded corners.
blocks:
- id: popover_css_content_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Content key
color: default
variant: outlined
```
SC
Sarah Chen
Sarah Chen
Product Manager
```yaml
- id: popover_usercard
type: Popover
layout:
flex: 0 0 auto
properties:
trigger: click
overlayInnerStyle:
width: 320
padding: 0
slots:
popover:
blocks:
- id: popover_usercard_header
type: Box
class: bg-bg-layout p-4 rounded-t-lg
layout:
gap: 12
align: center
blocks:
- id: popover_usercard_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 48
color: "#1677ff"
- id: popover_usercard_info
type: Box
layout:
direction: column
gap: 2
blocks:
- id: popover_usercard_name
type: Title
properties:
content: Sarah Chen
level: 5
- id: popover_usercard_role
type: Paragraph
properties:
content: Product Manager
- id: popover_usercard_details
type: Descriptions
class: p-4
properties:
size: small
column: 1
items:
- label: Email
value: sarah.chen@company.com
- label: Team
value: Product
- label: Location
value: San Francisco, CA
- id: popover_usercard_actions_row
type: Box
class: px-4 pb-4
layout:
gap: 8
blocks:
- id: popover_usercard_msg_btn
type: Button
layout:
flex: 1 1 0
properties:
title: Message
icon: mail
color: primary
variant: solid
size: small
events:
onClick:
- id: popover_usercard_msg_action
type: DisplayMessage
params:
content: Opening chat with Sarah...
duration: 2
- id: popover_usercard_profile_btn
type: Button
layout:
flex: 1 1 0
properties:
title: View Profile
icon: user
color: default
variant: outlined
size: small
events:
onClick:
- id: popover_usercard_profile_action
type: Link
params:
url: https://example.com/profile
newTab: true
blocks:
- id: popover_usercard_trigger
type: Box
layout:
gap: 8
align: center
blocks:
- id: popover_usercard_trigger_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
content: SC
color: "#1677ff"
- id: popover_usercard_trigger_name
type: Paragraph
layout:
flex: 0 0 auto
properties:
content: Sarah Chen
```
```yaml
- id: popover_quickmenu
type: Popover
layout:
flex: 0 0 auto
properties:
trigger: click
placement: bottomRight
overlayInnerStyle:
width: 200
padding: 8
events:
onOpenChange:
- id: popover_quickmenu_state
type: SetState
params:
menu_toggled: true
slots:
popover:
blocks:
- id: popover_quickmenu_col
type: Box
layout:
direction: column
gap: 2
blocks:
- id: popover_quickmenu_new
type: Button
properties:
title: New Document
icon: FilePlus
color: primary
variant: text
block: true
events:
onClick:
- id: popover_quickmenu_new_action
type: DisplayMessage
params:
content: Creating new document...
duration: 2
- id: popover_quickmenu_upload
type: Button
properties:
title: Upload File
icon: upload
color: default
variant: text
block: true
events:
onClick:
- id: popover_quickmenu_upload_action
type: DisplayMessage
params:
content: Opening file picker...
duration: 2
- id: popover_quickmenu_divider
type: Divider
properties:
dashed: true
- id: popover_quickmenu_import
type: Button
properties:
title: Import from URL
icon: link
color: default
variant: text
block: true
events:
onClick:
- id: popover_quickmenu_import_action
type: DisplayMessage
params:
content: Enter a URL to import...
duration: 2
- id: popover_quickmenu_template
type: Button
properties:
title: Use Template
icon: grid
color: default
variant: text
block: true
blocks:
- id: popover_quickmenu_trigger
type: Button
layout:
flex: 0 0 auto
properties:
title: Create New
icon: add
color: primary
variant: solid
```
Monthly Budget
The monthly budget is the maximum amount your team can spend on resources each billing cycle. It resets on the 1st of every month.
You will receive a warning notification when 80% of the budget is used.
```yaml
- id: popover_help_row
type: Box
layout:
gap: 16
align: center
blocks:
- id: popover_help_label
type: Title
layout:
flex: 0 0 auto
properties:
content: Monthly Budget
level: 5
- id: popover_help_icon
type: Popover
layout:
flex: 0 0 auto
properties:
title: About Monthly Budget
placement: right
overlayInnerStyle:
width: 300
slots:
popover:
blocks:
- id: popover_help_desc
type: Paragraph
properties:
content: The monthly budget is the maximum amount your team can spend on
resources each billing cycle. It resets on the 1st of every
month.
- id: popover_help_note
type: Paragraph
class: text-text-secondary text-sm
properties:
content: You will receive a warning notification when 80% of the budget is used.
- id: popover_help_link
type: Button
properties:
title: Learn more
color: primary
variant: link
size: small
events:
onClick:
- id: popover_help_link_action
type: Link
params:
url: https://example.com/docs/budget
newTab: true
blocks:
- id: popover_help_trigger
type: Icon
layout:
flex: 0 0 auto
properties:
name: help
color: "#8c8c8c"
size: 18
- id: popover_help_input
type: NumberInput
layout:
flex: 1 1 0
properties:
label:
disabled: true
prefix: $
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `arrow` | boolean \| object | `true` | Whether to show the arrow. Set `{ pointAtCenter: true }` to point the arrow at the center of the target. |
| `arrow.pointAtCenter` | boolean | `false` | Whether the arrow is pointed at the center of target. |
| `destroyOnHidden` | boolean | `false` | Unmount the blocks inside the popover when it closes, so they mount again each time it opens. |
| `title` | string | - | Title of the card - supports html. |
| `color` | string | - | Popover background color. |
| `defaultOpen` | boolean | `false` | Whether the popover is open by default. |
| `autoAdjustOverflow` | boolean | `true` | Whether to adjust popup placement automatically when popup is off screen |
| `placement` | string | `"top"` | Placement of the popover. Enum: `top`, `topLeft`, `topRight`, `left`, `leftTop`, `leftBottom`, `right`, `rightTop`, `rightBottom`, `bottom`, `bottomLeft`, `bottomRight`. |
| `trigger` | string | `"hover"` | Trigger mode which executes the popover. `contextMenu` opens the popover on right click. Enum: `hover`, `click`, `focus`, `contextMenu`. |
| `zIndex` | number | - | Z-index of the popover. |
| `overlayInnerStyle` | object | - | Style of overlay inner div. Prefer `style.inner`. |
| `mouseEnterDelay` | number | `0.1` | Delay in seconds, before the popover is shown on mouse enter. |
| `mouseLeaveDelay` | number | `0.1` | Delay in seconds, before the popover is hidden on mouse leave. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design popover tokens](https://ant.design/components/popover#design-token). |
| `theme.width` | number \| string | - | Width of the popover. |
| `theme.minWidth` | number \| string | - | Minimum width of the popover. |
| `theme.titleMinWidth` | number \| string | `177` | Minimum width of the popover when it has a title. |
| `theme.zIndexPopup` | number | `1030` | Z-index of the popover. |
| `theme.innerPadding` | number \| string | `12` | Padding inside the popover content area. |
| `theme.titlePadding` | number \| string | - | Padding of the title area. |
| `theme.titleMarginBottom` | number | `8` | Margin bottom of the title. |
| `theme.titleBorderBottom` | string | `"none"` | Border bottom of the title area. |
| `theme.innerContentPadding` | number \| string | `0` | Padding of the inner content area. |
| `theme.colorBgElevated` | string | - | Background color of the popover. |
| `theme.borderRadiusLG` | number | `8` | Border radius of the popover container. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onOpenChange` | `{ open }` | Trigger actions when visibility of the popover card is changed. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Popover element. |
| `/inner` | The Popover inner. |
| `/title` | The Popover title. |
| `/content` | The Popover content. |
| Slot | Description |
| --- | --- |
| `content` | Blocks that trigger the Popover. |
| `popover` | Blocks inside the popup. |
---
url: https://docs.lowdefy.com/md/container-blocks/result.md
---
# Result
Result page with status icon, title, and extra actions.
```yaml
- id: status_success
type: Result
properties:
status: success
title: Successfully Purchased Cloud Server
subTitle: "Order number: 2026-0342-8756-0028. Cloud server configuration takes
1-5 minutes, please wait."
- id: status_error
type: Result
properties:
status: error
title: Submission Failed
subTitle: Please check and modify the following information before resubmitting.
- id: status_info
type: Result
properties:
status: info
title: Your Operation Has Been Executed
subTitle: We will review your request and respond within 24 hours.
- id: status_warning
type: Result
properties:
status: warning
title: There Are Some Problems With Your Operation
subTitle: Please review and correct the issues listed below before proceeding.
```
```yaml
- id: http_404
type: Result
properties:
status: "404"
title: "404"
subTitle: Sorry, the page you visited does not exist.
- id: http_403
type: Result
properties:
status: "403"
title: "403"
subTitle: Sorry, you are not authorized to access this page.
- id: http_500
type: Result
properties:
status: "500"
title: "500"
subTitle: Sorry, something went wrong on our server.
```
```yaml
- id: extra_success
type: Result
properties:
status: success
title: Payment Successful
subTitle: "Order number: 2026-0815-9932. Your receipt has been emailed to you."
slots:
extra:
blocks:
- id: extra_success_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: extra_success_home
type: Button
layout:
flex: 0 0 auto
properties:
title: Back to Home
color: primary
variant: solid
- id: extra_success_orders
type: Button
layout:
flex: 0 0 auto
properties:
title: View Orders
color: default
variant: outlined
- id: extra_error
type: Result
properties:
status: error
title: Submission Failed
subTitle: Please check and modify the following information before resubmitting.
slots:
extra:
blocks:
- id: extra_error_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: extra_error_retry
type: Button
layout:
flex: 0 0 auto
properties:
title: Try Again
color: primary
variant: solid
icon: refresh
- id: extra_error_support
type: Button
layout:
flex: 0 0 auto
properties:
title: Contact Support
color: default
variant: outlined
icon: Headset
- id: extra_404
type: Result
properties:
status: "404"
title: "404"
subTitle: Sorry, the page you visited does not exist.
slots:
extra:
blocks:
- id: extra_404_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Back Home
color: primary
variant: solid
- id: extra_403
type: Result
properties:
status: "403"
title: "403"
subTitle: Sorry, you are not authorized to access this page.
slots:
extra:
blocks:
- id: extra_403_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Back Home
color: primary
variant: solid
- id: extra_500
type: Result
properties:
status: "500"
title: "500"
subTitle: Sorry, something went wrong on our server.
slots:
extra:
blocks:
- id: extra_500_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Back Home
color: primary
variant: solid
```
```yaml
- id: child_error
type: Result
properties:
status: error
title: Submission Failed
subTitle: Please check and modify the following information before resubmitting.
slots:
extra:
blocks:
- id: child_error_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: child_error_retry_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Try Again
color: primary
variant: solid
- id: child_error_modify_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Modify Details
color: default
variant: outlined
blocks:
- id: child_error_details
type: Descriptions
properties:
title: Error Details
bordered: true
size: small
column: 1
items:
- label: Field
value: Email Address
- label: Issue
value: Invalid email format — must include @ symbol
- label: Field
value: Phone Number
- label: Issue
value: Phone number must be 10 digits
- id: child_success
type: Result
properties:
status: success
title: Application Submitted
subTitle: "Reference: APP-2026-1234. We will review and respond within 3
business days."
slots:
extra:
blocks:
- id: child_success_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: child_success_dashboard_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Go to Dashboard
color: primary
variant: solid
- id: child_success_track_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Track Application
color: default
variant: outlined
blocks:
- id: child_success_summary
type: Descriptions
properties:
title: Submission Summary
bordered: true
size: small
column: 1
items:
- label: Applicant
value: Jane Smith
- label: Submitted
value: March 10, 2026 at 14:32
- label: Type
value: Business License Renewal
- label: Status
value: Under Review
```
```yaml
- id: icon_rocket
type: Result
properties:
status: info
title: Deployment in Progress
subTitle: Your application is being deployed to production. This usually takes
2-5 minutes.
icon:
name: Rocket
color: "#1677ff"
size: 72
- id: icon_lock
type: Result
properties:
status: warning
title: Account Locked
subTitle: Your account has been temporarily locked due to multiple failed login
attempts. Try again in 30 minutes.
icon:
name: lock
color: "#faad14"
size: 72
- id: icon_mail
type: Result
properties:
status: success
title: Email Verified
subTitle: Your email address has been successfully verified. You can now access
all features.
icon:
name: mail
color: "#52c41a"
size: 72
- id: icon_cloud
type: Result
properties:
status: success
title: Upload Complete
subTitle: All 24 files have been uploaded successfully to your cloud storage.
icon:
name: CloudUpload
color: "#1677ff"
size: 72
```
```yaml
- id: scenario_payment_success
type: Result
properties:
status: success
title: Payment Successful
subTitle: "Transaction ID: TXN-2026-0310-5847. Amount: $299.00 charged to Visa
ending 4242."
slots:
extra:
blocks:
- id: scenario_payment_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: scenario_payment_receipt_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Download Receipt
color: primary
variant: solid
icon: download
- id: scenario_payment_orders_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: View All Orders
color: default
variant: outlined
blocks:
- id: scenario_payment_details
type: Descriptions
properties:
title: Order Summary
bordered: true
size: small
column: 1
items:
- label: Product
value: Annual Pro Plan
- label: Amount
value: $299.00
- label: Payment Method
value: Visa ending 4242
- label: Billing Email
value: jane.smith@example.com
- label: Next Renewal
value: March 10, 2027
- id: scenario_payment_failed
type: Result
properties:
status: error
title: Payment Failed
subTitle: Your card was declined. Please try a different payment method or
contact your bank.
slots:
extra:
blocks:
- id: scenario_payment_failed_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: scenario_payment_failed_retry_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Try Different Card
color: primary
variant: solid
icon: CreditCard
- id: scenario_payment_failed_cancel_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Cancel Order
color: default
variant: outlined
```
```yaml
- id: scenario_permission_denied
type: Result
properties:
status: "403"
title: Permission Denied
subTitle: You need admin privileges to access the User Management panel. Contact
your organization administrator.
slots:
extra:
blocks:
- id: scenario_perm_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: scenario_perm_request_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Request Access
color: primary
variant: solid
icon: Key
- id: scenario_perm_back_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Go Back
color: default
variant: outlined
- id: scenario_page_not_found
type: Result
properties:
status: "404"
title: Page Not Found
subTitle: The page /dashboard/reports/q4-2025 does not exist or has been moved.
slots:
extra:
blocks:
- id: scenario_notfound_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: scenario_notfound_home_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Back to Dashboard
color: primary
variant: solid
- id: scenario_notfound_search_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Search
color: default
variant: outlined
icon: search
- id: scenario_server_error
type: Result
properties:
status: "500"
title: Service Unavailable
subTitle: "We are experiencing technical difficulties. Error reference:
ERR-2026-0310-7721."
slots:
extra:
blocks:
- id: scenario_server_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: scenario_server_refresh_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Refresh Page
color: primary
variant: solid
icon: refresh
- id: scenario_server_status_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: System Status
color: default
variant: outlined
```
```yaml
- id: scenario_form_submitted
type: Result
properties:
status: success
title: Form Submitted Successfully
subTitle: Thank you for your feedback. Our team will review it and get back to
you within 48 hours.
slots:
extra:
blocks:
- id: scenario_form_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: scenario_form_new_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Submit Another
color: primary
variant: solid
- id: scenario_form_home_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Return Home
color: default
variant: outlined
- id: scenario_account_created
type: Result
properties:
status: success
title: Account Created
subTitle: Welcome aboard! A verification email has been sent to your inbox.
Please verify within 24 hours.
icon:
name: UserPlus
color: "#52c41a"
size: 72
slots:
extra:
blocks:
- id: scenario_acct_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: scenario_acct_login_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Go to Login
color: primary
variant: solid
- id: scenario_acct_resend_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Resend Verification
color: default
variant: outlined
icon: mail
- id: scenario_subscription_expired
type: Result
properties:
status: warning
title: Subscription Expired
subTitle: Your Pro plan expired on March 1, 2026. Renew now to continue
accessing premium features.
slots:
extra:
blocks:
- id: scenario_sub_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: scenario_sub_renew_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Renew Subscription
color: primary
variant: solid
icon: CreditCard
- id: scenario_sub_plans_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: View Plans
color: default
variant: outlined
```
```yaml
- id: title_only
type: Result
properties:
status: success
title: Operation Completed
- id: subtitle_only
type: Result
properties:
status: info
subTitle: Your changes have been saved. No further action is required.
- id: html_title
type: Result
properties:
status: success
title: "Order #ORD-2026-4455 Confirmed "
subTitle: "Estimated delivery: March 15, 2026 . Track your package in the
orders section."
- id: long_content
type: Result
properties:
status: info
title: System Maintenance Scheduled
subTitle: Our platform will undergo scheduled maintenance on Saturday, March 15,
2026 from 02:00 to 06:00 UTC. During this window, the application may be
intermittently unavailable. All data will be preserved and no action is
required on your part. We apologize for any inconvenience.
```
```yaml
- id: compact_success
type: Result
properties:
status: success
title: Saved
style:
.element:
padding: 16px 24px
- id: compact_error
type: Result
properties:
status: error
title: Failed
subTitle: Please try again.
style:
.element:
padding: 16px 24px
- id: compact_warning
type: Result
properties:
status: warning
title: Attention Required
style:
.element:
padding: 16px 24px
- id: compact_info
type: Result
properties:
status: info
title: Processing
subTitle: Please wait a moment.
style:
.element:
padding: 16px 24px
```
```yaml
- id: styled_success_card
type: Result
class: bg-bg-layout rounded-lg border border-border
properties:
status: success
title: Environment Ready
subTitle: Your staging environment has been provisioned and is ready for deployment.
- id: styled_error_card
type: Result
class: bg-bg-layout rounded-lg border border-border
properties:
status: error
title: Build Failed
subTitle: The CI pipeline encountered 3 errors during the build step. Check the
logs for details.
- id: styled_warning_card
type: Result
class: bg-bg-layout rounded-lg border border-border
properties:
status: warning
title: Rate Limit Approaching
subTitle: You have used 85% of your monthly API quota. Consider upgrading your plan.
- id: styled_info_card
type: Result
class: bg-bg-layout rounded-lg border border-border
properties:
status: info
title: New Features Available
subTitle: Version 4.2 includes real-time collaboration and improved dashboard
analytics.
- id: styled_gradient
type: Result
class: bg-gradient-to-br from-primary/10 to-primary/5 rounded-lg border
border-border
properties:
status: success
title: Welcome to Your Workspace
subTitle: Your team workspace has been created. Invite members to get started.
icon:
name: users
color: "#722ed1"
size: 72
- id: styled_dark
type: Result
class: bg-bg-layout rounded-lg
style:
.element:
color: white
properties:
status: success
title: Deployment Complete
subTitle: All services are running on the latest version.
```
```yaml
- id: inline_bordered
type: Result
properties:
status: info
title: Verification Required
subTitle: Please verify your identity to continue. Check your email for the
verification code.
style:
.element:
border: "2px solid #1677ff"
borderRadius: 12px
padding: 32px
- id: inline_shadow
type: Result
properties:
status: success
title: Connected
subTitle: Your database connection has been established successfully.
style:
.element:
boxShadow: 0 4px 16px rgba(0, 0, 0, 0.08)
borderRadius: 12px
padding: 32px
- id: inline_max_width
type: Result
properties:
status: warning
title: Storage Almost Full
subTitle: You have used 9.2 GB of your 10 GB storage limit. Delete files or
upgrade your plan.
style:
.element:
maxWidth: 480px
margin: 0 auto
border: "1px solid #faad14"
borderRadius: 8px
padding: 24px
```
```yaml
- id: theme_large_title
type: Result
properties:
status: success
title: All Systems Operational
subTitle: All 12 services are running normally.
theme:
titleFontSize: 32
subtitleFontSize: 18
- id: theme_small_icon
type: Result
properties:
status: info
title: Update Available
subTitle: A new version is ready to install.
theme:
iconFontSize: 48
titleFontSize: 20
- id: theme_custom_colors
type: Result
properties:
status: success
title: Invitation Accepted
subTitle: You have joined the Design Team workspace.
theme:
colorSuccess: "#389e0d"
colorTextHeading: "#135200"
colorTextDescription: "#595959"
- id: theme_branded
type: Result
properties:
status: info
title: Welcome to Acme Corp
subTitle: Your enterprise account is ready. Start by configuring your first project.
theme:
colorInfo: "#6366f1"
titleFontSize: 28
subtitleFontSize: 16
iconFontSize: 80
```
```yaml
- id: fullpage_404
type: Result
style:
.element:
minHeight: 320px
display: flex
flexDirection: column
justifyContent: center
properties:
status: "404"
title: Page Not Found
subTitle: The page you are looking for might have been removed, had its name
changed, or is temporarily unavailable.
slots:
extra:
blocks:
- id: fullpage_404_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: fullpage_404_home_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Take Me Home
color: primary
variant: solid
size: large
icon: home
- id: fullpage_404_report_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Report Issue
color: default
variant: outlined
size: large
- id: fullpage_500
type: Result
style:
.element:
minHeight: 320px
display: flex
flexDirection: column
justifyContent: center
properties:
status: "500"
title: Something Went Wrong
subTitle: Our engineering team has been automatically notified. Please try again
in a few minutes.
slots:
extra:
blocks:
- id: fullpage_500_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: fullpage_500_retry_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Retry
color: primary
variant: solid
size: large
icon: refresh
- id: fullpage_500_status_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Check Status Page
color: default
variant: outlined
size: large
- id: fullpage_403
type: Result
style:
.element:
minHeight: 320px
display: flex
flexDirection: column
justifyContent: center
properties:
status: "403"
title: Access Restricted
subTitle: This resource requires elevated permissions. If you believe this is an
error, contact your system administrator.
slots:
extra:
blocks:
- id: fullpage_403_extra_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: fullpage_403_login_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Sign In as Different User
color: primary
variant: solid
size: large
icon: user
- id: fullpage_403_back_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Go Back
color: default
variant: outlined
size: large
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize icon to use as result image. |
| `icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `icon.color` | string | - | Icon color. |
| `icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `status` | string | `"info"` | Status of the result. Determines image and color. Enum: `success`, `error`, `info`, `warning`, `404`, `403`, `500`. |
| `subTitle` | string | - | Result subtitle or secondary text - supports html. |
| `title` | string | - | Result title or primary text - supports html. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design result tokens](https://ant.design/components/result#design-token). |
| `theme.titleFontSize` | number | `24` | Font size of the result title. |
| `theme.subtitleFontSize` | number | `14` | Font size of the result subtitle. |
| `theme.iconFontSize` | number | `72` | Font size of the result status icon. |
| `theme.extraMargin` | string | `"24px 0 0 0"` | Margin applied to the extra content area. |
| `theme.colorSuccess` | string | - | Color used for the success status icon. |
| `theme.colorError` | string | - | Color used for the error status icon. |
| `theme.colorInfo` | string | - | Color used for the info status icon. |
| `theme.colorWarning` | string | - | Color used for the warning status icon. |
| `theme.colorTextHeading` | string | - | Color of the result title text. |
| `theme.colorTextDescription` | string | - | Color of the result subtitle text. |
| `theme.paddingLG` | number | `24` | Large padding value applied to the result container. |
| `theme.lineHeight` | number | `1.5714285714285714` | Line height used for result text content. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Result element. |
| `/icon` | The icon in the Result. |
| `/title` | The Result title. |
| `/subTitle` | The Result subtitle. |
| Slot | Description |
| --- | --- |
| `content` | Additional content below the Result. |
| `extra` | Extra content, typically action buttons. |
---
url: https://docs.lowdefy.com/md/container-blocks/sider.md
---
# Sider
Sidebar layout container for page navigation.
The Sider block provides a sidebar within a Layout. It supports collapsing, themes, breakpoints, and custom widths. Place navigation menus or supplementary content inside the sider.
```yaml
- id: basic_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: basic_sider
type: Sider
properties:
theme: light
width: 200
blocks:
- id: basic_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: basic_home
type: MenuLink
properties:
title: Home
icon: home
- id: basic_users
type: MenuLink
properties:
title: Users
icon: user
- id: basic_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: basic_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: basic_content_text
type: Paragraph
properties:
content: The Sider block provides a sidebar within a Layout. It supports
collapsing, themes, breakpoints, and custom widths. Place
navigation menus or supplementary content inside the sider.
```
Setting theme to "dark" gives the sider a dark background with light text. Match the Menu theme to the sider theme for a consistent appearance.
```yaml
- id: dark_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: dark_sider
type: Sider
properties:
theme: dark
width: 200
blocks:
- id: dark_menu
type: Menu
properties:
mode: inline
theme: dark
links:
- id: dark_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: dark_analytics
type: MenuLink
properties:
title: Analytics
icon: chart
- id: dark_files
type: MenuLink
properties:
title: Files
icon: file
- id: dark_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: dark_content_text
type: Paragraph
properties:
content: Setting theme to "dark" gives the sider a dark background with light
text. Match the Menu theme to the sider theme for a consistent
appearance.
```
With collapsible set to true a collapse trigger appears at the bottom. Toggle between expanded and collapsed states. Menu icons remain visible when collapsed.
```yaml
- id: collapsible_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: collapsible_sider
type: Sider
properties:
theme: light
width: 220
collapsible: true
initialCollapsed: false
blocks:
- id: collapsible_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: col_inbox
type: MenuLink
properties:
title: Inbox
icon: Inbox
- id: col_starred
type: MenuLink
properties:
title: Starred
icon: star
- id: col_sent
type: MenuLink
properties:
title: Sent
icon: send
- id: collapsible_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: collapsible_content_text
type: Paragraph
properties:
content: With collapsible set to true a collapse trigger appears at the bottom.
Toggle between expanded and collapsed states. Menu icons remain
visible when collapsed.
```
This sider starts collapsed with initialCollapsed set to true. Click the collapse trigger to expand it.
```yaml
- id: init_collapsed_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: init_collapsed_sider
type: Sider
properties:
theme: light
width: 200
collapsible: true
initialCollapsed: true
blocks:
- id: init_collapsed_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: ic_overview
type: MenuLink
properties:
title: Overview
icon: grid
- id: ic_reports
type: MenuLink
properties:
title: Reports
icon: document
- id: ic_config
type: MenuLink
properties:
title: Configuration
icon: Wrench
- id: init_collapsed_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: init_collapsed_content_text
type: Paragraph
properties:
content: This sider starts collapsed with initialCollapsed set to true. Click
the collapse trigger to expand it.
```
Setting collapsedWidth to 0 completely hides the sider when collapsed and shows a special floating trigger. Useful for mobile-friendly layouts where sidebar space needs to be fully reclaimed.
```yaml
- id: cw_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: cw_sider
type: Sider
properties:
theme: dark
width: 240
collapsedWidth: 0
collapsible: true
initialCollapsed: true
blocks:
- id: cw_menu
type: Menu
properties:
mode: inline
theme: dark
links:
- id: cw_projects
type: MenuLink
properties:
title: Projects
icon: SquareKanban
- id: cw_tasks
type: MenuLink
properties:
title: Tasks
icon: SquareCheck
- id: cw_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: cw_content_text
type: Paragraph
properties:
content: Setting collapsedWidth to 0 completely hides the sider when collapsed
and shows a special floating trigger. Useful for mobile-friendly
layouts where sidebar space needs to be fully reclaimed.
```
The Sider is placed on the right side of the layout with reverseArrow set to true. This flips the collapse arrow direction to match the right-side placement.
```yaml
- id: reverse_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: reverse_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: reverse_content_text
type: Paragraph
properties:
content: The Sider is placed on the right side of the layout with reverseArrow
set to true. This flips the collapse arrow direction to match the
right-side placement.
- id: reverse_sider
type: Sider
properties:
theme: light
width: 200
collapsible: true
initialCollapsed: false
reverseArrow: true
style:
borderLeft: "1px solid #f0f0f0"
blocks:
- id: reverse_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: rev_details
type: MenuLink
properties:
title: Details
icon: info
- id: rev_history
type: MenuLink
properties:
title: History
icon: history
```
The onBreakpoint event fires when the viewport crosses the breakpoint, with `broken` true below it. Here it calls the sider's setOpen method, so the sider collapses below the large (lg) breakpoint. Supported values are xs, sm, md, lg, xl, xxl and xxxl.
```yaml
- id: bp_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: bp_sider
type: Sider
properties:
theme: light
width: 200
collapsible: true
initialCollapsed: false
breakpoint: lg
events:
onBreakpoint:
- id: bp_sider_set_open
type: CallMethod
params:
blockId: bp_sider
method: setOpen
args:
- open:
_not:
_event: broken
blocks:
- id: bp_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: bp_home
type: MenuLink
properties:
title: Home
icon: home
- id: bp_search
type: MenuLink
properties:
title: Search
icon: search
- id: bp_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: bp_content_text
type: Paragraph
properties:
content: The onBreakpoint event fires when the viewport crosses the breakpoint,
with `broken` true below it. Here it calls the sider's setOpen
method, so the sider collapses below the large (lg) breakpoint.
Supported values are xs, sm, md, lg, xl, xxl and xxxl.
```
The width property accepts a number (pixels) or string value. Here the sider is set to 300px wide, providing more room for longer menu labels or nested navigation.
```yaml
- id: width_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: width_sider
type: Sider
properties:
theme: light
width: 300
collapsible: false
initialCollapsed: false
blocks:
- id: width_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: width_nav1
type: MenuLink
properties:
title: Getting Started
icon: Rocket
- id: width_nav2
type: MenuLink
properties:
title: Documentation
icon: Book
- id: width_nav3
type: MenuLink
properties:
title: API Reference
icon: CodeXml
- id: width_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: width_content_text
type: Paragraph
properties:
content: The width property accepts a number (pixels) or string value. Here the
sider is set to 300px wide, providing more room for longer menu
labels or nested navigation.
```
The Sider fires onOpen and onClose events when it expands or collapses. Use these events with SetState or other actions to react to sider state changes. Toggle the sider to see the state update above.
```yaml
- id: events_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: events_sider
type: Sider
properties:
theme: light
width: 200
collapsible: true
initialCollapsed: false
events:
onOpen:
- id: events_on_open_action
type: SetState
params:
siderState: open
onClose:
- id: events_on_close_action
type: SetState
params:
siderState: closed
blocks:
- id: events_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: events_nav_home
type: MenuLink
properties:
title: Home
icon: home
- id: events_nav_alerts
type: MenuLink
properties:
title: Alerts
icon: bell
- id: events_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: events_state_label
type: Paragraph
properties:
content:
_nunjucks:
template: "Sider state: {{ siderState }}"
on:
_state: true
- id: events_content_text
type: Paragraph
properties:
content: The Sider fires onOpen and onClose events when it expands or collapses.
Use these events with SetState or other actions to react to sider
state changes. Toggle the sider to see the state update above.
```
The Sider theme takes antd Layout design tokens. Here lightTriggerBg, lightTriggerColor and triggerHeight style the collapse trigger, and the Menu theme styles the selected item.
```yaml
- id: token_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: token_sider
type: Sider
properties:
width: 220
collapsible: true
initialCollapsed: false
theme:
lightTriggerBg: "#f9f0ff"
lightTriggerColor: "#722ed1"
triggerHeight: 40
blocks:
- id: token_menu
type: Menu
properties:
mode: inline
theme:
itemSelectedBg: "#f9f0ff"
itemSelectedColor: "#722ed1"
links:
- id: token_nav_explore
type: MenuLink
properties:
title: Explore
icon: Compass
- id: token_nav_favorites
type: MenuLink
properties:
title: Favorites
icon: heart
- id: token_nav_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: token_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: token_content_text
type: Paragraph
properties:
content: The Sider theme takes antd Layout design tokens. Here lightTriggerBg,
lightTriggerColor and triggerHeight style the collapse trigger,
and the Menu theme styles the selected item.
```
The Sider has a single CSS key called "element" which targets the entire sider container. Use it with Tailwind classes for gradients, borders, shadows, and other visual effects.
A shadow-lg class on the element CSS key gives the sider an elevated appearance that visually separates it from the main content area.
```yaml
- id: css_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: css_sider
type: Sider
properties:
theme: light
width: 220
collapsible: false
initialCollapsed: false
class:
.element: bg-gradient-to-b from-primary/10 to-bg-container border-r border-border
blocks:
- id: css_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: css_nav_workspace
type: MenuLink
properties:
title: Workspace
icon: grid
- id: css_nav_members
type: MenuLink
properties:
title: Members
icon: users
- id: css_nav_billing
type: MenuLink
properties:
title: Billing
icon: CreditCard
- id: css_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: css_content_text
type: Paragraph
properties:
content: The Sider has a single CSS key called "element" which targets the
entire sider container. Use it with Tailwind classes for
gradients, borders, shadows, and other visual effects.
- id: css_shadow_layout
type: Layout
style:
minHeight: 300px
blocks:
- id: css_shadow_sider
type: Sider
properties:
theme: light
width: 200
collapsible: false
initialCollapsed: false
class:
.element: shadow-lg bg-bg-container
blocks:
- id: css_shadow_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: css_sh_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: css_sh_analytics
type: MenuLink
properties:
title: Analytics
icon: ChartLine
- id: css_shadow_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: css_shadow_content_text
type: Paragraph
properties:
content: A shadow-lg class on the element CSS key gives the sider an elevated
appearance that visually separates it from the main content area.
```
Admin
Dashboard
```yaml
- id: admin_layout
type: Layout
style:
minHeight: 400px
blocks:
- id: admin_sider
type: Sider
properties:
theme: dark
width: 240
collapsible: true
initialCollapsed: false
events:
onClose:
- id: admin_on_close
type: SetState
params:
adminSiderOpen: false
onOpen:
- id: admin_on_open
type: SetState
params:
adminSiderOpen: true
blocks:
- id: admin_logo_box
type: Box
style:
padding: 16px
textAlign: center
blocks:
- id: admin_logo_title
type: Title
class: text-white
properties:
content: Admin
level: 4
- id: admin_menu
type: Menu
properties:
mode: inline
theme: dark
links:
- id: admin_nav_dashboard
type: MenuLink
properties:
title: Dashboard
icon: Gauge
- id: admin_nav_users
type: MenuGroup
properties:
title: User Management
icon: users
links:
- id: admin_nav_all_users
type: MenuLink
properties:
title: All Users
- id: admin_nav_roles
type: MenuLink
properties:
title: Roles
- id: admin_nav_content
type: MenuGroup
properties:
title: Content
icon: document
links:
- id: admin_nav_pages
type: MenuLink
properties:
title: Pages
- id: admin_nav_media
type: MenuLink
properties:
title: Media
- id: admin_nav_settings
type: MenuLink
properties:
title: Settings
icon: settings
- id: admin_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-layout)
blocks:
- id: admin_header_row
type: Box
layout:
gap: 16
justify: space-between
align: center
blocks:
- id: admin_page_title
type: Title
layout:
flex: 0 0 auto
properties:
content: Dashboard
level: 3
- id: admin_header_actions
type: Box
layout:
flex: 0 0 auto
gap: 8
blocks:
- id: admin_notif_btn
type: Button
layout:
flex: 0 0 auto
properties:
icon: bell
color: default
variant: text
hideTitle: true
- id: admin_profile_btn
type: Button
layout:
flex: 0 0 auto
properties:
icon: user
color: default
variant: text
hideTitle: true
- id: admin_stats_row
type: Box
layout:
gap: 16
blocks:
- id: admin_stat_users
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: admin_stat_users_val
type: Statistic
properties:
title: Total Users
value: 2847
- id: admin_stat_revenue
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: admin_stat_revenue_val
type: Statistic
properties:
title: Revenue
value: 48200
prefix: $
- id: admin_stat_orders
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: admin_stat_orders_val
type: Statistic
properties:
title: Orders
value: 384
```
Settings
Profile Settings
Manage your personal information and preferences.
```yaml
- id: settings_layout
type: Layout
style:
minHeight: 400px
blocks:
- id: settings_sider
type: Sider
properties:
theme: light
width: 220
collapsible: false
initialCollapsed: false
style:
borderRight: "1px solid #f0f0f0"
blocks:
- id: settings_heading
type: Title
style:
padding: 16px 16px 8px
properties:
content: Settings
level: 5
- id: settings_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: settings_nav_profile
type: MenuLink
properties:
title: Profile
icon: user
- id: settings_nav_account
type: MenuLink
properties:
title: Account
icon: Shield
- id: settings_nav_notifications
type: MenuLink
properties:
title: Notifications
icon: bell
- id: settings_nav_appearance
type: MenuLink
properties:
title: Appearance
icon: PaintBucket
- id: settings_nav_integrations
type: MenuLink
properties:
title: Integrations
icon: Plug
- id: settings_content
type: Content
style:
padding: 24px
background: var(--ant-color-bg-container)
blocks:
- id: settings_content_title
type: Title
properties:
content: Profile Settings
level: 4
- id: settings_content_desc
type: Paragraph
properties:
content: Manage your personal information and preferences.
- id: settings_divider
type: Divider
- id: settings_form_name
type: TextInput
properties:
title: Display Name
placeholder: Enter your name
- id: settings_form_email
type: TextInput
properties:
title: Email Address
placeholder: you@example.com
- id: settings_form_bio
type: TextArea
properties:
title: Bio
placeholder: Tell us about yourself
- id: settings_form_save
type: Button
properties:
title: Save Changes
color: primary
variant: solid
icon: save
```
Introduction
Welcome to the documentation. This page gives an overview of the framework and how to get started building your first application.
Use the sidebar on the left to browse through different sections. On smaller screens the sidebar collapses automatically thanks to the breakpoint property set to "md".
```yaml
- id: docs_layout
type: Layout
style:
minHeight: 400px
blocks:
- id: docs_sider
type: Sider
properties:
theme: light
width: 260
collapsible: true
initialCollapsed: false
breakpoint: md
class:
.element: border-r border-border
blocks:
- id: docs_search
type: TextInput
style:
padding: 12px 16px
properties:
placeholder: Search docs...
prefixIcon: search
- id: docs_menu
type: Menu
properties:
mode: inline
theme: light
links:
- id: docs_nav_getting_started
type: MenuGroup
properties:
title: Getting Started
links:
- id: docs_nav_intro
type: MenuLink
properties:
title: Introduction
- id: docs_nav_install
type: MenuLink
properties:
title: Installation
- id: docs_nav_quickstart
type: MenuLink
properties:
title: Quick Start
- id: docs_nav_guides
type: MenuGroup
properties:
title: Guides
links:
- id: docs_nav_blocks
type: MenuLink
properties:
title: Blocks
- id: docs_nav_operators
type: MenuLink
properties:
title: Operators
- id: docs_nav_actions
type: MenuLink
properties:
title: Actions
- id: docs_content
type: Content
style:
padding: 32px
background: var(--ant-color-bg-container)
blocks:
- id: docs_content_title
type: Title
properties:
content: Introduction
level: 3
- id: docs_content_p1
type: Paragraph
properties:
content: Welcome to the documentation. This page gives an overview of the
framework and how to get started building your first application.
- id: docs_content_p2
type: Paragraph
properties:
content: Use the sidebar on the left to browse through different sections. On
smaller screens the sidebar collapses automatically thanks to the
breakpoint property set to "md".
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `breakpoint` | string | - | Breakpoint of the responsive layout. Crossing it fires onBreakpoint. Enum: `xs`, `sm`, `md`, `lg`, `xl`, `xxl`, `xxxl`. |
| `collapsedWidth` | integer | - | Width of the collapsed sidebar, by setting to 0 a special trigger will appear |
| `collapsible` | boolean | `false` | Show a trigger at the bottom of the sider that collapses and expands it. |
| `initialCollapsed` | boolean | `true` | Set the initial collapsed state |
| `reverseArrow` | boolean | `false` | Direction of arrow, for a sider that expands from the right |
| `width` | string \| number | - | width of the sidebar |
| `theme` | string \| object | - | The Sider color theme, light or dark, or antd Layout design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design layout tokens](https://ant.design/components/layout#design-token). |
| `theme.triggerHeight` | number | `48` | Height of the collapse trigger of a collapsible Sider. |
| `theme.triggerBg` | string | `"#002140"` | Background color of the collapse trigger of a dark Sider. |
| `theme.triggerColor` | string | `"#fff"` | Color of the collapse trigger of a dark Sider. |
| `theme.lightTriggerBg` | string | `"#ffffff"` | Background color of the collapse trigger of a light Sider. |
| `theme.lightTriggerColor` | string | `"rgba(0, 0, 0, 0.88)"` | Color of the collapse trigger of a light Sider. |
| `theme.zeroTriggerWidth` | number | `40` | Width of the trigger shown when collapsedWidth is 0. |
| `theme.zeroTriggerHeight` | number | `40` | Height of the trigger shown when collapsedWidth is 0. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onClose` | \- | Trigger actions when sider is closed. |
| `onOpen` | \- | Trigger actions when sider is opened. |
| `onBreakpoint` | `{ broken }` | Trigger actions when the screen width crosses the breakpoint. Use it with the setOpen method to collapse the sider on small screens. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Sider element. |
| `/body` | The box inside the Sider that holds its child blocks. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks in the sider panel. |
---
url: https://docs.lowdefy.com/md/container-blocks/span.md
---
# Span
Inline container for wrapping content.
A Span with no child blocks, using the content property instead.
```yaml
- id: span_basic
type: Span
blocks:
- id: span_basic_text
type: Html
properties:
html: This is text inside a Span block using the content area.
- id: span_basic_empty
type: Span
properties:
content: A Span with no child blocks, using the content property instead.
```
Plain text rendered via the content property.
Bold , italic , and underlined via the content property.
This content property overrides the content area below.
```yaml
- id: span_content_plain
type: Span
properties:
content: Plain text rendered via the content property.
- id: span_content_html
type: Span
properties:
content: Bold , italic , and underlined via the content property.
- id: span_content_overrides
type: Span
properties:
content: This content property overrides the content area below.
blocks:
- id: span_content_overrides_child
type: Html
properties:
html: This child block is hidden because the content property takes priority.
```
```yaml
- id: span_content_area
type: Span
blocks:
- id: span_content_area_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: info
size: 14
color: "#1677ff"
- id: span_content_area_text
type: Html
layout:
flex: 0 0 auto
properties:
html: Child blocks render inside the content area when no content property is
set.
```
Click me to show a message
Click to update state
Click to navigate
```yaml
- id: span_click_basic
type: Span
style:
.element:
color: "#1677ff"
textDecoration: underline
cursor: pointer
properties:
content: Click me to show a message
events:
onClick:
- id: span_click_basic_msg
type: DisplayMessage
params:
content: You clicked the Span!
status: success
- id: span_click_set_state
type: Span
style:
.element:
background: "#e6f4ff"
padding: 4px 12px
borderRadius: 4
color: "#1677ff"
fontWeight: bold
properties:
content: Click to update state
events:
onClick:
- id: span_click_set_state_action
type: SetState
params:
spanClicked: true
clickedAt:
_date: now
- id: span_click_link
type: Span
style:
.element:
color: "#722ed1"
textDecoration: underline
properties:
content: Click to navigate
events:
onClick:
- id: span_click_link_action
type: Link
params:
url: https://docs.lowdefy.com
newTab: true
```
Underlined span
uppercase span
monospace code style
Gradient span
```yaml
- id: span_style_underline
type: Span
layout:
flex: 0 0 auto
style:
.element:
textDecoration: underline
textDecorationColor: "#1677ff"
textUnderlineOffset: 4px
properties:
content: Underlined span
- id: span_style_uppercase
type: Span
layout:
flex: 0 0 auto
style:
.element:
textTransform: uppercase
letterSpacing: 2
fontSize: 12
fontWeight: bold
color: "#8c8c8c"
properties:
content: uppercase span
- id: span_style_mono
type: Span
layout:
flex: 0 0 auto
style:
.element:
fontFamily: monospace
background: "#f5f5f5"
padding: 2px 6px
borderRadius: 4
fontSize: 13
color: "#cf1322"
properties:
content: monospace code style
- id: span_style_gradient
type: Span
layout:
flex: 0 0 auto
style:
.element:
background: linear-gradient(90deg,
color: "#ffffff"
padding: 4px 12px
borderRadius: 6
fontWeight: bold
properties:
content: Gradient span
```
Bold blue text via Tailwind
Pill badge
Hover for effect
Ring outline
```yaml
- id: span_tw_bold_blue
type: Span
layout:
flex: 0 0 auto
class:
element: font-bold text-blue-600
properties:
content: Bold blue text via Tailwind
- id: span_tw_bg_pill
type: Span
layout:
flex: 0 0 auto
class:
element: bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium
properties:
content: Pill badge
- id: span_tw_hover
type: Span
layout:
flex: 0 0 auto
class:
element: text-gray-600 hover:text-blue-600 hover:underline transition-colors
duration-200 cursor-pointer
properties:
content: Hover for effect
- id: span_tw_ring
type: Span
layout:
flex: 0 0 auto
class:
element: ring-2 ring-purple-300 bg-purple-50 text-purple-700 px-3 py-1
rounded-md text-sm
properties:
content: Ring outline
```
This paragraph has an
inline highlighted Span
mixed with regular text.
```yaml
- id: span_inline_wrapper
type: Box
blocks:
- id: span_inline_before
type: Span
layout:
flex: 0 0 auto
properties:
content: "This paragraph has an "
- id: span_inline_highlight
type: Span
layout:
flex: 0 0 auto
style:
.element:
color: "#1677ff"
fontWeight: bold
properties:
content: inline highlighted Span
- id: span_inline_after
type: Span
layout:
flex: 0 0 auto
properties:
content: " mixed with regular text."
```
Hello,
world
!
```yaml
- id: span_multi_wrapper
type: Box
blocks:
- id: span_multi_hello
type: Span
layout:
flex: 0 0 auto
style:
.element:
fontWeight: bold
properties:
content: "Hello, "
- id: span_multi_world
type: Span
layout:
flex: 0 0 auto
style:
.element:
color: "#1677ff"
properties:
content: world
- id: span_multi_excl
type: Span
layout:
flex: 0 0 auto
properties:
content: "!"
```
Status:
```yaml
- id: span_nested_outer
type: Span
style:
.element:
padding: 8px 12px
background: "#f5f5f5"
borderRadius: 6
display: inline-flex
alignItems: center
gap: 8
blocks:
- id: span_nested_label
type: Span
layout:
flex: 0 0 auto
style:
.element:
fontWeight: bold
color: "#262626"
properties:
content: "Status:"
- id: span_nested_value
type: Span
layout:
flex: 0 0 auto
style:
.element:
color: "#52c41a"
blocks:
- id: span_nested_value_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: check-circle
size: 14
color: "#52c41a"
- id: span_nested_value_text
type: Html
layout:
flex: 0 0 auto
properties:
html: Active
```
Info
Success
Error
```yaml
- id: span_tag_blue
type: Span
layout:
flex: 0 0 auto
style:
.element:
background: "#e6f4ff"
color: "#1677ff"
padding: 2px 8px
borderRadius: 4
fontSize: 12
border: 1px solid
properties:
content: Info
- id: span_tag_green
type: Span
layout:
flex: 0 0 auto
style:
.element:
background: "#f6ffed"
color: "#52c41a"
padding: 2px 8px
borderRadius: 4
fontSize: 12
border: 1px solid
properties:
content: Success
- id: span_tag_red
type: Span
layout:
flex: 0 0 auto
style:
.element:
background: "#fff2f0"
color: "#ff4d4f"
padding: 2px 8px
borderRadius: 4
fontSize: 12
border: 1px solid
properties:
content: Error
```
NEW
3
LIVE
```yaml
- id: span_badge_primary
type: Span
layout:
flex: 0 0 auto
style:
.element:
background: "#1677ff"
color: "#ffffff"
padding: 2px 10px
borderRadius: 12
fontSize: 12
fontWeight: bold
properties:
content: NEW
- id: span_badge_danger
type: Span
layout:
flex: 0 0 auto
style:
.element:
background: "#ff4d4f"
color: "#ffffff"
padding: 2px 10px
borderRadius: 12
fontSize: 12
fontWeight: bold
properties:
content: "3"
- id: span_badge_success
type: Span
layout:
flex: 0 0 auto
style:
.element:
background: "#52c41a"
color: "#ffffff"
padding: 2px 10px
borderRadius: 12
fontSize: 12
fontWeight: bold
properties:
content: LIVE
```
```yaml
- id: span_icon_smile
type: Span
style:
.element:
display: inline-flex
alignItems: center
gap: 6
blocks:
- id: span_icon_smile_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: FaceSlightlySmiling
size: 16
color: "#faad14"
- id: span_icon_smile_label
type: Html
layout:
flex: 0 0 auto
properties:
html: Happy face
- id: span_icon_check
type: Span
style:
.element:
display: inline-flex
alignItems: center
gap: 6
blocks:
- id: span_icon_check_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: check-circle
size: 16
color: "#52c41a"
- id: span_icon_check_label
type: Html
layout:
flex: 0 0 auto
properties:
html: Approved
- id: span_icon_warning
type: Span
style:
.element:
display: inline-flex
alignItems: center
gap: 6
blocks:
- id: span_icon_warning_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: warning
size: 16
color: "#ff4d4f"
- id: span_icon_warning_label
type: Html
layout:
flex: 0 0 auto
properties:
html: Warning
```
Order #10482:
Estimated delivery Mar 18, 2026
```yaml
- id: span_order_wrapper
type: Box
layout:
gap: 16
align: center
blocks:
- id: span_order_label
type: Span
layout:
flex: 0 0 auto
style:
.element:
fontWeight: bold
color: "#262626"
properties:
content: "Order #10482:"
- id: span_order_shipped
type: Span
layout:
flex: 0 0 auto
style:
.element:
display: inline-flex
alignItems: center
gap: 6
background: "#f6ffed"
color: "#52c41a"
padding: 4px 12px
borderRadius: 12
fontSize: 13
fontWeight: 500
border: 1px solid
blocks:
- id: span_order_shipped_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: check-circle
size: 14
color: "#52c41a"
- id: span_order_shipped_text
type: Html
layout:
flex: 0 0 auto
properties:
html: Shipped
- id: span_order_date
type: Span
layout:
flex: 0 0 auto
style:
.element:
color: "#8c8c8c"
fontSize: 13
properties:
content: Estimated delivery Mar 18, 2026
```
Home
/
Products
/
Widget Pro X
```yaml
- id: span_breadcrumb_wrapper
type: Box
layout:
gap: 8
align: center
blocks:
- id: span_breadcrumb_home
type: Span
layout:
flex: 0 0 auto
style:
.element:
color: "#1677ff"
cursor: pointer
properties:
content: Home
events:
onClick:
- id: span_breadcrumb_home_click
type: Link
params:
url: /
- id: span_breadcrumb_sep1
type: Span
layout:
flex: 0 0 auto
style:
.element:
color: "#d9d9d9"
properties:
content: /
- id: span_breadcrumb_products
type: Span
layout:
flex: 0 0 auto
style:
.element:
color: "#1677ff"
cursor: pointer
properties:
content: Products
events:
onClick:
- id: span_breadcrumb_products_click
type: Link
params:
url: /products
- id: span_breadcrumb_sep2
type: Span
layout:
flex: 0 0 auto
style:
.element:
color: "#d9d9d9"
properties:
content: /
- id: span_breadcrumb_current
type: Span
layout:
flex: 0 0 auto
style:
.element:
color: "#595959"
fontWeight: 500
properties:
content: Widget Pro X
```
Sarah Mitchell
Admin
```yaml
- id: span_profile_wrapper
type: Box
layout:
gap: 12
align: center
blocks:
- id: span_profile_avatar
type: Icon
layout:
flex: 0 0 auto
properties:
name: user
size: 20
color: "#1677ff"
- id: span_profile_name
type: Span
layout:
flex: 0 0 auto
style:
.element:
fontWeight: bold
fontSize: 14
color: "#262626"
properties:
content: Sarah Mitchell
- id: span_profile_role
type: Span
layout:
flex: 0 0 auto
class:
element: bg-purple-100 text-purple-700 px-2 py-0.5 rounded-full text-xs
font-medium
properties:
content: Admin
- id: span_profile_status
type: Span
layout:
flex: 0 0 auto
style:
.element:
display: inline-flex
alignItems: center
gap: 4
fontSize: 12
color: "#52c41a"
blocks:
- id: span_profile_status_dot
type: Html
layout:
flex: 0 0 auto
properties:
html:
- id: span_profile_status_text
type: Html
layout:
flex: 0 0 auto
properties:
html: Online
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `content` | string | - | Span content string. Overrides the "content" content area. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onClick` | \- | Trigger actions when the Span is clicked. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Span element. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks in the Span. |
---
url: https://docs.lowdefy.com/md/container-blocks/splitter.md
---
# Splitter
Resizable split panels with configurable sizes and collapsible.
Left Panel
Right Panel
```yaml
- id: basic_h
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: left
defaultSize: 50
- key: right
defaultSize: 50
slots:
left:
blocks:
- id: basic_h_left
type: Box
class: bg-bg-layout h-full flex items-center justify-center
blocks:
- id: basic_h_left_text
type: Paragraph
properties:
content: Left Panel
right:
blocks:
- id: basic_h_right
type: Box
class: bg-bg-layout h-full flex items-center justify-center
blocks:
- id: basic_h_right_text
type: Paragraph
properties:
content: Right Panel
```
Top Panel
Bottom Panel
```yaml
- id: basic_v
type: Splitter
style:
height: 300px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: vertical
panels:
- key: top
defaultSize: 50
- key: bottom
defaultSize: 50
slots:
top:
blocks:
- id: basic_v_top
type: Box
class: bg-bg-layout h-full flex items-center justify-center
blocks:
- id: basic_v_top_text
type: Paragraph
properties:
content: Top Panel
bottom:
blocks:
- id: basic_v_bottom
type: Box
class: bg-bg-layout h-full flex items-center justify-center
blocks:
- id: basic_v_bottom_text
type: Paragraph
properties:
content: Bottom Panel
```
25%
50%
25%
Fixed 200px
Flexible remainder
```yaml
- id: three_h
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: first
defaultSize: 25
- key: second
defaultSize: 50
- key: third
defaultSize: 25
slots:
first:
blocks:
- id: three_h_first
type: Box
class: bg-bg-layout h-full flex items-center justify-center
blocks:
- id: three_h_first_text
type: Paragraph
properties:
content: 25%
second:
blocks:
- id: three_h_second
type: Box
class: bg-bg-layout h-full flex items-center justify-center
blocks:
- id: three_h_second_text
type: Paragraph
properties:
content: 50%
third:
blocks:
- id: three_h_third
type: Box
class: bg-bg-layout h-full flex items-center justify-center
blocks:
- id: three_h_third_text
type: Paragraph
properties:
content: 25%
- id: pixel_sizes
type: Splitter
style:
height: 180px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: px_fixed
defaultSize: 200px
- key: px_flex
slots:
px_fixed:
blocks:
- id: pixel_sizes_fixed
type: Box
class: bg-bg-layout h-full flex items-center justify-center
blocks:
- id: pixel_sizes_fixed_text
type: Paragraph
properties:
content: Fixed 200px
px_flex:
blocks:
- id: pixel_sizes_flex
type: Box
class: bg-bg-layout h-full flex items-center justify-center
blocks:
- id: pixel_sizes_flex_text
type: Paragraph
properties:
content: Flexible remainder
```
Navigation
Min: 20% / Max: 40%
Main Content
The left panel cannot be resized smaller than 20% or larger than 40%.
Min: 100px / Max: 400px
Flexible Center
Min: 100px / Max: 300px
```yaml
- id: constrained
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: nav
defaultSize: 30
min: 20
max: 40
- key: main
defaultSize: 70
slots:
nav:
blocks:
- id: constrained_nav
type: Box
class: bg-bg-layout h-full p-4
blocks:
- id: constrained_nav_title
type: Paragraph
properties:
content: Navigation
- id: constrained_nav_desc
type: Paragraph
properties:
content: "Min: 20% / Max: 40%"
main:
blocks:
- id: constrained_main
type: Box
class: bg-bg-layout h-full p-4
blocks:
- id: constrained_main_title
type: Paragraph
properties:
content: Main Content
- id: constrained_main_desc
type: Paragraph
properties:
content: The left panel cannot be resized smaller than 20% or larger than 40%.
- id: constrained_px
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: cpx_left
defaultSize: 30
min: 100px
max: 400px
- key: cpx_center
defaultSize: 40
- key: cpx_right
defaultSize: 30
min: 100px
max: 300px
slots:
cpx_left:
blocks:
- id: constrained_px_left
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: constrained_px_left_text
type: Paragraph
properties:
content: "Min: 100px / Max: 400px"
cpx_center:
blocks:
- id: constrained_px_center
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: constrained_px_center_text
type: Paragraph
properties:
content: Flexible Center
cpx_right:
blocks:
- id: constrained_px_right
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: constrained_px_right_text
type: Paragraph
properties:
content: "Min: 100px / Max: 300px"
```
Collapsible Sidebar
Click the arrow on the divider to collapse this panel.
Main body content remains visible when the sidebar is collapsed.
Left (collapsible)
Center (fixed)
Right (collapsible)
```yaml
- id: collapsible_simple
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: col_sidebar
defaultSize: 30
collapsible: true
- key: col_body
defaultSize: 70
slots:
col_sidebar:
blocks:
- id: collapsible_simple_sidebar
type: Box
class: bg-bg-layout h-full p-4
blocks:
- id: collapsible_simple_sidebar_text
type: Paragraph
properties:
content: Collapsible Sidebar
- id: collapsible_simple_sidebar_desc
type: Paragraph
properties:
content: Click the arrow on the divider to collapse this panel.
col_body:
blocks:
- id: collapsible_simple_body
type: Box
class: bg-bg-container h-full p-4
blocks:
- id: collapsible_simple_body_text
type: Paragraph
properties:
content: Main body content remains visible when the sidebar is collapsed.
- id: collapsible_both
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: cb_left
defaultSize: 25
collapsible: true
- key: cb_center
defaultSize: 50
- key: cb_right
defaultSize: 25
collapsible: true
slots:
cb_left:
blocks:
- id: collapsible_both_left
type: Box
class: bg-bg-layout h-full p-3 flex items-center justify-center
blocks:
- id: collapsible_both_left_text
type: Paragraph
properties:
content: Left (collapsible)
cb_center:
blocks:
- id: collapsible_both_center
type: Box
class: bg-bg-layout h-full p-3 flex items-center justify-center
blocks:
- id: collapsible_both_center_text
type: Paragraph
properties:
content: Center (fixed)
cb_right:
blocks:
- id: collapsible_both_right
type: Box
class: bg-bg-layout h-full p-3 flex items-center justify-center
blocks:
- id: collapsible_both_right_text
type: Paragraph
properties:
content: Right (collapsible)
```
Collapse left only
Collapse both directions
Collapse right only
```yaml
- id: col_start_end
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: cse_left
defaultSize: 30
collapsible:
end: true
- key: cse_center
defaultSize: 40
collapsible:
start: true
end: true
- key: cse_right
defaultSize: 30
collapsible:
start: true
slots:
cse_left:
blocks:
- id: col_se_left
type: Box
class: bg-bg-layout h-full p-3 flex items-center justify-center
blocks:
- id: col_se_left_text
type: Paragraph
properties:
content: Collapse left only
cse_center:
blocks:
- id: col_se_center
type: Box
class: bg-bg-layout h-full p-3 flex items-center justify-center
blocks:
- id: col_se_center_text
type: Paragraph
properties:
content: Collapse both directions
cse_right:
blocks:
- id: col_se_right
type: Box
class: bg-bg-layout h-full p-3 flex items-center justify-center
blocks:
- id: col_se_right_text
type: Paragraph
properties:
content: Collapse right only
```
The panel animates as it collapses, and its blocks unmount while it is collapsed.
Double-click the drag handle to trigger onDraggerDoubleClick.
```yaml
- id: col_motion
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
destroyOnHidden: true
draggerIcon: GripVertical
collapsible:
motion: true
icon:
start: ChevronsLeft
end: ChevronsRight
panels:
- key: col_motion_nav
defaultSize: 30
collapsible:
end: true
showCollapsibleIcon: true
- key: col_motion_main
slots:
col_motion_nav:
blocks:
- id: col_motion_nav_text
type: Paragraph
properties:
content: The panel animates as it collapses, and its blocks unmount while it is
collapsed.
col_motion_main:
blocks:
- id: col_motion_main_text
type: Paragraph
properties:
content: Double-click the drag handle to trigger onDraggerDoubleClick.
```
Fixed (resizable: false)
Resizable
Resizable
```yaml
- id: nonresizable
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: nr_fixed
defaultSize: 30
resizable: false
- key: nr_flex_a
defaultSize: 40
- key: nr_flex_b
defaultSize: 30
slots:
nr_fixed:
blocks:
- id: nonresizable_fixed
type: Box
class: bg-bg-layout h-full p-3 flex items-center justify-center
blocks:
- id: nonresizable_fixed_text
type: Paragraph
properties:
content: "Fixed (resizable: false)"
nr_flex_a:
blocks:
- id: nonresizable_flex_a
type: Box
class: bg-bg-layout h-full p-3 flex items-center justify-center
blocks:
- id: nonresizable_flex_a_text
type: Paragraph
properties:
content: Resizable
nr_flex_b:
blocks:
- id: nonresizable_flex_b
type: Box
class: bg-bg-layout h-full p-3 flex items-center justify-center
blocks:
- id: nonresizable_flex_b_text
type: Paragraph
properties:
content: Resizable
```
Lazy rendering defers content until the panel is visible. Collapse and expand to see the effect.
This panel content is also lazily rendered.
```yaml
- id: lazy_splitter
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
lazy: true
panels:
- key: lazy_left
defaultSize: 50
collapsible: true
- key: lazy_right
defaultSize: 50
slots:
lazy_left:
blocks:
- id: lazy_left_box
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: lazy_left_text
type: Paragraph
properties:
content: Lazy rendering defers content until the panel is visible. Collapse and
expand to see the effect.
lazy_right:
blocks:
- id: lazy_right_box
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: lazy_right_text
type: Paragraph
properties:
content: This panel content is also lazily rendered.
```
Collapsible Panel
Collapse this panel or resize the divider to see event messages.
The onResizeEnd and onCollapse events fire DisplayMessage actions to show the current panel state.
State Tracking
Resize the panels. The onResizeStart fires a message and onResizeEnd saves panel sizes to state.
Current sizes:
```yaml
- id: event_splitter
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: evt_left
defaultSize: 50
collapsible: true
- key: evt_right
defaultSize: 50
events:
onResizeEnd:
- id: event_resize_msg
type: DisplayMessage
params:
content:
_string.concat:
- "Resize complete. Panel sizes: "
- _json.stringify:
on:
_event: sizes
duration: 2
onCollapse:
- id: event_collapse_msg
type: DisplayMessage
params:
content:
_if:
test:
_event: collapsed
then: Panel collapsed.
else: Panel expanded.
duration: 2
slots:
evt_left:
blocks:
- id: event_left_box
type: Box
class: bg-bg-layout h-full p-4
blocks:
- id: event_left_title
type: Paragraph
properties:
content: Collapsible Panel
- id: event_left_desc
type: Paragraph
properties:
content: Collapse this panel or resize the divider to see event messages.
evt_right:
blocks:
- id: event_right_box
type: Box
class: bg-bg-container h-full p-4
blocks:
- id: event_right_desc
type: Paragraph
properties:
content: The onResizeEnd and onCollapse events fire DisplayMessage actions to
show the current panel state.
- id: event_state_splitter
type: Splitter
style:
height: 220px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: es_left
defaultSize: 40
- key: es_right
defaultSize: 60
events:
onResizeEnd:
- id: event_set_state
type: SetState
params:
splitter_sizes:
_event: sizes
onResizeStart:
- id: event_resize_start_msg
type: DisplayMessage
params:
content: Resizing started...
duration: 1
slots:
es_left:
blocks:
- id: es_left_box
type: Box
class: bg-bg-layout h-full p-4
blocks:
- id: es_left_title
type: Paragraph
properties:
content: State Tracking
- id: es_left_desc
type: Paragraph
properties:
content: Resize the panels. The onResizeStart fires a message and onResizeEnd
saves panel sizes to state.
es_right:
blocks:
- id: es_right_box
type: Box
class: bg-bg-container h-full p-4
blocks:
- id: es_right_title
type: Paragraph
properties:
content: Current sizes:
- id: es_right_sizes
type: Paragraph
properties:
content:
_if:
test:
_not:
_not:
_state: splitter_sizes
then:
_json.stringify:
on:
_state: splitter_sizes
else: Resize panels to see sizes here.
```
Sidebar
Dashboard
Analytics
Settings
Main Content Area
A horizontal splitter with a nested vertical splitter. The sidebar splits horizontally, while the main area is split vertically into content and a bottom panel.
Bottom Panel
Collapsible bottom panel inside the nested vertical splitter.
```yaml
- id: nested_outer
type: Splitter
style:
height: 350px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: n_sidebar
defaultSize: 25
min: 15
collapsible: true
- key: n_main
defaultSize: 75
slots:
n_sidebar:
blocks:
- id: nested_sidebar
type: Box
class: bg-bg-layout h-full p-4
blocks:
- id: nested_sidebar_title
type: Paragraph
properties:
content: Sidebar
- id: nested_sidebar_item_1
type: Paragraph
properties:
content: Dashboard
- id: nested_sidebar_item_2
type: Paragraph
properties:
content: Analytics
- id: nested_sidebar_item_3
type: Paragraph
properties:
content: Settings
n_main:
blocks:
- id: nested_inner
type: Splitter
style:
height: 100%
properties:
orientation: vertical
panels:
- key: n_content
defaultSize: 70
- key: n_footer
defaultSize: 30
min: 15
collapsible: true
slots:
n_content:
blocks:
- id: nested_content
type: Box
class: bg-bg-container h-full p-4
blocks:
- id: nested_content_title
type: Paragraph
properties:
content: Main Content Area
- id: nested_content_desc
type: Paragraph
properties:
content: A horizontal splitter with a nested vertical splitter. The sidebar
splits horizontally, while the main area is split
vertically into content and a bottom panel.
n_footer:
blocks:
- id: nested_footer
type: Box
class: bg-bg-layout h-full p-4
blocks:
- id: nested_footer_title
type: Paragraph
properties:
content: Bottom Panel
- id: nested_footer_desc
type: Paragraph
properties:
content: Collapsible bottom panel inside the nested vertical splitter.
```
splitBarSize: 4, splitTriggerSize: 24
Thicker blue splitter bar with larger trigger area
Green themed divider, arrows, and resize dots
colorFill, colorPrimary, colorText overridden
Minimal divider with no visible trigger handle
resizeSpinnerSize: 0, splitTriggerSize: 0
Custom drag handle with blue tones
splitBarDraggableSize: 40, borderRadius: 12
```yaml
- id: theme_thick_bar
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: ttb_left
defaultSize: 50
- key: ttb_right
defaultSize: 50
theme:
splitBarSize: 4
splitTriggerSize: 24
colorFill: "#1677ff"
slots:
ttb_left:
blocks:
- id: theme_thick_left
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: theme_thick_left_text
type: Paragraph
properties:
content: "splitBarSize: 4, splitTriggerSize: 24"
ttb_right:
blocks:
- id: theme_thick_right
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: theme_thick_right_text
type: Paragraph
properties:
content: Thicker blue splitter bar with larger trigger area
- id: theme_green
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: tg_left
defaultSize: 50
collapsible: true
- key: tg_right
defaultSize: 50
theme:
splitBarSize: 3
colorFill: "#52c41a"
colorPrimary: "#52c41a"
colorText: "#52c41a"
splitTriggerSize: 20
slots:
tg_left:
blocks:
- id: theme_green_left
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: theme_green_left_text
type: Paragraph
properties:
content: Green themed divider, arrows, and resize dots
tg_right:
blocks:
- id: theme_green_right
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: theme_green_right_text
type: Paragraph
properties:
content: colorFill, colorPrimary, colorText overridden
- id: theme_minimal
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: tm_left
defaultSize: 50
- key: tm_right
defaultSize: 50
theme:
splitBarSize: 1
splitTriggerSize: 0
resizeSpinnerSize: 0
slots:
tm_left:
blocks:
- id: theme_minimal_left
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: theme_minimal_left_text
type: Paragraph
properties:
content: Minimal divider with no visible trigger handle
tm_right:
blocks:
- id: theme_minimal_right
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: theme_minimal_right_text
type: Paragraph
properties:
content: "resizeSpinnerSize: 0, splitTriggerSize: 0"
- id: theme_custom_handle
type: Splitter
style:
height: 200px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: tch_left
defaultSize: 50
- key: tch_right
defaultSize: 50
theme:
splitBarDraggableSize: 40
colorFillTertiary: "#e6f4ff"
colorFillSecondary: "#91caff"
borderRadius: 12
slots:
tch_left:
blocks:
- id: theme_handle_left
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: theme_handle_left_text
type: Paragraph
properties:
content: Custom drag handle with blue tones
tch_right:
blocks:
- id: theme_handle_right
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: theme_handle_right_text
type: Paragraph
properties:
content: "splitBarDraggableSize: 40, borderRadius: 12"
```
The element CSS key applies Tailwind classes to the outer Splitter wrapper.
class.element: rounded-2xl shadow-lg overflow-hidden
Dashed blue border via Tailwind
class.element: border-2 border-dashed border-blue-300 rounded-xl
```yaml
- id: css_rounded
type: Splitter
class:
.element: rounded-2xl shadow-lg overflow-hidden
style:
height: 200px
properties:
orientation: horizontal
panels:
- key: css_r_left
defaultSize: 50
- key: css_r_right
defaultSize: 50
slots:
css_r_left:
blocks:
- id: css_rounded_left
type: Box
class: bg-gradient-to-br from-primary/10 to-primary/10 h-full p-4 flex
items-center justify-center
blocks:
- id: css_rounded_left_text
type: Paragraph
properties:
content: The element CSS key applies Tailwind classes to the outer Splitter
wrapper.
css_r_right:
blocks:
- id: css_rounded_right
type: Box
class: bg-gradient-to-br from-primary/15 to-primary/10 h-full p-4 flex
items-center justify-center
blocks:
- id: css_rounded_right_text
type: Paragraph
properties:
content: "class.element: rounded-2xl shadow-lg overflow-hidden"
- id: css_border
type: Splitter
class:
.element: border-2 border-dashed border-blue-300 rounded-xl
style:
height: 180px
properties:
orientation: horizontal
panels:
- key: css_b_left
defaultSize: 40
- key: css_b_right
defaultSize: 60
slots:
css_b_left:
blocks:
- id: css_border_left
type: Box
class: bg-bg-layout h-full p-4 flex items-center justify-center
blocks:
- id: css_border_left_text
type: Paragraph
properties:
content: Dashed blue border via Tailwind
css_b_right:
blocks:
- id: css_border_right
type: Box
class: bg-bg-container h-full p-4 flex items-center justify-center
blocks:
- id: css_border_right_text
type: Paragraph
properties:
content: "class.element: border-2 border-dashed border-blue-300 rounded-xl"
```
Explorer
src/
index.js
App.js
styles.css
package.json
App.js
import React from "react" ;function App () { return ( <div className ="app" > <h1 >Hello World</h1 > </div > ); }
Terminal
$ npm start
Compiled successfully!
```yaml
- id: editor_outer
type: Splitter
style:
height: 420px
border: "1px solid #d9d9d9"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: editor_files
defaultSize: 18
min: 12
collapsible: true
- key: editor_main
defaultSize: 82
events:
onCollapse:
- id: editor_collapse_msg
type: DisplayMessage
params:
content:
_if:
test:
_event: collapsed
then: File explorer collapsed.
else: File explorer expanded.
duration: 2
slots:
editor_files:
blocks:
- id: editor_files_box
type: Box
class: bg-bg-layout h-full p-3
blocks:
- id: editor_files_title
type: Paragraph
style:
color: "#9ca3af"
fontSize: 11px
textTransform: uppercase
letterSpacing: 1px
properties:
content: Explorer
- id: editor_files_f1
type: Paragraph
style:
color: "#e2e8f0"
fontSize: 13px
properties:
content: src/
- id: editor_files_f2
type: Paragraph
style:
color: "#94a3b8"
fontSize: 13px
paddingLeft: 12px
properties:
content: index.js
- id: editor_files_f3
type: Paragraph
style:
color: "#94a3b8"
fontSize: 13px
paddingLeft: 12px
properties:
content: App.js
- id: editor_files_f4
type: Paragraph
style:
color: "#94a3b8"
fontSize: 13px
paddingLeft: 12px
properties:
content: styles.css
- id: editor_files_f5
type: Paragraph
style:
color: "#e2e8f0"
fontSize: 13px
properties:
content: package.json
editor_main:
blocks:
- id: editor_inner
type: Splitter
style:
height: 100%
properties:
orientation: vertical
panels:
- key: editor_code
defaultSize: 65
- key: editor_terminal
defaultSize: 35
min: 15
collapsible: true
slots:
editor_code:
blocks:
- id: editor_code_box
type: Box
class: bg-bg-layout h-full p-4
blocks:
- id: editor_code_tab
type: Paragraph
style:
color: "#64748b"
fontSize: 12px
borderBottom: "1px solid #334155"
paddingBottom: 8px
properties:
content: App.js
- id: editor_code_content
type: Paragraph
style:
color: "#e2e8f0"
fontFamily: monospace
fontSize: 13px
lineHeight: 1.6
properties:
content: import React from "react" ;function App ()
{ return
( <div className ="app" > <h1 >Hello
World</h1 > </div > ); }
editor_terminal:
blocks:
- id: editor_terminal_box
type: Box
class: bg-bg-layout h-full p-3
blocks:
- id: editor_terminal_title
type: Paragraph
style:
color: "#64748b"
fontSize: 11px
textTransform: uppercase
letterSpacing: 1px
borderBottom: "1px solid #1e293b"
paddingBottom: 6px
properties:
content: Terminal
- id: editor_terminal_line
type: Paragraph
style:
color: "#22c55e"
fontFamily: monospace
fontSize: 13px
properties:
content: $ npm start
- id: editor_terminal_output
type: Paragraph
style:
color: "#94a3b8"
fontFamily: monospace
fontSize: 13px
properties:
content: Compiled successfully!
```
Overview
Sarah updated the project plan 2 min ago
James added 3 team members 15 min ago
System completed deployment 1 hour ago
Alex resolved 5 support tickets 3 hours ago
```yaml
- id: dashboard_outer
type: Splitter
style:
height: 400px
border: "1px solid #e8e8e8"
borderRadius: 8px
properties:
orientation: horizontal
panels:
- key: dash_nav
defaultSize: 22
min: 15
max: 35
collapsible: true
- key: dash_content
defaultSize: 50
- key: dash_detail
defaultSize: 28
min: 20
collapsible: true
events:
onResizeEnd:
- id: dash_resize_state
type: SetState
params:
dashboard_layout:
_event: sizes
slots:
dash_nav:
blocks:
- id: dash_nav_box
type: Box
class: bg-bg-layout h-full p-0
blocks:
- id: dash_nav_card
type: Card
properties:
title: Navigation
size: small
bordered: false
blocks:
- id: dash_nav_item1
type: Button
properties:
title: Overview
icon: Gauge
variant: text
block: true
- id: dash_nav_item2
type: Button
properties:
title: Analytics
icon: chart
variant: text
block: true
- id: dash_nav_item3
type: Button
properties:
title: Users
icon: users
variant: text
block: true
- id: dash_nav_item4
type: Button
properties:
title: Settings
icon: settings
variant: text
block: true
dash_content:
blocks:
- id: dash_content_box
type: Box
class: h-full p-4
blocks:
- id: dash_content_title
type: Title
properties:
content: Overview
level: 4
- id: dash_stats_row
type: Box
layout:
gap: 16
blocks:
- id: dash_stat_users
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: dash_stat_users_val
type: Statistic
properties:
title: Total Users
value: 2846
- id: dash_stat_revenue
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: dash_stat_revenue_val
type: Statistic
properties:
title: Revenue
value: 48200
prefix: $
- id: dash_progress_card
type: Card
properties:
title: Monthly Target
size: small
blocks:
- id: dash_progress_bar
type: Progress
properties:
percent: 72
dash_detail:
blocks:
- id: dash_detail_box
type: Box
class: bg-bg-layout h-full p-0
blocks:
- id: dash_detail_card
type: Card
properties:
title: Recent Activity
size: small
bordered: false
blocks:
- id: dash_detail_item1
type: Paragraph
properties:
content: Sarah updated the project plan 2 min ago
- id: dash_detail_divider1
type: Divider
- id: dash_detail_item2
type: Paragraph
properties:
content: James added 3 team members 15 min ago
- id: dash_detail_divider2
type: Divider
- id: dash_detail_item3
type: Paragraph
properties:
content: System completed deployment 1 hour ago
- id: dash_detail_divider3
type: Divider
- id: dash_detail_item4
type: Paragraph
properties:
content: Alex resolved 5 support tickets 3 hours ago
```
Folders
Inbox - 12 messages
Alice Johnson
Q4 Planning Meeting Notes
10:30 AM
Bob Williams
Design review feedback
9:15 AM
Carol Davis
Updated project timeline
Yesterday
Q4 Planning Meeting Notes
Alice Johnson
March 13, 2026 at 10:30 AM
Hi team, here are the key takeaways from our Q4 planning meeting yesterday. We agreed on the following priorities: launching the new dashboard feature, improving API performance by 30%, and completing the migration to the new design system.
Please review the attached document and share any feedback by end of week. Our next sync is scheduled for Monday at 2 PM.
```yaml
- id: email_outer
type: Splitter
class:
.element: rounded-lg shadow-md overflow-hidden
style:
height: 420px
properties:
orientation: horizontal
panels:
- key: email_folders
defaultSize: 20
min: 15
collapsible: true
- key: email_list
defaultSize: 35
min: 25
- key: email_preview
defaultSize: 45
events:
onCollapse:
- id: email_collapse_action
type: DisplayMessage
params:
content:
_if:
test:
_event: collapsed
then: Folder panel collapsed. Click the arrow to expand.
else: Folder panel expanded.
duration: 2
slots:
email_folders:
blocks:
- id: email_folders_box
type: Box
class: bg-bg-layout h-full p-3
blocks:
- id: email_folders_title
type: Paragraph
style:
fontWeight: 600
fontSize: 13px
color: "#64748b"
textTransform: uppercase
letterSpacing: 0.5px
properties:
content: Folders
- id: email_folder_inbox
type: Button
properties:
title: Inbox (12)
icon: Inbox
variant: text
block: true
size: small
- id: email_folder_sent
type: Button
properties:
title: Sent
icon: send
variant: text
block: true
size: small
- id: email_folder_drafts
type: Button
properties:
title: Drafts (3)
icon: edit
variant: text
block: true
size: small
- id: email_folder_trash
type: Button
properties:
title: Trash
icon: delete
variant: text
block: true
size: small
email_list:
blocks:
- id: email_list_box
type: Box
class: h-full p-0
blocks:
- id: email_list_header
type: Box
class: px-3 py-2 border-b border-border
blocks:
- id: email_list_search
type: Paragraph
style:
color: "#94a3b8"
fontSize: 13px
properties:
content: Inbox - 12 messages
- id: email_msg1
type: Box
class: px-3 py-2 border-b border-border bg-bg-layout
blocks:
- id: email_msg1_from
type: Paragraph
style:
fontWeight: 600
fontSize: 13px
properties:
content: Alice Johnson
- id: email_msg1_subject
type: Paragraph
style:
fontSize: 13px
properties:
content: Q4 Planning Meeting Notes
- id: email_msg1_time
type: Paragraph
style:
fontSize: 11px
color: "#94a3b8"
properties:
content: 10:30 AM
- id: email_msg2
type: Box
class: px-3 py-2 border-b border-border
blocks:
- id: email_msg2_from
type: Paragraph
style:
fontWeight: 600
fontSize: 13px
properties:
content: Bob Williams
- id: email_msg2_subject
type: Paragraph
style:
fontSize: 13px
properties:
content: Design review feedback
- id: email_msg2_time
type: Paragraph
style:
fontSize: 11px
color: "#94a3b8"
properties:
content: 9:15 AM
- id: email_msg3
type: Box
class: px-3 py-2 border-b border-border
blocks:
- id: email_msg3_from
type: Paragraph
style:
fontSize: 13px
properties:
content: Carol Davis
- id: email_msg3_subject
type: Paragraph
style:
fontSize: 13px
properties:
content: Updated project timeline
- id: email_msg3_time
type: Paragraph
style:
fontSize: 11px
color: "#94a3b8"
properties:
content: Yesterday
email_preview:
blocks:
- id: email_preview_box
type: Box
class: h-full p-4
blocks:
- id: email_preview_subject
type: Title
properties:
content: Q4 Planning Meeting Notes
level: 4
- id: email_preview_meta
type: Box
layout:
gap: 8
align: center
blocks:
- id: email_preview_avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
icon: user
size: 32
color: "#1677ff"
- id: email_preview_sender
type: Box
layout:
flex: 1 1 0
blocks:
- id: email_preview_from
type: Paragraph
style:
fontWeight: 600
fontSize: 14px
properties:
content: Alice Johnson
- id: email_preview_date
type: Paragraph
style:
fontSize: 12px
color: "#94a3b8"
properties:
content: March 13, 2026 at 10:30 AM
- id: email_preview_divider
type: Divider
- id: email_preview_body
type: Paragraph
properties:
content: "Hi team, here are the key takeaways from our Q4 planning meeting
yesterday. We agreed on the following priorities: launching
the new dashboard feature, improving API performance by 30%,
and completing the migration to the new design system."
- id: email_preview_body2
type: Paragraph
properties:
content: Please review the attached document and share any feedback by end of
week. Our next sync is scheduled for Monday at 2 PM.
- id: email_preview_tags
type: Box
layout:
gap: 8
blocks:
- id: email_preview_tag1
type: Tag
properties:
title: Planning
color: blue
- id: email_preview_tag2
type: Tag
properties:
title: Q4
color: purple
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `collapsible` | object | - | Collapse behaviour shared by all panels. Which panels collapse is set per panel with panels[].collapsible. |
| `collapsible.motion` | boolean | `false` | Animate panels as they collapse and expand. |
| `collapsible.icon` | object | - | Custom collapse icons. By default the collapse buttons show `chevron-left` and `chevron-right` arrows, or `chevron-up` and `chevron-down` arrows on a vertical Splitter. |
| `collapsible.icon.start` | string \| object | - | Icon name or properties of an Icon block for the collapse button that moves the bar towards the start. |
| `collapsible.icon.start.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `collapsible.icon.start.color` | string | - | Icon color. |
| `collapsible.icon.start.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `collapsible.icon.start.rotate` | number | - | Number of degrees to rotate the icon. |
| `collapsible.icon.start.spin` | boolean | - | Continuously spin the icon with animation. |
| `collapsible.icon.start.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `collapsible.icon.start.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `collapsible.icon.start.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `collapsible.icon.start.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `collapsible.icon.end` | string \| object | - | Icon name or properties of an Icon block for the collapse button that moves the bar towards the end. |
| `collapsible.icon.end.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `collapsible.icon.end.color` | string | - | Icon color. |
| `collapsible.icon.end.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `collapsible.icon.end.rotate` | number | - | Number of degrees to rotate the icon. |
| `collapsible.icon.end.spin` | boolean | - | Continuously spin the icon with animation. |
| `collapsible.icon.end.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `collapsible.icon.end.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `collapsible.icon.end.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `collapsible.icon.end.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `destroyOnHidden` | boolean | `false` | Unmount the blocks in a panel while it is collapsed. Can be overridden per panel. |
| `draggerIcon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to show in the drag handle. |
| `draggerIcon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `draggerIcon.color` | string | - | Icon color. |
| `draggerIcon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `draggerIcon.rotate` | number | - | Number of degrees to rotate the icon. |
| `draggerIcon.spin` | boolean | - | Continuously spin the icon with animation. |
| `draggerIcon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `draggerIcon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `draggerIcon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `draggerIcon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `lazy` | boolean | `false` | Lazy render panel content. |
| `layout` | string | `"horizontal"` | Layout direction of the splitter. Prefer orientation. Enum: `horizontal`, `vertical`. |
| `orientation` | string | - | Layout direction of the splitter. Alias for layout, takes precedence if both are set. Enum: `horizontal`, `vertical`. |
| `panels` | array | - | Panel configuration array. Each panel has key, size, min, max, defaultSize, collapsible, resizable and destroyOnHidden. |
| `panels.$.key` | string | - | Unique panel key, used to match content slots. |
| `panels.$.size` | number \| string | - | Controlled panel size. |
| `panels.$.min` | number \| string | - | Minimum size threshold. |
| `panels.$.max` | number \| string | - | Maximum size threshold. |
| `panels.$.defaultSize` | number \| string | - | Default panel size. |
| `panels.$.collapsible` | boolean \| object | `false` | Whether the panel is collapsible. Set an object to choose the collapse directions and when the collapse buttons show. |
| `panels.$.collapsible.start` | boolean | - | Show a collapse button on the bar at the start edge of the panel. |
| `panels.$.collapsible.end` | boolean | - | Show a collapse button on the bar at the end edge of the panel. |
| `panels.$.collapsible.showCollapsibleIcon` | boolean \| string | `"auto"` | When to show the collapse buttons: always (true), never (false) or on hover (auto). Enum: `true`, `false`, `auto`. |
| `panels.$.destroyOnHidden` | boolean | - | Unmount the blocks in this panel while it is collapsed. Overrides the Splitter destroyOnHidden. |
| `panels.$.resizable` | boolean | `true` | Whether the panel is resizable. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design splitter tokens](https://ant.design/components/splitter#design-token). |
| `theme.splitBarSize` | number | `1` | Thickness of the divider bar between panels in pixels. |
| `theme.splitTriggerSize` | number | `6` | Size of the interactive trigger area for resizing in pixels. |
| `theme.splitBarDraggableSize` | number | `20` | Size of the draggable handle area in pixels. |
| `theme.resizeSpinnerSize` | number | `20` | Size of the resize indicator dots in pixels. |
| `theme.colorFill` | string | - | Color of the splitter bar. |
| `theme.colorFillTertiary` | string | - | Background color of the drag trigger area. |
| `theme.colorFillSecondary` | string | - | Background color of the drag trigger area on hover. |
| `theme.colorPrimary` | string | - | Color used for the collapse arrows. |
| `theme.colorText` | string | - | Color of the resize dots indicator. |
| `theme.colorBgElevated` | string | - | Background color of the drag trigger handle. |
| `theme.borderRadius` | number | `6` | Border radius of the drag trigger handle. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onCollapse` | `{ collapsed, sizes }` | Trigger action when a panel is collapsed or expanded. |
| `onResize` | `{ sizes }` | Trigger action when panel sizes change during resize. |
| `onResizeEnd` | `{ sizes }` | Trigger action when resize ends. |
| `onResizeStart` | `{ sizes }` | Trigger action when resize starts. |
| `onDraggerDoubleClick` | `{ index }` | Trigger action when a drag handle is double-clicked. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Splitter element. |
| `/panel` | Each Splitter panel. |
| `/dragger` | The drag handle between panels. |
| `/draggerIcon` | The custom icon in the drag handle, set with draggerIcon. |
| `/collapseIcon` | The collapse icons on the drag handles of collapsible panels. |
Slot keys are user-defined in your config and resolved at build time — not generated at runtime. The block typically pairs slots with an array property (`tabs`, `panels`, `slides`) listed in the Properties table; see the examples above for the expected shape.
---
url: https://docs.lowdefy.com/md/container-blocks/spinner.md
---
# Spinner
Loading spinner overlay for content areas.
```yaml
- id: spinner_default
type: Spinner
```
```yaml
- id: spinner_named_small
type: Spinner
layout:
flex: 0 0 auto
properties:
size: small
- id: spinner_named_medium
type: Spinner
layout:
flex: 0 0 auto
properties:
size: medium
- id: spinner_named_large
type: Spinner
layout:
flex: 0 0 auto
properties:
size: large
```
```yaml
- id: spinner_numeric_16
type: Spinner
layout:
flex: 0 0 auto
properties:
size: 16
- id: spinner_numeric_32
type: Spinner
layout:
flex: 0 0 auto
properties:
size: 32
- id: spinner_numeric_64
type: Spinner
layout:
flex: 0 0 auto
properties:
size: 64
```
```yaml
- id: spinner_styled_blue
type: Spinner
layout:
flex: 0 0 auto
class:
element: text-blue-500
properties:
size: large
- id: spinner_styled_green
type: Spinner
layout:
flex: 0 0 auto
class:
element: text-green-500
properties:
size: large
- id: spinner_styled_red
type: Spinner
layout:
flex: 0 0 auto
class:
element: text-red-500
properties:
size: large
- id: spinner_styled_purple
type: Spinner
layout:
flex: 0 0 auto
class:
element: text-purple-600
properties:
size: large
```
```yaml
- id: spinner_css_bg_pill
type: Spinner
layout:
flex: 0 0 auto
class:
element: bg-blue-50 p-4 rounded-full
properties:
size: large
- id: spinner_css_bordered
type: Spinner
layout:
flex: 0 0 auto
class:
element: border border-gray-200 p-3 rounded-lg bg-white shadow-sm
properties:
size: medium
- id: spinner_css_dark_bg
type: Spinner
layout:
flex: 0 0 auto
class:
element: bg-gray-800 text-white p-4 rounded-xl
properties:
size: large
```
```yaml
- id: spinner_style_custom_color
type: Spinner
layout:
flex: 0 0 auto
style:
.element:
color: "#fa8c16"
properties:
size: large
- id: spinner_style_padded
type: Spinner
layout:
flex: 0 0 auto
style:
.element:
padding: 16px
backgroundColor: "#f6ffed"
borderRadius: 12px
properties:
size: medium
```
Loading orders...
```yaml
- id: spinner_loading_overlay_card
type: Card
properties:
title: Recent Orders
slots:
extra:
blocks:
- id: spinner_loading_overlay_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Refresh
icon: refresh
color: primary
variant: outlined
size: small
events:
onClick:
- id: spinner_loading_overlay_msg
type: DisplayMessage
params:
content: Fetching latest orders...
duration: 2
blocks:
- id: spinner_loading_overlay_box
type: Box
layout:
direction: column
align: center
justify: center
gap: 12
style:
.element:
minHeight: 200px
blocks:
- id: spinner_loading_overlay_spinner
type: Spinner
layout:
flex: 0 0 auto
class:
element: text-blue-500
properties:
size: large
- id: spinner_loading_overlay_text
type: Paragraph
layout:
flex: 0 0 auto
class: text-gray-400
properties:
content: Loading orders...
```
```yaml
- id: spinner_btn_loading_card
type: Card
properties:
title: Submit Application
blocks:
- id: spinner_btn_loading_form_name
type: TextInput
properties:
label:
title: Full Name
placeholder: Enter your name
- id: spinner_btn_loading_form_email
type: TextInput
properties:
label:
title: Email Address
placeholder: you@example.com
- id: spinner_btn_loading_row
type: Box
layout:
gap: 12
align: center
justify: end
blocks:
- id: spinner_btn_loading_indicator
type: Spinner
layout:
flex: 0 0 auto
class:
element: text-blue-500
visible:
_if:
test:
_eq:
- _state: submitting
- true
then: true
else: false
properties:
size: small
- id: spinner_btn_loading_submit
type: Button
layout:
flex: 0 0 auto
properties:
title: Submit
color: primary
variant: solid
icon: send
events:
onClick:
- id: spinner_btn_loading_set_state
type: SetState
params:
submitting: true
- id: spinner_btn_loading_msg
type: DisplayMessage
params:
content: Application submitted successfully!
duration: 3
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `size` | string \| number | - | Size of the icon spinner: small, medium, large, or a pixel number. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Spinner element. |
No slots defined.
---
url: https://docs.lowdefy.com/md/container-blocks/tabs.md
---
# Tabs
Tab panels with card, editable, and positioned variants.
Personal Information
Manage your personal information, display name, and avatar. Changes are saved automatically across all your connected devices.
Preferences
Configure application preferences, notification settings, and keyboard shortcuts. These settings apply to your current workspace.
Billing Details
View your current plan, payment history, and update billing information. Your next invoice is scheduled for the first of next month.
```yaml
- id: basic_tabs
type: Tabs
properties:
tabs:
- key: profile
title: Profile
- key: settings
title: Settings
- key: billing
title: Billing
slots:
profile:
blocks:
- id: basic_profile_title
type: Title
properties:
content: Personal Information
level: 4
- id: basic_profile_content
type: Paragraph
properties:
content: Manage your personal information, display name, and avatar. Changes are
saved automatically across all your connected devices.
settings:
blocks:
- id: basic_settings_title
type: Title
properties:
content: Preferences
level: 4
- id: basic_settings_content
type: Paragraph
properties:
content: Configure application preferences, notification settings, and keyboard
shortcuts. These settings apply to your current workspace.
billing:
blocks:
- id: basic_billing_title
type: Title
properties:
content: Billing Details
level: 4
- id: basic_billing_content
type: Paragraph
properties:
content: View your current plan, payment history, and update billing
information. Your next invoice is scheduled for the first of next
month.
```
Dashboard overview showing key metrics and recent activity for your project.
Conversion funnel progress for the current quarter.
Generate and download reports for weekly, monthly, and quarterly performance summaries. Select a date range to get started.
Export your data in CSV, JSON, or PDF format. Scheduled exports run daily at midnight UTC.
```yaml
- id: card_tabs
type: Tabs
properties:
tabType: card
tabs:
- key: overview
title: Overview
- key: analytics
title: Analytics
- key: reports
title: Reports
- key: exports
title: Exports
slots:
overview:
blocks:
- id: card_overview_row
type: Box
layout:
gap: 16
blocks:
- id: card_stat_users
type: Statistic
layout:
flex: 1 1 0
properties:
title: Active Users
value: 1284
- id: card_stat_sessions
type: Statistic
layout:
flex: 1 1 0
properties:
title: Sessions Today
value: 3567
- id: card_stat_revenue
type: Statistic
layout:
flex: 1 1 0
properties:
title: Revenue
value: 48250
prefix: $
- id: card_overview_content
type: Paragraph
properties:
content: Dashboard overview showing key metrics and recent activity for your
project.
analytics:
blocks:
- id: card_analytics_progress_label
type: Paragraph
properties:
content: Conversion funnel progress for the current quarter.
- id: card_analytics_progress
type: Progress
properties:
percent: 72
status: active
reports:
blocks:
- id: card_reports_content
type: Paragraph
properties:
content: Generate and download reports for weekly, monthly, and quarterly
performance summaries. Select a date range to get started.
exports:
blocks:
- id: card_exports_content
type: Paragraph
properties:
content: Export your data in CSV, JSON, or PDF format. Scheduled exports run
daily at midnight UTC.
```
**Top (default):**
Tabs positioned at the top are the most common layout, suitable for primary navigation within a section.
This is the second tab in the top-positioned layout.
This is the third tab in the top-positioned layout.
**Bottom:**
You have 12 unread messages. The most recent is from the engineering team regarding deployment schedules.
Your last sent message was a project status update to the stakeholders group.
You have 3 saved drafts including the quarterly review document and team feedback form.
**Start:**
General application settings including workspace name, default language, and timezone configuration.
Two-factor authentication, session management, and login history for your account.
Connect with third-party services like Slack, GitHub, Jira, and Google Workspace.
Manage API keys for programmatic access. Create, revoke, and monitor usage of your tokens.
**End:**
Premium wireless headphones with active noise cancellation, 30-hour battery life, and comfortable over-ear design.
4.7 out of 5 stars based on 2,340 reviews. Customers praise the sound quality and battery life.
Free standard shipping (3-5 business days). Express shipping available for $9.99 (1-2 business days).
```yaml
- id: pos_top_label
type: Markdown
properties:
content: "**Top (default):**"
- id: pos_top_tabs
type: Tabs
properties:
tabPlacement: top
tabs:
- key: pos_top_first
title: First
- key: pos_top_second
title: Second
- key: pos_top_third
title: Third
slots:
pos_top_first:
blocks:
- id: pos_top_first_content
type: Paragraph
properties:
content: Tabs positioned at the top are the most common layout, suitable for
primary navigation within a section.
pos_top_second:
blocks:
- id: pos_top_second_content
type: Paragraph
properties:
content: This is the second tab in the top-positioned layout.
pos_top_third:
blocks:
- id: pos_top_third_content
type: Paragraph
properties:
content: This is the third tab in the top-positioned layout.
- id: pos_bottom_label
type: Markdown
properties:
content: "**Bottom:**"
- id: pos_bottom_tabs
type: Tabs
properties:
tabPlacement: bottom
tabs:
- key: pos_bot_inbox
title: Inbox
- key: pos_bot_sent
title: Sent
- key: pos_bot_drafts
title: Drafts
slots:
pos_bot_inbox:
blocks:
- id: pos_bot_inbox_content
type: Paragraph
properties:
content: You have 12 unread messages. The most recent is from the engineering
team regarding deployment schedules.
pos_bot_sent:
blocks:
- id: pos_bot_sent_content
type: Paragraph
properties:
content: Your last sent message was a project status update to the stakeholders
group.
pos_bot_drafts:
blocks:
- id: pos_bot_drafts_content
type: Paragraph
properties:
content: You have 3 saved drafts including the quarterly review document and
team feedback form.
- id: pos_start_label
type: Markdown
properties:
content: "**Start:**"
- id: pos_left_tabs
type: Tabs
properties:
tabPlacement: start
tabs:
- key: pos_left_general
title: General
- key: pos_left_security
title: Security
- key: pos_left_integrations
title: Integrations
- key: pos_left_api
title: API Keys
slots:
pos_left_general:
blocks:
- id: pos_left_general_content
type: Paragraph
properties:
content: General application settings including workspace name, default
language, and timezone configuration.
pos_left_security:
blocks:
- id: pos_left_security_content
type: Paragraph
properties:
content: Two-factor authentication, session management, and login history for
your account.
pos_left_integrations:
blocks:
- id: pos_left_integrations_content
type: Paragraph
properties:
content: Connect with third-party services like Slack, GitHub, Jira, and Google
Workspace.
pos_left_api:
blocks:
- id: pos_left_api_content
type: Paragraph
properties:
content: Manage API keys for programmatic access. Create, revoke, and monitor
usage of your tokens.
- id: pos_end_label
type: Markdown
properties:
content: "**End:**"
- id: pos_right_tabs
type: Tabs
properties:
tabPlacement: end
tabs:
- key: pos_right_desc
title: Description
- key: pos_right_reviews
title: Reviews
- key: pos_right_shipping
title: Shipping
slots:
pos_right_desc:
blocks:
- id: pos_right_desc_content
type: Paragraph
properties:
content: Premium wireless headphones with active noise cancellation, 30-hour
battery life, and comfortable over-ear design.
pos_right_reviews:
blocks:
- id: pos_right_reviews_content
type: Paragraph
properties:
content: 4.7 out of 5 stars based on 2,340 reviews. Customers praise the sound
quality and battery life.
pos_right_shipping:
blocks:
- id: pos_right_shipping_content
type: Paragraph
properties:
content: Free standard shipping (3-5 business days). Express shipping available
for $9.99 (1-2 business days).
```
Billed every month. Cancel any time.
Billed once a year with two months free.
```yaml
- id: centered_tabs
type: Tabs
properties:
centered: true
tabBarGutter: 40
indicator:
size: 24
align: center
tabs:
- key: centered_monthly
title: Monthly
- key: centered_yearly
title: Yearly
slots:
centered_monthly:
blocks:
- id: centered_monthly_content
type: Paragraph
properties:
content: Billed every month. Cancel any time.
centered_yearly:
blocks:
- id: centered_yearly_content
type: Paragraph
properties:
content: Billed once a year with two months free.
```
**Small:**
Compact tabs for dense interfaces where screen space is at a premium. Ideal for side panels and secondary navigation.
Technical specifications displayed in a compact view.
Internal notes and comments in small tab format.
**Default:**
Standard-sized tabs for most use cases. Provides a balanced reading experience and comfortable click targets.
Technical specifications displayed in standard tab format.
Internal notes and comments in default tab format.
**Large:**
Large tabs for prominent navigation areas and primary page sections. Gives a spacious, easy-to-read layout.
Technical specifications displayed with large, prominent tab headers.
Internal notes and comments with large tab format for emphasis.
```yaml
- id: size_small_label
type: Markdown
properties:
content: "**Small:**"
- id: size_small_tabs
type: Tabs
properties:
size: small
tabs:
- key: sm_details
title: Details
- key: sm_specs
title: Specifications
- key: sm_notes
title: Notes
slots:
sm_details:
blocks:
- id: sm_details_content
type: Paragraph
properties:
content: Compact tabs for dense interfaces where screen space is at a premium.
Ideal for side panels and secondary navigation.
sm_specs:
blocks:
- id: sm_specs_content
type: Paragraph
properties:
content: Technical specifications displayed in a compact view.
sm_notes:
blocks:
- id: sm_notes_content
type: Paragraph
properties:
content: Internal notes and comments in small tab format.
- id: size_default_label
type: Markdown
properties:
content: "**Default:**"
- id: size_default_tabs
type: Tabs
properties:
size: default
tabs:
- key: def_details
title: Details
- key: def_specs
title: Specifications
- key: def_notes
title: Notes
slots:
def_details:
blocks:
- id: def_details_content
type: Paragraph
properties:
content: Standard-sized tabs for most use cases. Provides a balanced reading
experience and comfortable click targets.
def_specs:
blocks:
- id: def_specs_content
type: Paragraph
properties:
content: Technical specifications displayed in standard tab format.
def_notes:
blocks:
- id: def_notes_content
type: Paragraph
properties:
content: Internal notes and comments in default tab format.
- id: size_large_label
type: Markdown
properties:
content: "**Large:**"
- id: size_large_tabs
type: Tabs
properties:
size: large
tabs:
- key: lg_details
title: Details
- key: lg_specs
title: Specifications
- key: lg_notes
title: Notes
slots:
lg_details:
blocks:
- id: lg_details_content
type: Paragraph
properties:
content: Large tabs for prominent navigation areas and primary page sections.
Gives a spacious, easy-to-read layout.
lg_specs:
blocks:
- id: lg_specs_content
type: Paragraph
properties:
content: Technical specifications displayed with large, prominent tab headers.
lg_notes:
blocks:
- id: lg_notes_content
type: Paragraph
properties:
content: Internal notes and comments with large tab format for emphasis.
```
**Small card:**
Small card tabs are compact and fit well in tight layouts or secondary navigation areas.
Second tab of the small card variant.
Third tab of the small card variant.
**Default card:**
Default card tabs provide a standard raised panel appearance, commonly used for content organization.
Second tab of the default card variant.
Third tab of the default card variant.
**Large card:**
Large card tabs have more padding and larger font, making them ideal for primary dashboard navigation.
Second tab of the large card variant.
Third tab of the large card variant.
```yaml
- id: card_sm_label
type: Markdown
properties:
content: "**Small card:**"
- id: card_small_tabs
type: Tabs
properties:
tabType: card
size: small
tabs:
- key: csm_tab1
title: Tab 1
- key: csm_tab2
title: Tab 2
- key: csm_tab3
title: Tab 3
slots:
csm_tab1:
blocks:
- id: csm_tab1_content
type: Paragraph
properties:
content: Small card tabs are compact and fit well in tight layouts or secondary
navigation areas.
csm_tab2:
blocks:
- id: csm_tab2_content
type: Paragraph
properties:
content: Second tab of the small card variant.
csm_tab3:
blocks:
- id: csm_tab3_content
type: Paragraph
properties:
content: Third tab of the small card variant.
- id: card_def_label
type: Markdown
properties:
content: "**Default card:**"
- id: card_default_tabs
type: Tabs
properties:
tabType: card
size: default
tabs:
- key: cdf_tab1
title: Tab 1
- key: cdf_tab2
title: Tab 2
- key: cdf_tab3
title: Tab 3
slots:
cdf_tab1:
blocks:
- id: cdf_tab1_content
type: Paragraph
properties:
content: Default card tabs provide a standard raised panel appearance, commonly
used for content organization.
cdf_tab2:
blocks:
- id: cdf_tab2_content
type: Paragraph
properties:
content: Second tab of the default card variant.
cdf_tab3:
blocks:
- id: cdf_tab3_content
type: Paragraph
properties:
content: Third tab of the default card variant.
- id: card_lg_label
type: Markdown
properties:
content: "**Large card:**"
- id: card_large_tabs
type: Tabs
properties:
tabType: card
size: large
tabs:
- key: clg_tab1
title: Tab 1
- key: clg_tab2
title: Tab 2
- key: clg_tab3
title: Tab 3
slots:
clg_tab1:
blocks:
- id: clg_tab1_content
type: Paragraph
properties:
content: Large card tabs have more padding and larger font, making them ideal
for primary dashboard navigation.
clg_tab2:
blocks:
- id: clg_tab2_content
type: Paragraph
properties:
content: Second tab of the large card variant.
clg_tab3:
blocks:
- id: clg_tab3_content
type: Paragraph
properties:
content: Third tab of the large card variant.
```
Welcome to the dashboard. Here you can view recent activity, quick statistics, and announcements from your team.
Application configuration, theme settings, and advanced options. Changes take effect immediately.
Monthly target progress at 85%. On track for completion by end of quarter.
```yaml
- id: icon_tabs
type: Tabs
properties:
tabs:
- key: icon_home
title: Home
icon: home
- key: icon_users
title: Users
icon: users
- key: icon_settings
title: Settings
icon: settings
- key: icon_chart
title: Analytics
icon: chart
slots:
icon_home:
blocks:
- id: icon_home_content
type: Paragraph
properties:
content: Welcome to the dashboard. Here you can view recent activity, quick
statistics, and announcements from your team.
icon_users:
blocks:
- id: icon_users_desc
type: Descriptions
properties:
bordered: true
size: small
items:
- label: Total Members
value: "24"
- label: Active Now
value: "8"
- label: Pending Invites
value: "3"
icon_settings:
blocks:
- id: icon_settings_content
type: Paragraph
properties:
content: Application configuration, theme settings, and advanced options.
Changes take effect immediately.
icon_chart:
blocks:
- id: icon_chart_progress
type: Progress
properties:
percent: 85
status: active
- id: icon_chart_note
type: Paragraph
properties:
content: Monthly target progress at 85%. On track for completion by end of
quarter.
```
> 3 Deprecation Warnings
```yaml
- id: custom_icon_tabs
type: Tabs
properties:
tabs:
- key: ci_success
title: Passed
icon:
name: check-circle
color: "#52c41a"
- key: ci_warning
title: Warnings
icon:
name: warning
color: "#faad14"
- key: ci_error
title: Failed
icon:
name: close-circle
color: "#ff4d4f"
slots:
ci_success:
blocks:
- id: ci_success_result
type: Result
properties:
status: success
title: All Tests Passed
subTitle: 142 tests completed successfully in 4.2 seconds.
ci_warning:
blocks:
- id: ci_warning_alert
type: Alert
properties:
message: 3 Deprecation Warnings
description: Some test suites use deprecated assertion methods. Please update to
the latest API.
type: warning
showIcon: true
ci_error:
blocks:
- id: ci_error_result
type: Result
properties:
status: error
title: 2 Tests Failed
subTitle: Check the error log below for details on the failing assertions.
```
This tab is accessible and contains normal content. Users can freely navigate to this section.
This content is not yet available. The tab is disabled to indicate an upcoming feature.
> Beta Feature
This section requires an upgraded subscription plan to access.
```yaml
- id: disabled_tabs
type: Tabs
properties:
tabs:
- key: dis_active
title: Active
- key: dis_coming_soon
title: Coming Soon
disabled: true
- key: dis_beta
title: Beta
- key: dis_locked
title: Locked
disabled: true
slots:
dis_active:
blocks:
- id: dis_active_content
type: Paragraph
properties:
content: This tab is accessible and contains normal content. Users can freely
navigate to this section.
dis_coming_soon:
blocks:
- id: dis_coming_soon_content
type: Paragraph
properties:
content: This content is not yet available. The tab is disabled to indicate an
upcoming feature.
dis_beta:
blocks:
- id: dis_beta_alert
type: Alert
properties:
message: Beta Feature
description: This feature is currently in beta. Some functionality may be
incomplete or change without notice.
type: info
showIcon: true
dis_locked:
blocks:
- id: dis_locked_content
type: Paragraph
properties:
content: This section requires an upgraded subscription plan to access.
```
This is the first tab. It is not active by default because defaultActiveKey is set to the second tab.
> This tab is active by default
This is the third tab with regular content.
```yaml
- id: default_key_tabs
type: Tabs
properties:
defaultActiveKey: dk_second
tabs:
- key: dk_first
title: First
- key: dk_second
title: Second (Default)
- key: dk_third
title: Third
slots:
dk_first:
blocks:
- id: dk_first_content
type: Paragraph
properties:
content: This is the first tab. It is not active by default because
defaultActiveKey is set to the second tab.
dk_second:
blocks:
- id: dk_second_content
type: Alert
properties:
message: This tab is active by default
description: The defaultActiveKey property is set to "dk_second", so this tab is
shown when the component first renders.
type: success
showIcon: true
dk_third:
blocks:
- id: dk_third_content
type: Paragraph
properties:
content: This is the third tab with regular content.
```
Browse your uploaded documents. Supported formats include PDF, DOCX, TXT, and Markdown files. Use the Upload button in the tab bar to add new files.
View your image gallery. Supports JPEG, PNG, SVG, and WebP formats up to 10MB each.
Your video library. Supports MP4, WebM, and MOV formats. Maximum file size is 500MB.
```yaml
- id: extra_tabs
type: Tabs
properties:
extraAreaKey: extra_area
tabs:
- key: extra_documents
title: Documents
- key: extra_images
title: Images
- key: extra_videos
title: Videos
slots:
extra_area:
blocks:
- id: extra_area_button
type: Button
layout:
flex: 0 0 auto
properties:
title: Upload
icon: upload
color: primary
variant: solid
size: small
extra_documents:
blocks:
- id: extra_documents_content
type: Paragraph
properties:
content: Browse your uploaded documents. Supported formats include PDF, DOCX,
TXT, and Markdown files. Use the Upload button in the tab bar to
add new files.
extra_images:
blocks:
- id: extra_images_content
type: Paragraph
properties:
content: View your image gallery. Supports JPEG, PNG, SVG, and WebP formats up
to 10MB each.
extra_videos:
blocks:
- id: extra_videos_content
type: Paragraph
properties:
content: Your video library. Supports MP4, WebM, and MOV formats. Maximum file
size is 500MB.
```
Quarterly target progress
> 2 open positions
Recent Activity
10:42 AM - Sarah merged pull request #247 into main branch.
09:15 AM - James deployed v2.4.1 to production environment.
Yesterday - Alex created 3 new issues in the backlog tracker.
```yaml
- id: rich_tabs
type: Tabs
properties:
tabs:
- key: rich_dashboard
title: Dashboard
icon: Gauge
- key: rich_team
title: Team
icon: users
- key: rich_activity
title: Activity
icon: history
slots:
rich_dashboard:
blocks:
- id: rich_dash_stats
type: Box
layout:
gap: 16
blocks:
- id: rich_stat_1
type: Statistic
layout:
flex: 1 1 0
properties:
title: Total Revenue
value: 126560
prefix: $
precision: 2
- id: rich_stat_2
type: Statistic
layout:
flex: 1 1 0
properties:
title: Active Users
value: 8846
- id: rich_stat_3
type: Statistic
layout:
flex: 1 1 0
properties:
title: Completion Rate
value: 93.2
suffix: "%"
- id: rich_dash_divider
type: Divider
- id: rich_dash_progress_label
type: Paragraph
properties:
content: Quarterly target progress
- id: rich_dash_progress
type: Progress
properties:
percent: 78
status: active
rich_team:
blocks:
- id: rich_team_desc
type: Descriptions
properties:
bordered: true
column: 2
items:
- label: Engineering
value: 12 members
- label: Design
value: 5 members
- label: Product
value: 4 members
- label: QA
value: 3 members
- id: rich_team_divider
type: Divider
- id: rich_team_note
type: Alert
properties:
message: 2 open positions
description: Senior Backend Engineer and Product Designer roles are currently
hiring.
type: info
showIcon: true
rich_activity:
blocks:
- id: rich_activity_title
type: Title
properties:
content: Recent Activity
level: 5
- id: rich_activity_item_1
type: Paragraph
properties:
content: "10:42 AM - Sarah merged pull request #247 into main branch."
- id: rich_activity_divider_1
type: Divider
properties:
dashed: true
- id: rich_activity_item_2
type: Paragraph
properties:
content: 09:15 AM - James deployed v2.4.1 to production environment.
- id: rich_activity_divider_2
type: Divider
properties:
dashed: true
- id: rich_activity_item_3
type: Paragraph
properties:
content: Yesterday - Alex created 3 new issues in the backlog tracker.
```
January report - Q1 kickoff with team planning sessions and annual goal setting. Revenue target set at $1.2M.
February report - Sprint planning completed. 3 new team members onboarded. Infrastructure migration started.
March report - Q1 close. Revenue hit 108% of target. Product launch scheduled for April.
April report - Product v2.0 launched successfully. 500 new signups in the first week.
May report - Customer feedback collected and prioritized. Feature roadmap updated for Q3.
June report - Q2 close. Revenue exceeded targets by 15%. Team offsite and retrospective completed.
July report - H2 planning underway. Engineering team focused on performance optimizations.
August report - Beta testing for v3.0 started with 50 partner organizations.
September report - Q3 close. Beta feedback incorporated. Security audit completed with no critical findings.
October report - v3.0 released to general availability. Conference presentation at TechSummit.
November report - Black Friday promotion drove 200% increase in signups. Support team scaled up.
December report - Year-end review. Annual revenue target exceeded by 22%. Holiday code freeze in effect.
```yaml
- id: scroll_tabs
type: Tabs
properties:
tabs:
- key: scroll_jan
title: January
- key: scroll_feb
title: February
- key: scroll_mar
title: March
- key: scroll_apr
title: April
- key: scroll_may
title: May
- key: scroll_jun
title: June
- key: scroll_jul
title: July
- key: scroll_aug
title: August
- key: scroll_sep
title: September
- key: scroll_oct
title: October
- key: scroll_nov
title: November
- key: scroll_dec
title: December
slots:
scroll_jan:
blocks:
- id: scroll_jan_content
type: Paragraph
properties:
content: January report - Q1 kickoff with team planning sessions and annual goal
setting. Revenue target set at $1.2M.
scroll_feb:
blocks:
- id: scroll_feb_content
type: Paragraph
properties:
content: February report - Sprint planning completed. 3 new team members
onboarded. Infrastructure migration started.
scroll_mar:
blocks:
- id: scroll_mar_content
type: Paragraph
properties:
content: March report - Q1 close. Revenue hit 108% of target. Product launch
scheduled for April.
scroll_apr:
blocks:
- id: scroll_apr_content
type: Paragraph
properties:
content: April report - Product v2.0 launched successfully. 500 new signups in
the first week.
scroll_may:
blocks:
- id: scroll_may_content
type: Paragraph
properties:
content: May report - Customer feedback collected and prioritized. Feature
roadmap updated for Q3.
scroll_jun:
blocks:
- id: scroll_jun_content
type: Paragraph
properties:
content: June report - Q2 close. Revenue exceeded targets by 15%. Team offsite
and retrospective completed.
scroll_jul:
blocks:
- id: scroll_jul_content
type: Paragraph
properties:
content: July report - H2 planning underway. Engineering team focused on
performance optimizations.
scroll_aug:
blocks:
- id: scroll_aug_content
type: Paragraph
properties:
content: August report - Beta testing for v3.0 started with 50 partner
organizations.
scroll_sep:
blocks:
- id: scroll_sep_content
type: Paragraph
properties:
content: September report - Q3 close. Beta feedback incorporated. Security audit
completed with no critical findings.
scroll_oct:
blocks:
- id: scroll_oct_content
type: Paragraph
properties:
content: October report - v3.0 released to general availability. Conference
presentation at TechSummit.
scroll_nov:
blocks:
- id: scroll_nov_content
type: Paragraph
properties:
content: November report - Black Friday promotion drove 200% increase in
signups. Support team scaled up.
scroll_dec:
blocks:
- id: scroll_dec_content
type: Paragraph
properties:
content: December report - Year-end review. Annual revenue target exceeded by
22%. Holiday code freeze in effect.
```
Configure which events trigger notifications. Choose between email, push, or in-app delivery for each category.
Customize your visual preferences including theme mode, accent color, font size, and compact layout options.
> Privacy Settings
```yaml
- id: left_card_tabs
type: Tabs
properties:
tabType: card
tabPlacement: start
tabs:
- key: lc_account
title: Account
- key: lc_notifications
title: Notifications
- key: lc_appearance
title: Appearance
- key: lc_privacy
title: Privacy
slots:
lc_account:
blocks:
- id: lc_account_desc
type: Descriptions
properties:
bordered: true
column: 1
items:
- label: Username
value: johndoe
- label: Email
value: john@example.com
- label: Role
value: Administrator
- label: Member Since
value: March 2024
lc_notifications:
blocks:
- id: lc_notif_content
type: Paragraph
properties:
content: Configure which events trigger notifications. Choose between email,
push, or in-app delivery for each category.
lc_appearance:
blocks:
- id: lc_appearance_content
type: Paragraph
properties:
content: Customize your visual preferences including theme mode, accent color,
font size, and compact layout options.
lc_privacy:
blocks:
- id: lc_privacy_alert
type: Alert
properties:
message: Privacy Settings
description: Your profile is currently set to public. Other workspace members
can see your name, avatar, and activity status.
type: warning
showIcon: true
```
Tab content switches instantly without any transition animation. This can be useful for performance-sensitive interfaces or when animation feels distracting.
The animated property is set to false, disabling both the ink bar animation and the content transition.
Compare this with the other tab examples on this page to see the difference in transition behavior.
```yaml
- id: no_anim_tabs
type: Tabs
properties:
animated: false
tabs:
- key: na_tab1
title: No Animation 1
- key: na_tab2
title: No Animation 2
- key: na_tab3
title: No Animation 3
slots:
na_tab1:
blocks:
- id: na_tab1_content
type: Paragraph
properties:
content: Tab content switches instantly without any transition animation. This
can be useful for performance-sensitive interfaces or when
animation feels distracting.
na_tab2:
blocks:
- id: na_tab2_content
type: Paragraph
properties:
content: The animated property is set to false, disabling both the ink bar
animation and the content transition.
na_tab3:
blocks:
- id: na_tab3_content
type: Paragraph
properties:
content: Compare this with the other tab examples on this page to see the
difference in transition behavior.
```
This example demonstrates CSS customization using the style property. The element has a light gray background with rounded corners, and the tab bar has extra bottom margin.
The tabBar, tabPane, and element CSS keys can be individually targeted. Each accepts standard CSS properties as an object.
Use style.element to control the outer wrapper, style.tabBar for the navigation strip, and style.tabPane for each content panel.
Dark-themed tabs using CSS overrides. Suitable for code editors, terminal views, or developer tool interfaces.
Output panel with matching dark theme. The element and tabBar CSS keys are styled together for a cohesive look.
Log viewer panel. Monospaced fonts and dark backgrounds reduce eye strain during extended debugging sessions.
```yaml
- id: css_tabs
type: Tabs
properties:
tabs:
- key: css_overview
title: Overview
- key: css_details
title: Details
- key: css_contact
title: Contact
style:
.element:
padding: 16px
borderRadius: 8px
.tabBar:
marginBottom: 24px
.tabPane:
padding: 12px
slots:
css_overview:
blocks:
- id: css_overview_content
type: Paragraph
properties:
content: This example demonstrates CSS customization using the style property.
The element has a light gray background with rounded corners, and
the tab bar has extra bottom margin.
css_details:
blocks:
- id: css_details_content
type: Paragraph
properties:
content: The tabBar, tabPane, and element CSS keys can be individually targeted.
Each accepts standard CSS properties as an object.
css_contact:
blocks:
- id: css_contact_content
type: Paragraph
properties:
content: Use style.element to control the outer wrapper, style.tabBar for the
navigation strip, and style.tabPane for each content panel.
- id: css_dark_tabs
type: Tabs
properties:
tabs:
- key: cssd_code
title: Code
- key: cssd_output
title: Output
- key: cssd_logs
title: Logs
style:
.element:
background: "#1e1e2e"
padding: 16px
borderRadius: 8px
color: "#cdd6f4"
.tabBar:
color: "#cdd6f4"
slots:
cssd_code:
blocks:
- id: cssd_code_content
type: Paragraph
properties:
content: Dark-themed tabs using CSS overrides. Suitable for code editors,
terminal views, or developer tool interfaces.
style:
.element:
color: "#cdd6f4"
cssd_output:
blocks:
- id: cssd_output_content
type: Paragraph
properties:
content: Output panel with matching dark theme. The element and tabBar CSS keys
are styled together for a cohesive look.
style:
.element:
color: "#cdd6f4"
cssd_logs:
blocks:
- id: cssd_logs_content
type: Paragraph
properties:
content: Log viewer panel. Monospaced fonts and dark backgrounds reduce eye
strain during extended debugging sessions.
style:
.element:
color: "#cdd6f4"
fontFamily: monospace
```
**Custom ink bar and text colors:**
The ink bar and selected tab text are green, overriding the default blue. Use inkBarColor, itemSelectedColor, itemHoverColor, and itemActiveColor tokens.
The garden planner helps you organize plant spacing, sunlight needs, and watering schedules throughout the growing season.
Track your harvest yields by week and compare against previous seasons to optimize your gardening strategy.
**Custom card tab appearance:**
Card tabs with a warm amber background and custom height. The cardBg, cardHeight, cardPadding, and cardGutter tokens control the card-type appearance.
Your saved favorite recipes. Browse your curated collection of breakfast, lunch, and dinner ideas.
Recently viewed recipes from the past 30 days. Quick access to dishes you have been exploring.
**Custom spacing and font size:**
Wider spacing between tabs using horizontalItemGutter token set to 48px (default is 32px). The title font size is increased to 16px with a purple accent color.
Chapter listing with spaced-out tab headers. The increased gutter gives each tab more visual breathing room.
Supplementary materials and reference tables. The larger font size makes the tab labels easier to read at a glance.
**Custom vertical tab tokens:**
Vertical tabs with custom padding and pink accent. The verticalItemPadding and verticalItemMargin tokens control spacing in left/right tab layouts.
Development phase with code reviews, testing, and continuous integration. The pink accent differentiates this tab set from others on the page.
Deployment pipeline configuration. Preview environments, staging, and production release management.
```yaml
- id: theme_custom_colors
type: Markdown
properties:
content: "**Custom ink bar and text colors:**"
- id: theme_color_tabs
type: Tabs
properties:
theme:
inkBarColor: "#52c41a"
itemSelectedColor: "#52c41a"
itemHoverColor: "#73d13d"
itemActiveColor: "#389e0d"
tabs:
- key: tc_plants
title: Plants
- key: tc_garden
title: Garden
- key: tc_harvest
title: Harvest
slots:
tc_plants:
blocks:
- id: tc_plants_content
type: Paragraph
properties:
content: The ink bar and selected tab text are green, overriding the default
blue. Use inkBarColor, itemSelectedColor, itemHoverColor, and
itemActiveColor tokens.
tc_garden:
blocks:
- id: tc_garden_content
type: Paragraph
properties:
content: The garden planner helps you organize plant spacing, sunlight needs,
and watering schedules throughout the growing season.
tc_harvest:
blocks:
- id: tc_harvest_content
type: Paragraph
properties:
content: Track your harvest yields by week and compare against previous seasons
to optimize your gardening strategy.
- id: theme_card_label
type: Markdown
properties:
content: "**Custom card tab appearance:**"
- id: theme_card_tabs
type: Tabs
properties:
tabType: card
theme:
cardHeight: 48
cardPadding: 12px 24px
cardGutter: 4
itemSelectedColor: "#d46b08"
itemColor: "#874d00"
tabs:
- key: tcd_recipes
title: Recipes
- key: tcd_favorites
title: Favorites
- key: tcd_recent
title: Recent
slots:
tcd_recipes:
blocks:
- id: tcd_recipes_content
type: Paragraph
properties:
content: Card tabs with a warm amber background and custom height. The cardBg,
cardHeight, cardPadding, and cardGutter tokens control the
card-type appearance.
tcd_favorites:
blocks:
- id: tcd_favorites_content
type: Paragraph
properties:
content: Your saved favorite recipes. Browse your curated collection of
breakfast, lunch, and dinner ideas.
tcd_recent:
blocks:
- id: tcd_recent_content
type: Paragraph
properties:
content: Recently viewed recipes from the past 30 days. Quick access to dishes
you have been exploring.
- id: theme_spacing_label
type: Markdown
properties:
content: "**Custom spacing and font size:**"
- id: theme_spacing_tabs
type: Tabs
properties:
theme:
horizontalItemGutter: 48
horizontalItemPadding: 16px 0
titleFontSize: 16
inkBarColor: "#722ed1"
itemSelectedColor: "#722ed1"
itemHoverColor: "#9254de"
tabs:
- key: ts_intro
title: Introduction
- key: ts_chapters
title: Chapters
- key: ts_appendix
title: Appendix
slots:
ts_intro:
blocks:
- id: ts_intro_content
type: Paragraph
properties:
content: Wider spacing between tabs using horizontalItemGutter token set to 48px
(default is 32px). The title font size is increased to 16px with a
purple accent color.
ts_chapters:
blocks:
- id: ts_chapters_content
type: Paragraph
properties:
content: Chapter listing with spaced-out tab headers. The increased gutter gives
each tab more visual breathing room.
ts_appendix:
blocks:
- id: ts_appendix_content
type: Paragraph
properties:
content: Supplementary materials and reference tables. The larger font size
makes the tab labels easier to read at a glance.
- id: theme_vertical_label
type: Markdown
properties:
content: "**Custom vertical tab tokens:**"
- id: theme_vertical_tabs
type: Tabs
properties:
tabPlacement: start
theme:
verticalItemPadding: 12px 32px
verticalItemMargin: 8px 0 0 0
inkBarColor: "#eb2f96"
itemSelectedColor: "#eb2f96"
itemHoverColor: "#f759ab"
titleFontSize: 15
tabs:
- key: tv_design
title: Design
- key: tv_develop
title: Develop
- key: tv_deploy
title: Deploy
slots:
tv_design:
blocks:
- id: tv_design_content
type: Paragraph
properties:
content: Vertical tabs with custom padding and pink accent. The
verticalItemPadding and verticalItemMargin tokens control spacing
in left/right tab layouts.
tv_develop:
blocks:
- id: tv_develop_content
type: Paragraph
properties:
content: Development phase with code reviews, testing, and continuous
integration. The pink accent differentiates this tab set from
others on the page.
tv_deploy:
blocks:
- id: tv_deploy_content
type: Paragraph
properties:
content: Deployment pipeline configuration. Preview environments, staging, and
production release management.
```
Tab titles support HTML content. The first tab title uses bold text via the b tag. This is useful for emphasizing key tabs.
The second tab simulates a notification badge using a superscript element with red color. A lightweight alternative to separate badge components.
The third tab uses an inline span with green color to indicate active status directly in the tab title.
```yaml
- id: html_tabs
type: Tabs
properties:
tabs:
- key: html_bold
title: Important
- key: html_badge
title: 'Messages 3 '
- key: html_colored
title: 'Active '
slots:
html_bold:
blocks:
- id: html_bold_content
type: Paragraph
properties:
content: Tab titles support HTML content. The first tab title uses bold text via
the b tag. This is useful for emphasizing key tabs.
html_badge:
blocks:
- id: html_badge_content
type: Paragraph
properties:
content: The second tab simulates a notification badge using a superscript
element with red color. A lightweight alternative to separate
badge components.
html_colored:
blocks:
- id: html_colored_content
type: Paragraph
properties:
content: The third tab uses an inline span with green color to indicate active
status directly in the tab title.
```
Press Cmd+1 (Mac) or Ctrl+1 (Windows) to jump to this tab.
Press Cmd+2 (Mac) or Ctrl+2 (Windows) to jump to this tab.
Press Cmd+3 (Mac) or Ctrl+3 (Windows) to jump to this tab.
```yaml
- id: shortcut_tabs
type: Tabs
properties:
tabs:
- key: overview
title: Overview
shortcut: mod+1
- key: details
title: Details
shortcut: mod+2
- key: history
title: History
shortcut: mod+3
events:
onChange:
- id: shortcut_tab_msg
type: DisplayMessage
params:
content:
_string.concat:
- "Switched to: "
- _event: activeKey
status: info
slots:
overview:
blocks:
- id: shortcut_overview_content
type: Paragraph
properties:
content: Press Cmd+1 (Mac) or Ctrl+1 (Windows) to jump to this tab.
details:
blocks:
- id: shortcut_details_content
type: Paragraph
properties:
content: Press Cmd+2 (Mac) or Ctrl+2 (Windows) to jump to this tab.
history:
blocks:
- id: shortcut_history_content
type: Paragraph
properties:
content: Press Cmd+3 (Mac) or Ctrl+3 (Windows) to jump to this tab.
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `animated` | boolean | `true` | Whether to change tabs with animation. Only works while tabPlacement is top or bottom. |
| `centered` | boolean | `false` | Center the tabs in the tab bar. |
| `defaultActiveKey` | string | - | Initial active TabPane's key, if activeKey is not set. |
| `destroyOnHidden` | boolean | `false` | Unmount the content of inactive tabs. Blocks in a hidden tab keep their state values. |
| `indicator` | object | - | Size and alignment of the active tab indicator (ink bar). |
| `indicator.size` | number | - | Length of the indicator in pixels. Defaults to the width of the tab. |
| `indicator.align` | string | `"center"` | Alignment of the indicator along the tab when size is set. Enum: `start`, `center`, `end`. |
| `tabBarGutter` | number | - | Gap between tabs in pixels. |
| `size` | string | `"default"` | Size of the tabs. Enum: `default`, `small`, `large`. |
| `tabPlacement` | string | `"top"` | Position of the tabs. Enum: `top`, `end`, `bottom`, `start`. |
| `tabType` | string | `"line"` | Type of tabs. Enum: `line`, `card`. |
| `tabs` | array | - | |
| `tabs.$.title` | string | - | Title of the tab - supports html. |
| `tabs.$.key` | string | - | Area key of the tab. |
| `tabs.$.eventName` | string | - | Block-level event name to trigger when this tab becomes active, in addition to onChange. Declare an event with this name under `events:`. The event receives `{ key }` of the now-active tab. |
| `tabs.$.disabled` | boolean | `false` | Disable the tab if true. |
| `tabs.$.icon` | string \| object | - | Icon name (a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`) or properties of an Icon block to customize icon to show in tab title. |
| `tabs.$.icon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `tabs.$.icon.color` | string | - | Icon color. |
| `tabs.$.icon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `tabs.$.icon.rotate` | number | - | Number of degrees to rotate the icon. |
| `tabs.$.icon.spin` | boolean | - | Continuously spin the icon with animation. |
| `tabs.$.icon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `tabs.$.icon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `tabs.$.icon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `tabs.$.icon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `tabs.$.shortcut` | string | - | Keyboard shortcut to switch to this tab. Use "mod" for Cmd/Ctrl. |
| `extraAreaKey` | string | - | Area key for the extra area blocks. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design tabs tokens](https://ant.design/components/tabs#design-token). |
| `theme.cardBg` | string | `"rgba(0, 0, 0, 0.02)"` | Background color of card-type tab. |
| `theme.cardGutter` | number | `2` | Gap between card-type tabs. |
| `theme.cardHeight` | number | `40` | Height of card-type tab. |
| `theme.cardHeightSM` | number | `32` | Height of small card-type tab. |
| `theme.cardHeightLG` | number | `48` | Height of large card-type tab. |
| `theme.cardPadding` | string | `"8px 16px"` | Padding of card-type tab. |
| `theme.cardPaddingLG` | string | `"11px 16px"` | Padding of large card-type tab. |
| `theme.cardPaddingSM` | string | `"4px 8px"` | Padding of small card-type tab. |
| `theme.horizontalItemGutter` | number | `32` | Gap between horizontal tabs. |
| `theme.horizontalItemMargin` | string | - | Horizontal margin of tab item. |
| `theme.horizontalItemPadding` | string | `"12px 0"` | Padding of horizontal tab item. |
| `theme.horizontalItemPaddingLG` | string | `"16px 0"` | Padding of large horizontal tab item. |
| `theme.horizontalItemPaddingSM` | string | `"8px 0"` | Padding of small horizontal tab item. |
| `theme.horizontalMargin` | string | `"0 0 16px 0"` | Margin of horizontal tab bar. |
| `theme.inkBarColor` | string | `"#1677ff"` | Color of the active tab indicator bar. |
| `theme.itemActiveColor` | string | `"#0958d9"` | Text color of active (mousedown) tab. |
| `theme.itemColor` | string | `"rgba(0, 0, 0, 0.88)"` | Text color of tab. |
| `theme.itemHoverColor` | string | `"#4096ff"` | Text color of hovered tab. |
| `theme.itemSelectedColor` | string | `"#1677ff"` | Text color of selected tab. |
| `theme.titleFontSize` | number | `14` | Font size of tab title. |
| `theme.titleFontSizeLG` | number | `16` | Font size of large tab title. |
| `theme.titleFontSizeSM` | number | `14` | Font size of small tab title. |
| `theme.verticalItemMargin` | string | `"16px 0 0 0"` | Margin of vertical tab item. |
| `theme.verticalItemPadding` | string | `"8px 24px"` | Padding of vertical tab item. |
| `theme.zIndexPopup` | number | `1050` | Z-index of tab dropdown popup. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onChange` | `{ activeKey }` | Trigger action on any tab change. |
| `onTabSelect` | `{ key }` | Documentation reference — not a fixed event name. When a tab becomes active, the `eventName` string declared on that `tabs[]` entry is triggered (in addition to onChange). Declare your named events under `events:` (e.g. `onProfileTab`, `onBillingTab`). |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Tabs element. |
| `/icon` | The icon in the Tabs. |
| `/tabBar` | The Tabs tab bar. |
| `/tabPane` | The Tabs tab pane. |
| `/inkBar` | The Tabs ink bar. |
| `/item` | Each tab in the tab bar. |
| `/popup` | The dropdown that lists tabs that overflow the tab bar. |
Slot keys are user-defined in your config and resolved at build time — not generated at runtime. The block typically pairs slots with an array property (`tabs`, `panels`, `slides`) listed in the Properties table; see the examples above for the expected shape.
---
url: https://docs.lowdefy.com/md/container-blocks/tooltip.md
---
# Tooltip
Tooltip popup appearing on hover or focus.
```yaml
- id: tooltip_basic
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: This is a tooltip
blocks:
- id: tooltip_basic_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Hover me
color: primary
variant: solid
- id: tooltip_html
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Bold and italic text
blocks:
- id: tooltip_html_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: HTML content
color: primary
variant: outlined
- id: tooltip_long
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: This is a longer tooltip message that demonstrates how the tooltip wraps
text when the content exceeds the default maximum width.
blocks:
- id: tooltip_long_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Long text
color: default
variant: outlined
```
**Top placements:**
**Bottom placements:**
**Left placements:**
**Right placements:**
```yaml
- id: tooltip_placement_label_top
type: Markdown
properties:
content: "**Top placements:**"
- id: tooltip_placement_top_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: tooltip_topLeft
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: topLeft
placement: topLeft
blocks:
- id: tooltip_topLeft_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: topLeft
color: default
variant: outlined
size: small
- id: tooltip_top
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: top
placement: top
blocks:
- id: tooltip_top_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: top
color: primary
variant: solid
size: small
- id: tooltip_topRight
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: topRight
placement: topRight
blocks:
- id: tooltip_topRight_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: topRight
color: default
variant: outlined
size: small
- id: tooltip_placement_label_bottom
type: Markdown
properties:
content: "**Bottom placements:**"
- id: tooltip_placement_bottom_row
type: Box
layout:
gap: 8
justify: center
blocks:
- id: tooltip_bottomLeft
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: bottomLeft
placement: bottomLeft
blocks:
- id: tooltip_bottomLeft_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: bottomLeft
color: default
variant: outlined
size: small
- id: tooltip_bottom
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: bottom
placement: bottom
blocks:
- id: tooltip_bottom_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: bottom
color: primary
variant: solid
size: small
- id: tooltip_bottomRight
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: bottomRight
placement: bottomRight
blocks:
- id: tooltip_bottomRight_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: bottomRight
color: default
variant: outlined
size: small
- id: tooltip_placement_label_left
type: Markdown
properties:
content: "**Left placements:**"
- id: tooltip_placement_left_row
type: Box
layout:
gap: 8
blocks:
- id: tooltip_left
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: left
placement: left
blocks:
- id: tooltip_left_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: left
color: primary
variant: solid
size: small
- id: tooltip_leftTop
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: leftTop
placement: leftTop
blocks:
- id: tooltip_leftTop_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: leftTop
color: default
variant: outlined
size: small
- id: tooltip_leftBottom
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: leftBottom
placement: leftBottom
blocks:
- id: tooltip_leftBottom_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: leftBottom
color: default
variant: outlined
size: small
- id: tooltip_placement_label_right
type: Markdown
properties:
content: "**Right placements:**"
- id: tooltip_placement_right_row
type: Box
layout:
gap: 8
blocks:
- id: tooltip_right
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: right
placement: right
blocks:
- id: tooltip_right_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: right
color: primary
variant: solid
size: small
- id: tooltip_rightTop
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: rightTop
placement: rightTop
blocks:
- id: tooltip_rightTop_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: rightTop
color: default
variant: outlined
size: small
- id: tooltip_rightBottom
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: rightBottom
placement: rightBottom
blocks:
- id: tooltip_rightBottom_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: rightBottom
color: default
variant: outlined
size: small
```
```yaml
- id: tooltip_trigger_hover
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Triggered by hover
trigger: hover
blocks:
- id: tooltip_trigger_hover_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Hover (default)
color: primary
variant: solid
- id: tooltip_trigger_click
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Triggered by click
trigger: click
blocks:
- id: tooltip_trigger_click_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Click
color: primary
variant: outlined
- id: tooltip_trigger_focus
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Triggered by focus
trigger: focus
blocks:
- id: tooltip_trigger_focus_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Focus (tab to me)
color: primary
variant: dashed
```
```yaml
- id: tooltip_color_row
type: Box
layout:
gap: 8
blocks:
- id: tooltip_color_blue
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: blue
color: blue
blocks:
- id: tooltip_color_blue_tag
type: Tag
properties:
title: blue
color: blue
- id: tooltip_color_purple
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: purple
color: purple
blocks:
- id: tooltip_color_purple_tag
type: Tag
properties:
title: purple
color: purple
- id: tooltip_color_cyan
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: cyan
color: cyan
blocks:
- id: tooltip_color_cyan_tag
type: Tag
properties:
title: cyan
color: cyan
- id: tooltip_color_green
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: green
color: green
blocks:
- id: tooltip_color_green_tag
type: Tag
properties:
title: green
color: green
- id: tooltip_color_red
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: red
color: red
blocks:
- id: tooltip_color_red_tag
type: Tag
properties:
title: red
color: red
- id: tooltip_color_custom_row
type: Box
layout:
gap: 8
blocks:
- id: tooltip_color_hex1
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: "Custom color: #ff6b6b"
color: "#ff6b6b"
blocks:
- id: tooltip_color_hex1_tag
type: Tag
properties:
title: "#ff6b6b"
- id: tooltip_color_hex2
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: "Custom color: #20c997"
color: "#20c997"
blocks:
- id: tooltip_color_hex2_tag
type: Tag
properties:
title: "#20c997"
- id: tooltip_color_hex3
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: "Custom color: #4c6ef5"
color: "#4c6ef5"
blocks:
- id: tooltip_color_hex3_tag
type: Tag
properties:
title: "#4c6ef5"
```
```yaml
- id: tooltip_arrow_default
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Arrow at edge (default)
placement: topLeft
arrowPointAtCenter: false
blocks:
- id: tooltip_arrow_default_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Default arrow
color: default
variant: outlined
- id: tooltip_arrow_center
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Arrow at center
placement: topLeft
arrowPointAtCenter: true
blocks:
- id: tooltip_arrow_center_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Arrow at center
color: primary
variant: solid
```
```yaml
- id: tooltip_overflow_on
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: This tooltip auto-adjusts when near the viewport edge
autoAdjustOverflow: true
placement: top
blocks:
- id: tooltip_overflow_on_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Auto adjust (default)
color: primary
variant: solid
- id: tooltip_overflow_off
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: This tooltip stays in position even near viewport edges
autoAdjustOverflow: false
placement: top
blocks:
- id: tooltip_overflow_off_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No auto adjust
color: default
variant: outlined
```
```yaml
- id: tooltip_delay_fast
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Instant tooltip
mouseEnterDelay: 0
mouseLeaveDelay: 0
blocks:
- id: tooltip_delay_fast_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: No delay
color: primary
variant: solid
- id: tooltip_delay_slow_enter
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: This tooltip has a 1 second enter delay
mouseEnterDelay: 1
blocks:
- id: tooltip_delay_slow_enter_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: 1s enter delay
color: primary
variant: outlined
- id: tooltip_delay_slow_leave
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: This tooltip stays 2 seconds after mouse leaves
mouseLeaveDelay: 2
blocks:
- id: tooltip_delay_slow_leave_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: 2s leave delay
color: primary
variant: dashed
```
```yaml
- id: tooltip_default_open
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: I am open by default
defaultOpen: true
placement: right
blocks:
- id: tooltip_default_open_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Visible by default
color: green
variant: solid
- id: tooltip_destroy_on_hide
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: This tooltip DOM is destroyed when hidden
destroyTooltipOnHide: true
blocks:
- id: tooltip_destroy_on_hide_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Destroy on hide
color: default
variant: outlined
```
```yaml
- id: tooltip_zindex_high
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: High z-index tooltip (2000)
zIndex: 2000
blocks:
- id: tooltip_zindex_high_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: zIndex 2000
color: primary
variant: solid
```
Hover over this text to see the tooltip.
```yaml
- id: tooltip_on_text
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Tooltip on a paragraph
blocks:
- id: tooltip_on_text_p
type: Paragraph
properties:
content: Hover over this text to see the tooltip.
- id: tooltip_on_tag
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Tooltip on a tag
blocks:
- id: tooltip_on_tag_el
type: Tag
properties:
title: Hover tag
color: blue
- id: tooltip_on_icon_btn
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Delete this item
placement: bottom
blocks:
- id: tooltip_on_icon_btn_el
type: Button
layout:
flex: 0 0 auto
properties:
icon: delete
hideTitle: true
color: danger
variant: text
```
```yaml
- id: tooltip_event_open_change
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: This tooltip fires an event on open/close
events:
onOpenChange:
- id: tooltip_event_display_message
type: DisplayMessage
params:
content: Tooltip visibility changed!
duration: 2
blocks:
- id: tooltip_event_open_change_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Hover to trigger event
color: primary
variant: solid
- id: tooltip_event_set_state
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Tracks tooltip state
trigger: click
events:
onOpenChange:
- id: tooltip_event_set_state_action
type: SetState
params:
tooltip_was_toggled: true
blocks:
- id: tooltip_event_set_state_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Click to toggle and set state
color: primary
variant: outlined
```
```yaml
- id: tooltip_overlay_style
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Tooltip with custom overlay style
style:
.inner:
boxShadow: 0 4px 12px rgba(0, 0, 0, 0.3)
blocks:
- id: tooltip_overlay_style_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom overlay shadow
color: primary
variant: solid
```
```yaml
- id: tooltip_theme_large_radius
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Large radius tooltip
theme:
borderRadius: 16
blocks:
- id: tooltip_theme_large_radius_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Large radius
color: primary
variant: solid
- id: tooltip_theme_bg
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Custom background and text color
theme:
colorBgSpotlight: "#2d3436"
colorTextLightSolid: "#74b9ff"
blocks:
- id: tooltip_theme_bg_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom colors
color: primary
variant: outlined
- id: tooltip_theme_font
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Larger font size and line height
theme:
fontSize: 18
lineHeight: 2
blocks:
- id: tooltip_theme_font_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Large font
color: primary
variant: dashed
- id: tooltip_theme_wide
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: This tooltip has a wider max width so longer text can display on a single
line without wrapping.
theme:
maxWidth: 500
blocks:
- id: tooltip_theme_wide_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Wide tooltip (500px)
color: default
variant: outlined
- id: tooltip_theme_compact
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Compact tooltip
theme:
paddingXS: 4
controlHeight: 24
fontSize: 12
blocks:
- id: tooltip_theme_compact_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Compact theme
color: default
variant: dashed
- id: tooltip_theme_zindex
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Custom z-index via theme
theme:
zIndexPopup: 2000
blocks:
- id: tooltip_theme_zindex_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Theme z-index
color: default
variant: outlined
```
Hover me (help cursor via element style)
Hover me (Tailwind element class)
```yaml
- id: tooltip_style_element
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Styled with element CSS key
style:
.element:
cursor: help
blocks:
- id: tooltip_style_element_p
type: Paragraph
properties:
content: Hover me (help cursor via element style)
- id: tooltip_style_inner
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Custom inner styling
style:
.inner:
backgroundColor: "#1a1a2e"
color: "#e94560"
borderRadius: 12
padding: 12px 20px
fontSize: 16
blocks:
- id: tooltip_style_inner_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Custom inner style
color: primary
variant: solid
- id: tooltip_class_element
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Tailwind on element wrapper
class:
.element: cursor-help
blocks:
- id: tooltip_class_element_text
type: Paragraph
properties:
content: Hover me (Tailwind element class)
- id: tooltip_class_inner
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Tailwind on inner popup
class:
.inner: text-lg font-bold
blocks:
- id: tooltip_class_inner_btn
type: Button
layout:
flex: 0 0 auto
properties:
title: Tailwind inner class
color: primary
variant: outlined
```
Product
Revenue
Units Sold
Widget Pro
$12,450
342
Gadget X
$8,230
189
```yaml
- id: tooltip_table_header_card
type: Card
properties:
title: Monthly Sales Report
size: small
blocks:
- id: tooltip_table_header_row
type: Box
layout:
gap: 0
direction: column
blocks:
- id: tooltip_table_header_labels
type: Box
class: bg-bg-layout px-4 py-2 border-b border-border
layout:
gap: 0
blocks:
- id: tooltip_table_hdr_product
type: Tooltip
layout:
flex: 2 1 0
properties:
title: The product name as listed in the inventory system
placement: top
blocks:
- id: tooltip_table_hdr_product_text
type: Paragraph
class: font-semibold text-text-secondary text-sm m-0
properties:
content: Product
- id: tooltip_table_hdr_revenue
type: Tooltip
layout:
flex: 1 1 0
properties:
title: Total revenue after discounts and returns
placement: top
blocks:
- id: tooltip_table_hdr_revenue_text
type: Paragraph
class: font-semibold text-text-secondary text-sm m-0
properties:
content: Revenue
- id: tooltip_table_hdr_units
type: Tooltip
layout:
flex: 1 1 0
properties:
title: Number of individual units sold this month
placement: top
blocks:
- id: tooltip_table_hdr_units_text
type: Paragraph
class: font-semibold text-text-secondary text-sm m-0
properties:
content: Units Sold
- id: tooltip_table_row_1
type: Box
class: px-4 py-2 border-b border-border
layout:
gap: 0
blocks:
- id: tooltip_table_row_1_product
type: Paragraph
layout:
flex: 2 1 0
class: text-sm m-0
properties:
content: Widget Pro
- id: tooltip_table_row_1_revenue
type: Paragraph
layout:
flex: 1 1 0
class: text-sm m-0
properties:
content: $12,450
- id: tooltip_table_row_1_units
type: Paragraph
layout:
flex: 1 1 0
class: text-sm m-0
properties:
content: "342"
- id: tooltip_table_row_2
type: Box
class: px-4 py-2
layout:
gap: 0
blocks:
- id: tooltip_table_row_2_product
type: Paragraph
layout:
flex: 2 1 0
class: text-sm m-0
properties:
content: Gadget X
- id: tooltip_table_row_2_revenue
type: Paragraph
layout:
flex: 1 1 0
class: text-sm m-0
properties:
content: $8,230
- id: tooltip_table_row_2_units
type: Paragraph
layout:
flex: 1 1 0
class: text-sm m-0
properties:
content: "189"
```
```yaml
- id: tooltip_form_card
type: Card
properties:
title: User Profile Settings
blocks:
- id: tooltip_form_username
type: TextInput
properties:
label:
title: Username
tooltip:
title: Your unique username. Must be 3-20 characters, letters and numbers only.
color: "#8c8c8c"
placeholder: Enter your username
- id: tooltip_form_email
type: TextInput
properties:
label:
title: Email Address
tooltip:
title: We will send account notifications to this address. You can change it at
any time.
color: "#8c8c8c"
placeholder: Enter your email
```
Active Users
Monthly Revenue
```yaml
- id: tooltip_dashboard_row
type: Box
layout:
gap: 16
blocks:
- id: tooltip_dashboard_users_card
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: tooltip_dashboard_users_header
type: Box
layout:
gap: 8
align: center
blocks:
- id: tooltip_dashboard_users_title
type: Paragraph
layout:
flex: 1 1 0
class: text-text-secondary text-sm m-0
properties:
content: Active Users
- id: tooltip_dashboard_users_info
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Users who have logged in at least once in the last 30 days
placement: top
blocks:
- id: tooltip_dashboard_users_info_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: info
size: 14
color: "#8c8c8c"
- id: tooltip_dashboard_users_stat
type: Statistic
properties:
value: 2847
- id: tooltip_dashboard_users_tag
type: Tag
properties:
title: +12.3%
color: success
- id: tooltip_dashboard_revenue_card
type: Card
layout:
flex: 1 1 0
properties:
size: small
blocks:
- id: tooltip_dashboard_revenue_header
type: Box
layout:
gap: 8
align: center
blocks:
- id: tooltip_dashboard_revenue_title
type: Paragraph
layout:
flex: 1 1 0
class: text-text-secondary text-sm m-0
properties:
content: Monthly Revenue
- id: tooltip_dashboard_revenue_info
type: Tooltip
layout:
flex: 0 0 auto
properties:
title: Gross revenue before taxes and refunds for the current billing period
placement: top
blocks:
- id: tooltip_dashboard_revenue_info_icon
type: Icon
layout:
flex: 0 0 auto
properties:
name: info
size: 14
color: "#8c8c8c"
- id: tooltip_dashboard_revenue_stat
type: Statistic
properties:
value: 64250
prefix: $
- id: tooltip_dashboard_revenue_tag
type: Tag
properties:
title: +8.7%
color: success
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `arrow` | boolean \| object | `true` | Whether to show the arrow. Set `{ pointAtCenter: true }` to point the arrow at the center of the target. |
| `arrow.pointAtCenter` | boolean | `false` | Whether the arrow is pointed at the center of target. |
| `arrowPointAtCenter` | boolean | `false` | Whether the arrow is pointed at the center of target. Same as `arrow: { pointAtCenter: true }`. |
| `autoAdjustOverflow` | boolean | `true` | Whether to adjust popup placement automatically when popup is off screen. |
| `color` | string | - | The background color. |
| `defaultOpen` | boolean | `false` | Whether the floating tooltip card is visible by default. |
| `destroyOnHidden` | boolean | `false` | Whether to destroy the tooltip DOM when hidden. |
| `destroyTooltipOnHide` | boolean | `false` | Same as destroyOnHidden, which takes precedence. |
| `mouseEnterDelay` | number | `0.1` | Delay in seconds, before tooltip is shown on mouse enter. |
| `mouseLeaveDelay` | number | `0.1` | Delay in seconds, before tooltip is hidden on mouse leave. |
| `placement` | string | `"top"` | The position of the tooltip relative to the target. Enum: `top`, `left`, `right`, `bottom`, `topLeft`, `topRight`, `bottomLeft`, `bottomRight`, `leftTop`, `leftBottom`, `rightTop`, `rightBottom`. |
| `trigger` | string | `"hover"` | Tooltip trigger mode. `contextMenu` opens the tooltip on right click. Enum: `hover`, `focus`, `click`, `contextMenu`. |
| `title` | string | - | Title to show in the title area - supports html. Overwritten by blocks in the title content area. |
| `zIndex` | integer | - | The z-index of the Tooltip. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design tooltip tokens](https://ant.design/components/tooltip#design-token). |
| `theme.zIndexPopup` | number | `1070` | Z-index of the tooltip. |
| `theme.maxWidth` | number | `250` | Maximum width of the tooltip. |
| `theme.colorBgSpotlight` | string | `"rgba(0, 0, 0, 0.85)"` | Background color of the tooltip. |
| `theme.colorTextLightSolid` | string | `"#fff"` | Text color inside the tooltip. |
| `theme.borderRadius` | number | `6` | Border radius of the tooltip. |
| `theme.controlHeight` | number | `32` | Minimum height of the tooltip. |
| `theme.fontSize` | number | `14` | Font size of tooltip text. |
| `theme.lineHeight` | number | `1.5714` | Line height of tooltip text. |
| `theme.paddingXS` | number | `8` | Horizontal padding inside the tooltip. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onOpenChange` | `{ open }` | Trigger action when visibility of the tooltip card is changed. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Tooltip element. |
| `/inner` | The Tooltip inner. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks that trigger the tooltip. |
---
url: https://docs.lowdefy.com/md/container-blocks/watermark.md
---
# Watermark
Watermark overlay with text, image, and font customization.
```yaml
- id: basic_single
type: Watermark
properties:
text: Lowdefy
blocks:
- id: basic_single_child
type: Box
style:
height: 200px
- id: basic_multiline
type: Watermark
properties:
text:
- Lowdefy
- Confidential
blocks:
- id: basic_multiline_child
type: Box
style:
height: 220px
```
```yaml
- id: img_logo
type: Watermark
properties:
image: https://lowdefy.com/favicon-32x32.png
width: 80
height: 80
blocks:
- id: img_logo_child
type: Box
style:
height: 240px
- id: img_small
type: Watermark
properties:
image: https://lowdefy.com/favicon-32x32.png
width: 40
height: 40
blocks:
- id: img_small_child
type: Box
style:
height: 200px
```
```yaml
- id: font_red
type: Watermark
properties:
text: Rejected
font:
color: rgba(255, 0, 0, 0.15)
blocks:
- id: font_red_child
type: Box
style:
height: 180px
- id: font_large_bold
type: Watermark
properties:
text: DRAFT
font:
fontSize: 28
fontWeight: bold
color: rgba(255, 0, 0, 0.08)
blocks:
- id: font_large_bold_child
type: Box
style:
height: 220px
- id: font_serif_italic
type: Watermark
properties:
text: Elegant
font:
fontFamily: Georgia, serif
fontStyle: italic
fontSize: 20
color: rgba(139, 92, 246, 0.1)
blocks:
- id: font_serif_italic_child
type: Box
style:
height: 200px
```
```yaml
- id: per_line_font
type: Watermark
properties:
text:
- text: CONFIDENTIAL
font:
fontSize: 22
fontWeight: bold
color: rgba(255, 0, 0, 0.12)
- Prepared for the finance team
blocks:
- id: per_line_font_child
type: Box
style:
height: 200px
```
```yaml
- id: align_left
type: Watermark
properties:
text:
- Left Aligned
- Second Line
font:
textAlign: left
color: rgba(0, 0, 0, 0.1)
blocks:
- id: align_left_child
type: Box
style:
height: 200px
- id: align_center
type: Watermark
properties:
text:
- Center Aligned
- Second Line
font:
textAlign: center
color: rgba(0, 0, 0, 0.1)
blocks:
- id: align_center_child
type: Box
style:
height: 200px
- id: align_right
type: Watermark
properties:
text:
- Right Aligned
- Second Line
font:
textAlign: right
color: rgba(0, 0, 0, 0.1)
blocks:
- id: align_right_child
type: Box
style:
height: 200px
```
```yaml
- id: rotate_default
type: Watermark
properties:
text: Default (-22 degrees)
blocks:
- id: rotate_default_child
type: Box
style:
height: 180px
- id: rotate_horizontal
type: Watermark
properties:
text: Horizontal (0 degrees)
rotate: 0
blocks:
- id: rotate_horizontal_child
type: Box
style:
height: 180px
- id: rotate_steep
type: Watermark
properties:
text: Steep (-45 degrees)
rotate: -45
blocks:
- id: rotate_steep_child
type: Box
style:
height: 200px
```
```yaml
- id: gap_tight
type: Watermark
properties:
text: Tight Gap
gap:
- 50
- 50
blocks:
- id: gap_tight_child
type: Box
style:
height: 200px
- id: gap_wide
type: Watermark
properties:
text: Wide Gap
gap:
- 200
- 200
blocks:
- id: gap_wide_child
type: Box
style:
height: 200px
- id: offset_shifted
type: Watermark
properties:
text: Offset (50, 40)
offset:
- 50
- 40
blocks:
- id: offset_shifted_child
type: Box
style:
height: 200px
```
```yaml
- id: zindex_high
type: Watermark
properties:
text: High zIndex (100)
zIndex: 100
blocks:
- id: zindex_high_child
type: Box
style:
height: 180px
- id: inherit_false
type: Watermark
properties:
text: Inherit disabled
inherit: false
blocks:
- id: inherit_false_child
type: Box
style:
height: 180px
```
```yaml
- id: theme_color_fill
type: Watermark
properties:
text: Custom Fill Color
theme:
colorFill: rgba(22, 119, 255, 0.12)
blocks:
- id: theme_color_fill_child
type: Box
style:
height: 200px
- id: theme_font_size
type: Watermark
properties:
text: Large Default Font
theme:
fontSizeLG: 24
blocks:
- id: theme_font_size_child
type: Box
style:
height: 200px
- id: theme_font_family
type: Watermark
properties:
text: Serif Theme Font
theme:
fontFamily: Georgia, serif
blocks:
- id: theme_font_family_child
type: Box
style:
height: 200px
```
The element CSS key applies Tailwind classes to the Watermark wrapper. Here a gradient background and rounded corners create a styled preview area.
Dark Background
White watermark text with low opacity stays subtle on a dark surface. Useful for dark-mode interfaces and embedded viewers.
Drag and drop files here or click to browse
```yaml
- id: css_gradient_bg
type: Watermark
class:
.element: bg-gradient-to-br from-primary/10 to-primary/5 rounded-lg p-4
properties:
text: Preview
font:
color: rgba(79, 70, 229, 0.1)
fontSize: 18
blocks:
- id: css_gradient_bg_content
type: Paragraph
properties:
content: >
The element CSS key applies Tailwind classes to the Watermark wrapper.
Here a gradient background and rounded corners create a styled preview
area.
- id: css_dark_surface
type: Watermark
class:
.element: bg-bg-layout rounded-lg p-4
properties:
text: Dark Theme
font:
color: rgba(255, 255, 255, 0.08)
fontSize: 16
blocks:
- id: css_dark_surface_title
type: Title
style:
color: white
properties:
content: Dark Background
level: 5
- id: css_dark_surface_content
type: Paragraph
style:
color: rgba(255, 255, 255, 0.7)
properties:
content: >
White watermark text with low opacity stays subtle on a dark surface.
Useful for dark-mode interfaces and embedded viewers.
- id: css_bordered_area
type: Watermark
class:
.element: border-2 border-dashed border-border rounded-xl p-6
properties:
text: Upload Area
font:
color: rgba(0, 0, 0, 0.06)
fontSize: 20
rotate: 0
gap:
- 120
- 80
blocks:
- id: css_bordered_area_text
type: Paragraph
style:
textAlign: center
color: "#999"
properties:
content: Drag and drop files here or click to browse
```
Quarterly Financial Report
Prepared for the Board of Directors — Q1 2026
Revenue for the first quarter reached $12.4M, representing a 15% increase year-over-year. Operating margins improved to 23% driven by efficiency gains across all business units.
Customer acquisition costs decreased by 8% while customer lifetime value increased by 12%, indicating strong unit economics. The sales pipeline remains robust with $45M in qualified opportunities.
```yaml
- id: report_wrapper
type: Box
class: bg-bg-container rounded-lg shadow-sm
blocks:
- id: report_watermark
type: Watermark
properties:
text: DRAFT
font:
fontSize: 28
fontWeight: bold
color: rgba(255, 0, 0, 0.06)
gap:
- 150
- 150
rotate: -30
blocks:
- id: report_heading
type: Title
properties:
content: Quarterly Financial Report
level: 4
- id: report_subtitle
type: Paragraph
properties:
content: Prepared for the Board of Directors — Q1 2026
- id: report_divider
type: Divider
- id: report_body_1
type: Paragraph
properties:
content: >
Revenue for the first quarter reached $12.4M, representing a 15%
increase year-over-year. Operating margins improved to 23% driven
by efficiency gains across all business units.
- id: report_body_2
type: Paragraph
properties:
content: >
Customer acquisition costs decreased by 8% while customer lifetime
value increased by 12%, indicating strong unit economics. The
sales pipeline remains robust with $45M in qualified
opportunities.
```
Project Overview
A web application for managing team workflows and project timelines. Currently in active development with scheduled release next quarter.
Mobile app for real-time inventory tracking across multiple warehouses. Integrates with existing ERP systems for seamless data sync.
```yaml
- id: dashboard_watermark
type: Watermark
properties:
text:
- CONFIDENTIAL
- Do Not Copy
font:
fontSize: 18
color: rgba(22, 119, 255, 0.06)
fontWeight: bold
gap:
- 120
- 120
blocks:
- id: dashboard_title
type: Title
properties:
content: Project Overview
level: 4
- id: dashboard_cards
type: Box
layout:
gap: 16
blocks:
- id: dashboard_card_alpha
type: Card
layout:
flex: 1 1 0
properties:
title: Project Alpha
slots:
extra:
blocks:
- id: dashboard_alpha_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Active
color: success
blocks:
- id: dashboard_alpha_desc
type: Paragraph
properties:
content: A web application for managing team workflows and project timelines.
Currently in active development with scheduled release next
quarter.
- id: dashboard_alpha_progress
type: Progress
properties:
percent: 68
- id: dashboard_card_beta
type: Card
layout:
flex: 1 1 0
properties:
title: Project Beta
slots:
extra:
blocks:
- id: dashboard_beta_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title: Planning
color: warning
blocks:
- id: dashboard_beta_desc
type: Paragraph
properties:
content: Mobile app for real-time inventory tracking across multiple warehouses.
Integrates with existing ERP systems for seamless data sync.
- id: dashboard_beta_progress
type: Progress
properties:
percent: 25
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `font` | object | - | Font style configuration with color, fontSize, fontWeight, fontFamily, fontStyle, textAlign. |
| `font.color` | string | - | Font color of the watermark. |
| `font.fontFamily` | string | - | Font family of the watermark. |
| `font.fontSize` | number | - | Font size of the watermark. |
| `font.fontStyle` | string | - | Font style of the watermark. |
| `font.fontWeight` | string \| number | - | Font weight of the watermark. |
| `font.textAlign` | string | - | Text alignment of the watermark. Enum: `start`, `end`, `left`, `right`, `center`. |
| `gap` | array | - | Gap between watermarks as [horizontal, vertical]. |
| `height` | number | - | Height of the watermark. |
| `image` | string | - | Image URL to use as watermark. If set, text content is ignored. |
| `inherit` | boolean | `true` | Inherit watermark config from parent Watermark block. |
| `offset` | array | - | Offset of the watermark from the top-left as [x, y]. |
| `rotate` | number | `-22` | Rotation angle of watermark in degrees. |
| `text` | string \| array | - | Watermark text content. An array renders one line per item. A line can be a string, or `{ text, font }` to give that line its own font style. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design watermark tokens](https://ant.design/components/watermark#design-token). |
| `theme.colorFill` | string | - | Default watermark text color when font.color is not set. Maps to the global colorFill token. |
| `theme.fontSizeLG` | number | `16` | Default watermark font size when font.fontSize is not set. Maps to the global fontSizeLG token. |
| `theme.fontFamily` | string | `"sans-serif"` | Default font family used when font.fontFamily is not set. |
| `width` | number | - | Width of the watermark. |
| `zIndex` | integer | - | Z-index of the watermark. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The Watermark element. |
| Slot | Description |
| --- | --- |
| `content` | Child blocks with a watermark overlay. |
---
url: https://docs.lowdefy.com/md/list-blocks/controlledlist.md
---
# ControlledList
Dynamic list with built-in add and remove controls. Supports custom add/remove buttons, conditional field visibility, nested lists, theme tokens, and scoped validation. Use `addItemButton` and `removeItemIcon` to customize controls, and `visible` with operators for conditional fields.
```yaml
- id: team
type: ControlledList
properties:
title: Team Members
blocks:
- id: team.$.name
type: TextInput
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Full name
- id: team.$.role
type: Selector
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Role
options:
- Developer
- Designer
- PM
- QA
- id: team.$.email
type: TextInput
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Email
```
```yaml
- id: bookmarks
type: ControlledList
properties:
title: Bookmarks
addToFront: true
size: small
addItemButton:
title: Bookmark
icon: add
color: primary
variant: dashed
removeItemIcon:
name: delete
blocks:
- id: bookmarks.$.url
type: TextInput
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: https://...
prefixIcon: link
- id: bookmarks.$.label
type: TextInput
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Label
```
```yaml
- id: attendees
type: ControlledList
properties:
title: Attendees
addItemButton:
title: Add Attendee
icon: UserPlus
color: primary
variant: outlined
blocks:
- id: attendees.$.name
type: TextInput
required: true
layout:
flex: 2 1 0
properties:
label:
disabled: true
placeholder: Full name
- id: attendees.$.type
type: Selector
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Type
options:
- Adult
- Child
- Senior
- id: attendees.$.email
type: TextInput
required: true
visible:
_eq:
- _state: attendees.$.type
- Adult
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Email
validate:
- message: Enter a valid email.
status: error
pass:
_regex:
pattern: ^[^@]+@[^@]+\.[^@]+$
on:
_if_none:
- _state: attendees.$.email
- ""
- id: attendees.$.meal
type: Selector
visible:
_eq:
- _state: attendees.$.type
- Adult
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Meal
options:
- Standard
- Vegetarian
- Vegan
- id: attendees.$.age
type: NumberInput
visible:
_eq:
- _state: attendees.$.type
- Child
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Age
min: 1
max: 17
- id: attendees.$.supervision
type: Switch
visible:
_eq:
- _state: attendees.$.type
- Child
layout:
flex: 0 0 auto
properties:
title: Needs supervision
size: small
- id: attendees.$.wheelchair
type: Switch
visible:
_eq:
- _state: attendees.$.type
- Senior
layout:
flex: 0 0 auto
properties:
title: Wheelchair access
size: small
- id: attendees.$.dietary
type: TextInput
visible:
_eq:
- _state: attendees.$.type
- Senior
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Dietary notes
- id: attendees_footer
type: Box
layout:
justify: flex-end
blocks:
- id: attendees_register
type: Button
layout:
flex: 0 0 auto
properties:
title: Register All
icon: send
color: primary
variant: solid
events:
onClick:
- id: attendees_validate
type: Validate
params:
regex: ^attendees
- id: attendees_msg
type: DisplayMessage
params:
content: All attendees registered!
status: success
```
```yaml
- id: expenses
type: ControlledList
properties:
title: Expenses
addItemButton:
title: Add Expense
icon: add
color: primary
variant: dashed
theme:
itemPadding: 16px 12px
blocks:
- id: expenses.$.date
type: DateSelector
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Date
- id: expenses.$.category
type: Selector
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Category
options:
- Travel
- Meals
- Software
- Equipment
- Other
- id: expenses.$.desc
type: TextInput
required: true
layout:
flex: 2 1 0
properties:
label:
disabled: true
placeholder: Description
- id: expenses.$.amount
type: NumberInput
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Amount
min: 0
step: 0.01
prefix: $
- id: expenses_footer
type: Box
layout:
gap: 16
justify: flex-end
align: center
blocks:
- id: expenses_total
type: Statistic
layout:
flex: 0 0 auto
properties:
title: Total Expenses
prefix: $
precision: 2
value:
_js: |
const expenses = state('expenses') || [];
return expenses.reduce((sum, item) => sum + (item.amount || 0), 0);
- id: expenses_submit
type: Button
layout:
flex: 0 0 auto
properties:
title: Submit Report
icon: send
color: primary
variant: solid
events:
onClick:
- id: expenses_validate
type: Validate
params:
regex: ^expenses
- id: expenses_msg
type: DisplayMessage
params:
content: Expense report submitted!
status: success
```
```yaml
- id: projects
type: ControlledList
properties:
title: Projects
addItemButton:
title: Add Project
icon: add
color: primary
variant: outlined
blocks:
- id: projects.$.name
type: TextInput
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Project name
- id: projects.$.status
type: Selector
layout:
flex: 0 0 140px
properties:
label:
disabled: true
placeholder: Status
options:
- Planning
- Active
- Review
- Done
- id: projects.$.tasks
type: ControlledList
properties:
title: Tasks
size: small
addItemButton:
title: Add Task
icon: add
size: small
variant: dashed
blocks:
- id: projects.$.tasks.$.task
type: TextInput
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Task description
size: small
- id: projects.$.tasks.$.done
type: Switch
layout:
flex: 0 0 auto
properties:
title: Done
size: small
- id: projects_footer
type: Box
layout:
justify: flex-end
blocks:
- id: projects_save
type: Button
layout:
flex: 0 0 auto
properties:
title: Save All
icon: save
color: primary
variant: solid
events:
onClick:
- id: projects_validate
type: Validate
params:
regex: ^projects
- id: projects_msg
type: DisplayMessage
params:
content: Projects saved!
status: success
```
```yaml
- id: tags
type: ControlledList
properties:
title: Tags
size: small
addItemButton:
title: Add Tag
icon: add
size: small
variant: dashed
events:
onAdd:
- id: tags_added_msg
type: DisplayMessage
params:
content:
_string.concat:
- "Added row at index "
- _event: index
duration: 1
onRemove:
- id: tags_removed_msg
type: DisplayMessage
params:
content:
_string.concat:
- Removed "
- _if_none:
- _event: item.label
- (empty)
- '" at index '
- _event: index
status: warning
duration: 2
blocks:
- id: tags.$.label
type: TextInput
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Tag name
size: small
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `title` | string | - | Controlled list title. |
| `addToFront` | boolean | `false` | When true, add new items to the front of the list. |
| `hideAddButton` | boolean | `false` | When true, hide the add new item button. |
| `size` | string | `"default"` | Size of the list. Enum: `small`, `default`, `large`. |
| `addItemButton` | object | - | Custom add item button properties. |
| `removeItemIcon` | string \| object | - | Custom remove item icon properties. Defaults to `remove` at a standard size with the antd error color inherited from the icon wrapper — override via `class.removeIcon` / `style.removeIcon` for visual tweaks, or via this property to change the icon name itself. |
| `removeItemIcon.name` | string | - | Icon name: a semantic name like `edit`, a Lucide icon name like `Pencil`, or a set-qualified name like `tabler:Pencil`. |
| `removeItemIcon.color` | string | - | Icon color. |
| `removeItemIcon.size` | string \| number | - | Size of the icon. Defaults to `theme.icons.size`. |
| `removeItemIcon.rotate` | number | - | Number of degrees to rotate the icon. |
| `removeItemIcon.spin` | boolean | - | Continuously spin the icon with animation. |
| `removeItemIcon.strokeWidth` | number | - | Stroke width of the icon lines, in pixels of the 24px icon grid. Defaults to `theme.icons.strokeWidth` (2). |
| `removeItemIcon.nonScalingStroke` | boolean | - | Keep the stroke width constant at any icon size. Defaults to `theme.icons.nonScalingStroke`. |
| `removeItemIcon.title` | string | - | Icon hover title for accessibility. An empty string marks the icon as decorative. |
| `removeItemIcon.disableLoadingIcon` | boolean | - | While loading after the icon has been clicked, don't render the loading icon. |
| `hideRemoveButton` | boolean | `false` | When true, hide the remove item button on each list item. |
| `noDataTitle` | string | - | Title to show when list is empty. |
| `minItems` | number | `0` | Minimum number of items in the controlled list. |
| `theme` | object | - | Antd design token overrides for this block. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design list tokens](https://ant.design/components/list#design-token). |
| `theme.titleMarginBottom` | number | `12` | Margin bottom of list item title. |
| `theme.contentWidth` | number | `220` | Width of the content area. |
| `theme.itemPadding` | string | `"12px 0"` | Padding of list items. |
| `theme.itemPaddingLG` | string | `"16px 24px"` | Padding of list items (large size). |
| `theme.itemPaddingSM` | string | `"8px 16px"` | Padding of list items (small size). |
| `theme.headerBg` | string | `"transparent"` | Background color of the list header. |
| `theme.footerBg` | string | `"transparent"` | Background color of the list footer. |
| `theme.emptyTextPadding` | number | `32` | Padding for the empty text area. |
| `theme.metaMarginBottom` | number | `16` | Margin bottom of list item meta. |
| `theme.avatarMarginRight` | number | `16` | Margin right of the avatar in list items. |
| `theme.descriptionFontSize` | number | `14` | Font size of the description text. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onAdd` | \- | Triggered after a new item is added via the add button. The event payload is `{ index, item }`, where `item` is the newly added value (`undefined` for an empty row). |
| `onRemove` | \- | Triggered after an item is removed via the remove icon. The event payload is `{ index, item }`, where `item` is the removed value captured before removal. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The ControlledList element. |
| `/header` | The ControlledList header. |
| `/footer` | The ControlledList footer. |
| `/item` | The ControlledList item. |
| `/removeIcon` | The remove-item icon wrapper. Defaults to the antd error color at `fontSizeLG`; override `color`, `font-size`, or spacing here. |
| Slot | Description |
| --- | --- |
| `content` | Blocks rendered for each list item. |
---
url: https://docs.lowdefy.com/md/list-blocks/list.md
---
# List
Flex-based list container that renders a template block for each item in an array. Supports column/row direction, wrapping, and scrolling. Use `CallMethod` with `pushItem`, `removeItem`, `moveItemUp`, and `moveItemDown` to manage items. Pair with `Validate` to validate inputs across all list rows.
Notes
```yaml
- id: notes_header
type: Box
layout:
justify: space-between
align: center
blocks:
- id: notes_title
type: Title
layout:
flex: 0 0 auto
properties:
content: Notes
level: 4
- id: notes_add
type: Button
layout:
flex: 0 0 auto
properties:
title: Add Note
icon: add
color: primary
variant: solid
size: small
events:
onClick:
- id: notes_push
type: CallMethod
params:
blockId: notes
method: pushItem
- id: notes
type: List
properties:
direction: row
blocks:
- id: notes.$.text
type: TextInput
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Type a note...
- id: notes.$.rm
type: Button
layout:
flex: 0 0 auto
properties:
icon: close
color: default
variant: text
shape: circle
size: small
events:
onClick:
- id: rm_note
type: CallMethod
params:
blockId: notes
method: removeItem
args:
- _index: 0
```
```yaml
- id: skills
type: List
properties:
direction: row
wrap: wrap
blocks:
- id: skills.$.label
type: Tag
layout:
flex: 0 0 auto
properties:
title:
_state: skills.$.label
color:
_state: skills.$.color
closable: true
events:
onClose:
- id: rm_skill
type: CallMethod
params:
blockId: skills
method: removeItem
args:
- _index: 0
```
Tasks
```yaml
- id: tasks_header
type: Box
layout:
justify: space-between
align: center
blocks:
- id: tasks_title
type: Title
layout:
flex: 0 0 auto
properties:
content: Tasks
level: 4
- id: tasks_add
type: Button
layout:
flex: 0 0 auto
properties:
title: Add Task
icon: add
color: primary
variant: solid
size: small
events:
onClick:
- id: tasks_push
type: CallMethod
params:
blockId: tasks
method: pushItem
- id: tasks
type: List
blocks:
- id: tasks.$.done
type: Switch
layout:
flex: 0 0 auto
properties:
label:
disabled: true
size: small
- id: tasks.$.name
type: TextInput
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Task name
size: small
- id: tasks.$.priority
type: Selector
layout:
flex: 0 0 140px
properties:
label:
disabled: true
placeholder: Priority
size: small
options:
- High
- Medium
- Low
- id: tasks.$.pri_tag
type: Tag
layout:
flex: 0 0 auto
properties:
title:
_if_none:
- _state: tasks.$.priority
- ""
color:
_if:
test:
_eq:
- _state: tasks.$.priority
- High
then: red
else:
_if:
test:
_eq:
- _state: tasks.$.priority
- Medium
then: orange
else: green
- id: tasks.$.up
type: Button
layout:
flex: 0 0 auto
properties:
icon: arrow-up
color: default
variant: text
size: small
shape: circle
events:
onClick:
- id: tasks_up
type: CallMethod
params:
blockId: tasks
method: moveItemUp
args:
- _index: 0
- id: tasks.$.down
type: Button
layout:
flex: 0 0 auto
properties:
icon: arrow-down
color: default
variant: text
size: small
shape: circle
events:
onClick:
- id: tasks_down
type: CallMethod
params:
blockId: tasks
method: moveItemDown
args:
- _index: 0
- id: tasks.$.rm
type: Button
layout:
flex: 0 0 auto
properties:
icon: delete
color: danger
variant: text
size: small
shape: circle
events:
onClick:
- id: tasks_rm
type: CallMethod
params:
blockId: tasks
method: removeItem
args:
- _index: 0
- id: tasks_footer
type: Box
layout:
justify: flex-end
blocks:
- id: tasks_save
type: Button
layout:
flex: 0 0 auto
properties:
title: Save Tasks
icon: save
color: primary
variant: solid
events:
onClick:
- id: tasks_validate
type: Validate
params:
regex: ^tasks
- id: tasks_msg
type: DisplayMessage
params:
content: Tasks saved!
status: success
```
User Directory
```yaml
- id: users_header
type: Box
layout:
justify: space-between
align: center
blocks:
- id: users_title
type: Title
layout:
flex: 0 0 auto
properties:
content: User Directory
level: 4
- id: users_btns
type: Box
layout:
flex: 0 0 auto
gap: 8
blocks:
- id: users_load
type: Button
layout:
flex: 0 0 auto
properties:
title: Load Users
icon: CloudDownload
color: primary
variant: solid
size: small
events:
onClick:
- id: fetch_users
type: Fetch
params:
url: https://jsonplaceholder.typicode.com/users
responseFunction: json
- id: set_users
type: SetState
params:
users:
_actions: fetch_users.response
- id: users_clear
type: Button
layout:
flex: 0 0 auto
properties:
title: Clear
color: default
variant: outlined
size: small
events:
onClick:
- id: clear_users
type: SetState
params:
users: []
- id: users
type: List
blocks:
- id: users.$.avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
content:
_string.charAt:
on:
_if_none:
- _state: users.$.name
- "?"
index: 0
color: "#1677ff"
- id: users.$.disp_name
type: Paragraph
layout:
flex: 1 1 0
properties:
content:
_state: users.$.name
- id: users.$.disp_email
type: Paragraph
layout:
flex: 1 1 0
properties:
content:
_state: users.$.email
type: secondary
- id: users.$.disp_company
type: Tag
layout:
flex: 0 0 auto
properties:
title:
_state: users.$.company.name
color: blue
```
Invoice #1042
```yaml
- id: inv_header
type: Box
layout:
justify: space-between
align: center
blocks:
- id: inv_title
type: Title
layout:
flex: 0 0 auto
properties:
content: "Invoice #1042"
level: 4
- id: inv_add
type: Button
layout:
flex: 0 0 auto
properties:
title: Add Line
icon: add
color: primary
variant: dashed
size: small
events:
onClick:
- id: inv_push
type: CallMethod
params:
blockId: inv
method: pushItem
- id: inv
type: List
blocks:
- id: inv.$.desc
type: TextInput
required: true
layout:
flex: 3 1 0
properties:
label:
disabled: true
placeholder: Description
- id: inv.$.qty
type: NumberInput
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Qty
min: 1
- id: inv.$.price
type: NumberInput
required: true
layout:
flex: 1 1 0
properties:
label:
disabled: true
placeholder: Unit price
min: 0
step: 0.01
- id: inv.$.total
type: Paragraph
layout:
flex: 0 0 100px
properties:
content:
_js: |
const qty = state('inv.$.qty') || 0;
const price = state('inv.$.price') || 0;
return '$' + (qty * price).toFixed(2);
- id: inv.$.rm
type: Button
layout:
flex: 0 0 auto
properties:
icon: remove
color: danger
variant: text
size: small
shape: circle
events:
onClick:
- id: inv_rm
type: CallMethod
params:
blockId: inv
method: removeItem
args:
- _index: 0
- id: inv_footer
type: Box
layout:
gap: 16
justify: flex-end
align: center
blocks:
- id: inv_total
type: Statistic
layout:
flex: 0 0 auto
properties:
title: Total
prefix: $
precision: 2
value:
_js: |
const items = state('inv') || [];
return items.reduce((sum, item) =>
sum + ((item.qty || 0) * (item.price || 0)), 0);
- id: inv_submit
type: Button
layout:
flex: 0 0 auto
properties:
title: Submit Invoice
icon: send
color: primary
variant: solid
events:
onClick:
- id: inv_validate
type: Validate
params:
regex: ^inv
- id: inv_msg
type: DisplayMessage
params:
content: Invoice submitted!
status: success
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `direction` | string | - | List content along a 'row' or down a 'column'. Applies the 'flex-direction' css property to the List block. Enum: `row`, `column`, `row-reverse`, `column-reverse`. |
| `wrap` | string | - | Specifies wrapping style to be applied to List block as 'wrap', 'nowrap' or 'wrap-reverse'. Applies the 'flex-wrap' css property to the List block - defaults to 'wrap', requires List direction to be set. Enum: `wrap`, `nowrap`, `wrap-reverse`. |
| `scroll` | boolean | - | Specifies whether scrolling should be applied to the List, can be true or false. Applies the 'overflow' css property to the List block - defaults to 'visible', requires List direction to be set. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onClick` | \- | Trigger actions when the List is clicked. |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The List element. |
| Slot | Description |
| --- | --- |
| `content` | Blocks rendered for each list item. |
---
url: https://docs.lowdefy.com/md/list-blocks/listselector.md
---
# ListSelector
Data-driven vertical list of headerless cards that doubles as a single-select input. Each card body is rendered from a Nunjucks template against its row item. Clicking a card sets the block value to that data item and highlights it; set `selectable: false` to turn selection off and render a read-only card list. Virtualized via `react-virtuoso` so thousands of variable-height cards render smoothly, with a memoized row component to skip unnecessary re-renders. Optional client-side search bar filters rows by text across any field paths, a built-in loading skeleton stands in while data loads, and `onChange` / `onClick` events report `{ value, index, item }` for the row that was clicked.
```yaml
- id: basic_card_list
type: ListSelector
properties:
data:
- Alpha
- Beta
- Gamma
html: |
{{ index + 1 }}. {{ item }}
```
```yaml
- id: select_list
type: ListSelector
properties:
hoverable: true
data:
- id: 1
name: Starter
price: $0
- id: 2
name: Pro
price: $20
- id: 3
name: Enterprise
price: $99
html: |
{{ item.name }}
{{ item.price }} / month
events:
onChange:
- id: capture_selected
type: SetState
params:
selected_plan:
_event: value
- id: selected_plan_display
type: Paragraph
properties:
content:
_nunjucks:
template: "Selected: {{ selected_plan.name }}"
on:
_state: true
```
```yaml
- id: readonly_list
type: ListSelector
properties:
selectable: false
data:
- One
- Two
- Three
html: |
{{ item }}
```
```yaml
- id: empty_list
type: ListSelector
properties:
data: []
noData: No people to show yet.
html: |
{{ item.name }}
```
```yaml
- id: people_card_list
type: ListSelector
properties:
hoverable: true
bordered: false
data:
- name: Ada Lovelace
email: ada@example.com
role: Mathematician
- name: Linus Torvalds
email: linus@example.com
role: Engineer
- name: Grace Hopper
email: grace@example.com
role: Computer Scientist
html: |
```
```yaml
- id: click_card_list
type: ListSelector
properties:
hoverable: true
data:
- id: 1
label: First
- id: 2
label: Second
- id: 3
label: Third
html: |
{{ item.label }}
Click to see which row was selected.
events:
onClick:
- id: capture_clicked
type: SetState
params:
clicked_card:
_event: true
```
```yaml
- id: compact_card_list
type: ListSelector
properties:
size: small
gap: 4
data:
- One
- Two
- Three
- Four
html: |
{{ item }}
```
```yaml
- id: large_card_list
type: ListSelector
properties:
hoverable: true
height: 480
data:
_string.split:
on:
_string.repeat:
on: x,
count: 999
separator: ","
html: >
Row {{ index + 1 }}
This list renders one thousand cards. Only rows in (and near) the
viewport are mounted in the DOM.
```
```yaml
- id: search_all_card_list
type: ListSelector
properties:
hoverable: true
height: 360
search: {}
data:
- name: Ada Lovelace
email: ada@example.com
role: Mathematician
- name: Linus Torvalds
email: linus@example.com
role: Engineer
- name: Grace Hopper
email: grace@example.com
role: Computer Scientist
- name: Alan Turing
email: alan@example.com
role: Mathematician
- name: Margaret Hamilton
email: margaret@example.com
role: Software Engineer
html: >
{{ item.name }}
```
```yaml
- id: search_fields_card_list
type: ListSelector
properties:
hoverable: true
height: 360
search:
placeholder: Filter by name…
fields:
- name
minLength: 1
data:
- name: Ada Lovelace
email: ada@example.com
role: Mathematician
- name: Linus Torvalds
email: linus@example.com
role: Engineer
- name: Grace Hopper
email: grace@example.com
role: Computer Scientist
html: |
{{ item.name }}
{{ item.role }}
```
```yaml
- id: keyed_list
type: ListSelector
properties:
valueKey: id
primaryKey: id
data:
- id: 1
name: Starter
price: $0
- id: 2
name: Pro
price: $20
- id: 3
name: Enterprise
price: $99
html: |
{{ item.name }}
{{ item.price }} / month
events:
onChange:
- id: capture_keyed
type: SetState
params:
keyed_plan_id:
_event: value
- id: keyed_plan_display
type: Paragraph
properties:
content:
_nunjucks:
template: 'Selected plan id: {{ keyed_plan_id if keyed_plan_id != null else "—"
}}'
on:
_state: true
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `data` | array | `[]` | Array of items. Each item is rendered as one card by passing it to the html Nunjucks template as `item`. |
| `html` | string | - | Nunjucks template used to render the body of each card. The context exposes `item` (the current data row) and `index` (the zero-based row index). |
| `selectable` | boolean | `true` | Enable selecting a card. When true, clicking a card sets the block value to that data item and highlights it. When false, the block is a read-only card list that stores no value. |
| `allowDeselect` | boolean | `true` | Allow clicking the selected card again to clear the selection (sets the value to null). Ignored when `selectable` is false. |
| `valueKey` | string | - | Field of each data item stored as the block value when a card is selected (e.g. "id"). Omit to store the whole item. Lets the selection be driven with SetState using a simple key. Supports dotted paths. |
| `primaryKey` | string | - | Field used to match the current value (e.g. set with SetState) back to a card for highlighting. Defaults to `valueKey`. Set this when the stored value is the whole item but a single field (e.g. "id") uniquely identifies it. Supports dotted paths. |
| `bordered` | boolean | `true` | Toggles the border around each card. |
| `hoverable` | boolean | `false` | Lift each card up when hovered. |
| `size` | string | `"default"` | Card size. Enum: `default`, `small`. |
| `gap` | number | `8` | Pixel gap between cards. |
| `height` | number \| string | - | Optional pixel height (number) or CSS height string of the scroll container. When omitted, the list scrolls with the page. |
| `overscan` | number | `400` | Pixels of off-screen rows to render above and below the viewport. Increase for smoother fast-scroll, decrease to reduce DOM cost. |
| `noData` | string | - | Text shown in place of the list when the `data` array is empty. Defaults to the `blocks.listSelector.noData` message ("No data"). |
| `search` | object | - | Optional client-side search bar above the list. When this property is set, a debounced search input filters rows by text. Omit to hide the bar. |
| `search.placeholder` | string | `"Search…"` | Placeholder text in the input. |
| `search.fields` | array | - | Dotted field paths to match against (e.g. "user.name"). When omitted, every field path is searched (whole-item stringify). |
| `search.caseSensitive` | boolean | `false` | Match case exactly. |
| `search.debounce` | number | `150` | Milliseconds to wait after the last keystroke before filtering. |
| `search.sticky` | boolean | `true` | Stick the search bar to the top while scrolling. |
| `search.allowClear` | boolean | `true` | Show a clear (×) icon in the input. |
| `search.minLength` | number | `0` | Skip filtering until the query is at least this many characters. |
| `search.noResultsText` | string | `"No results"` | Text shown when the filter matches zero items. |
| `theme` | object | - | Antd design token overrides for the cards. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design card tokens](https://ant.design/components/card#design-token). |
| `theme.bodyPadding` | number | `24` | Padding of each card body. |
| `theme.bodyPaddingSM` | number | `12` | Padding of each card body for small cards. |
| `theme.borderRadiusLG` | number | `8` | Border radius of each card. |
| `theme.colorBorderSecondary` | string | - | Border color of each card. |
| `theme.colorBgContainer` | string | - | Background color of each card body. |
| `theme.colorText` | string | - | Text color inside each card. |
| `theme.boxShadowTertiary` | string | - | Shadow applied to each card on hover when hoverable is true. |
| Event | Event Data | Description |
| --- | --- | --- |
| `onChange` | `{ value, index, item }` | Triggered when the selection changes (only fires when `selectable` is true). |
| `onClick` | `{ index, item }` | Triggered when a card is clicked. |
| `onSearch` | `{ value, resultCount }` | Triggered when the debounced search query changes (only fires when the `search` property is set). |
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The list container. |
| `/card` | Each Card element. |
| `/body` | Each Card body. |
| `/selected` | The selected card. |
| `/search` | The search bar wrapper above the list. |
| `/noResults` | The "no results" placeholder shown when the search filter matches zero items. |
| `/noData` | The "no data" placeholder shown when the data array is empty. |
No slots defined.
---
url: https://docs.lowdefy.com/md/list-blocks/masonrylist.md
---
# MasonryList
Masonry-style grid layout for list data. Items flow into columns and stack vertically, filling gaps left by shorter items. Provide an array in state and use _state operators in the template to access each item's data.
```yaml
- id: ml_basic
type: MasonryList
properties:
columns: 3
gutter: 16
blocks:
- id: ml_basic.$.card
type: Card
class:
_state: ml_basic.$.bg
properties:
size: small
blocks:
- id: ml_basic.$.title_block
type: Title
properties:
content:
_state: ml_basic.$.title
level: 5
- id: ml_basic.$.desc_block
type: Paragraph
properties:
content:
_state: ml_basic.$.desc
```
```yaml
- id: ml_two
type: MasonryList
properties:
columns: 2
gutter: 16
blocks:
- id: ml_two.$.card
type: Card
class:
_state: ml_two.$.bg
properties:
size: small
blocks:
- id: ml_two.$.title_block
type: Title
properties:
content:
_state: ml_two.$.title
level: 5
- id: ml_two.$.body_block
type: Paragraph
properties:
content:
_state: ml_two.$.body
```
```yaml
- id: ml_gutter_tight
type: MasonryList
properties:
columns: 3
gutter: 6
blocks:
- id: ml_gutter_tight.$.card
type: Card
class: bg-bg-layout
properties:
size: small
blocks:
- id: ml_gutter_tight.$.label_block
type: Paragraph
properties:
content:
_state: ml_gutter_tight.$.label
- id: ml_gutter_wide
type: MasonryList
properties:
columns: 3
gutter: 24
blocks:
- id: ml_gutter_wide.$.card
type: Card
class: bg-bg-layout
properties:
size: small
blocks:
- id: ml_gutter_wide.$.label_block
type: Paragraph
properties:
content:
_state: ml_gutter_wide.$.label
```
```yaml
- id: ml_notes
type: MasonryList
properties:
columns: 3
gutter: 12
blocks:
- id: ml_notes.$.card
type: Card
class:
_state: ml_notes.$.bg
properties:
size: small
blocks:
- id: ml_notes.$.row
type: Box
layout:
justify: space-between
align: center
blocks:
- id: ml_notes.$.title_block
type: Title
layout:
flex: 1 1 0
properties:
content:
_state: ml_notes.$.title
level: 5
- id: ml_notes.$.tag_block
type: Tag
layout:
flex: 0 0 auto
properties:
title:
_state: ml_notes.$.tag
color:
_state: ml_notes.$.color
- id: ml_notes.$.body_block
type: Paragraph
properties:
content:
_state: ml_notes.$.body
```
```yaml
- id: ml_team
type: MasonryList
properties:
columns: 4
gutter: 12
blocks:
- id: ml_team.$.card
type: Card
properties:
size: small
blocks:
- id: ml_team.$.header
type: Box
layout:
gap: 8
align: center
blocks:
- id: ml_team.$.avatar
type: Avatar
layout:
flex: 0 0 auto
properties:
content:
_state: ml_team.$.initials
color:
_state: ml_team.$.bg
- id: ml_team.$.name_block
type: Title
layout:
flex: 1 1 0
properties:
content:
_state: ml_team.$.name
level: 5
- id: ml_team.$.role_block
type: Paragraph
properties:
content:
_state: ml_team.$.role
```
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `columns` | integer \| object | `3` | Number of columns, or responsive breakpoint object (e.g. { xs: 1, sm: 2, md: 3 }). |
| `fresh` | boolean | `false` | Keep watching the size of each item and re-layout when it changes, for items whose height changes after they render (images loading, expanding content). |
| `gutter` | number \| array \| object | `0` | Gap between items in pixels. A number, a responsive breakpoint object (e.g. { xs: 8, md: 16 }), or a [horizontal, vertical] array of either. |
| `sequential` | boolean | `false` | Has no effect: antd Masonry always places each item in the shortest column. Kept so existing configs stay valid. |
| `theme` | object | - | Antd design token overrides for this block. Masonry uses global motion tokens for item animations. See [antd design tokens](https://ant.design/components/overview#design-token). See [Ant Design masonry tokens](https://ant.design/components/masonry). |
| `theme.motionDurationSlow` | string | `"0.3s"` | Duration of item position and fade-in animations. |
| `theme.motionDurationFast` | string | `"0.1s"` | Duration of item fade-out animations. |
| `theme.motionEaseOut` | string | `"cubic-bezier(0.215, 0.61, 0.355, 1)"` | Easing function for item animations. |
No events defined.
| Key | Target |
| --- | --- |
| `/block` | Outer block wrapper (always available). |
| `/element` | The MasonryList element. |
| `/item` | Each item in the masonry grid. |
| Slot | Description |
| --- | --- |
| `content` | Blocks rendered for each masonry item. |
---
url: https://docs.lowdefy.com/md/connections/aigateway.md
---
# AI Gateway
The AIGateway connection connects to the [Vercel AI Gateway](https://vercel.com/docs/ai-gateway), one API for models from many providers. It provides the `AIGatewayAgent` agent type for use with [Lowdefy agents](/agents-introduction), the one-shot `GenerateText` and `GenerateObject` requests, and `Decide` on evaluation models such as TypeSafe's Jev.
> The AIGateway connection is provided by the `@lowdefy/connection-ai-gateway` package, which is included by default.
## Connections
### AIGateway
#### Properties
- `apiKey: string`: AI Gateway API key. Use [`_secret`](/_secret) to reference this securely. Optional — falls back to the `AI_GATEWAY_API_KEY` environment variable, or Vercel OIDC when deployed on Vercel.
- `baseURL: string`: Optional base URL for the AI Gateway API.
- `headers: object`: Optional custom headers to include in gateway requests.
- `maxOutputTokens: number`: Default maximum number of tokens a model call generates, for the requests and agents on this connection that do not set their own.
- `timeout: number`: Default milliseconds a model call may take, retries included, before it is cancelled, for the requests and agents on this connection that do not set their own. See _Limits and cancellation_ below.
Model ids name the creator and the model, e.g. `anthropic/claude-sonnet-5`, `google/gemini-3.8-flash` or `typesafe-ai/jev`.
###### Connection example:
```yaml
connections:
- id: gateway
type: AIGateway
properties:
apiKey:
_secret: AI_GATEWAY_API_KEY
```
## Agent Types
### AIGatewayAgent
The `AIGatewayAgent` supports all [common agent properties](/agents-introduction) plus the gateway's routing options:
| Property | Type | Description |
| --- | --- | --- |
| `order` | string[] | Provider slugs to try in order (e.g. `["vertex", "anthropic"]`). The gateway tries each until one succeeds. |
| `only` | string[] | Restrict routing to these provider slugs. |
| `fallbackModels` | string[] | Model ids tried in order when the primary model fails. |
| `user` | string | End-user identifier for spend attribution in gateway analytics. |
| `tags` | string[] | Tags to categorize and filter usage in gateway reports. |
###### Agent with a fallback model:
```yaml
agents:
- id: support_agent
type: AIGatewayAgent
connectionId: gateway
properties:
model: anthropic/claude-sonnet-5
fallbackModels:
- google/gemini-3.8-flash
instructions: |
You are a customer support agent. Search the knowledge
base before answering questions.
maxSteps: 5
tools:
- search-knowledge-base
```
## Evaluation models
Evaluation models return typed decisions — choices, yes/no probabilities and scores — instead of text, answer every question in one pass, and bill input tokens only. On the AI Gateway, `Decide` asks an evaluation model by default (`backend: evaluation`); set `backend: structured-output` to ask a language model on the gateway instead. See [`Decide`](#decide) below.
## Requests
Request types:
- GenerateText
- GenerateObject
- Decide
All AI provider connections (`Anthropic`, `OpenAI`, `Google`, `AIGateway`) provide the same `GenerateText`, `GenerateObject` and `Decide` request types — the `connectionId` selects the provider. These make a single, one-shot model call and return the result. They can be used as page requests, or as steps in [API endpoint routines](/api) — useful for classify, extract, summarize, or decide steps where the surrounding logic stays in your routine. For a closed-vocabulary decision — pick one of these options, yes or no, rate on this scale — use `Decide`.
For multi-step tool use, see [agents](/agents-introduction) instead.
### Limits and cancellation
Two limits bound every AI request. Set them on the request, or on the connection as the default for every request and agent that uses it:
- `maxOutputTokens` caps the tokens one call generates. Without it, the provider's default applies.
- `timeout` cancels a call, retries included, that runs longer than this many milliseconds. The request fails with a `ServiceError`.
A call is also cancelled when the request that started it closes, so a provider call that nobody is waiting for stops instead of running, and billing, to its end:
- A page request, or an API endpoint called over HTTP, is cancelled when the server's request timeout (`config.requestTimeout`, default 30 seconds) answers first, which fails it with a `ServiceError`. On the Node server it is also cancelled when the client disconnects; that is logged as a warning, not an error.
- On [Vercel](/vercel), only the request timeout cancels a call: a client disconnect does not, and the call runs until it finishes, times out, or the function reaches `config.vercel.maxDuration`. Keep `config.requestTimeout` below `maxDuration`, or Vercel stops the function before the timeout can cancel anything (the build warns when it is not).
- Endpoints with `async: true`, `detached: true` calls, and scheduled runs answer at once and then run to their end: the closing request does not cancel them.
- An agent chat turn runs to its end after the client disconnects, so its `onFinish` hooks still save the conversation. Bound it with the agent's `timeout` and `maxSteps`. A `CallAgent` step is cancelled with the routine that runs it.
### Files in messages
A file part in `messages` (`{ type: 'file', data: , mediaType }`) goes to the model as a link when the provider takes that media type as a link (the main providers do for images and PDFs). Any other file, such as a CSV or text file, is downloaded by the server and sent as content, within the request's `fileDownload` limits. The server downloads only an `https:` link to a public address, checking the address on every redirect, and a failed download names the file's host, never its link, so a signed link stays out of the server log. `Decide` takes no files.
When a provider rate-limits a call (HTTP 429), the model client retries it (`maxRetries`), waiting as long as the provider's `Retry-After` asks, up to a minute. If the retries run out, the request fails with a `ServiceError`, as a 429 does on every connection, and the server log records the `Retry-After` value.
### GenerateText
Generates text from a prompt.
#### Properties
- `model: string`: **Required** - Model id to generate with.
- `prompt: string`: Text prompt. Use either `prompt` or `messages`, not both.
- `messages: object[]`: Model messages (`{ role, content }`). Use either `prompt` or `messages`, not both.
- `system: string`: System prompt.
- `allowSystemInMessages: boolean`: Default: `false` - Allow `system` role messages in `messages`. A system message instructs the model as the app itself, so without this a request whose `messages` include one fails. Only set it when the messages come from the app, never from a user (for example a message list built from `_payload`). Use `system` for the system prompt.
- `maxOutputTokens: number`: Maximum number of tokens to generate. Defaults to the connection's `maxOutputTokens`.
- `timeout: number`: Milliseconds the model call may take, retries included, before it is cancelled. Defaults to the connection's `timeout`.
- `fileDownload: object`: Limits on a file in `messages` the server downloads (see [Files in messages](#files-in-messages)).
- `maxBytes: integer`: Default: `20971520` (20 MB) - Largest file the server downloads. A larger file fails the request.
- `timeout: integer`: Default: `30000` - Milliseconds a file download may take.
- `temperature: number`: Sampling temperature (0 to 2).
- `topP: number`: Nucleus sampling.
- `topK: number`: Only sample from the top K options for each subsequent token.
- `frequencyPenalty: number`: Penalize repeated tokens by frequency.
- `presencePenalty: number`: Penalize tokens that have already appeared.
- `seed: number`: Seed for deterministic sampling, if supported by the model.
- `stopSequences: string[]`: Sequences that stop generation.
- `maxRetries: number`: Maximum number of retries. Defaults to 2.
- `providerOptions: object`: Provider-specific options, keyed by provider (e.g. `anthropic`, `openai`, `google`).
#### Response
```yaml
text: string # The generated text.
reasoningText: string # Reasoning text, when the model produced any.
finishReason: string # 'stop', 'length', 'content-filter', ...
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens, ... }).
providerMetadata: object # Provider-specific metadata, when returned.
warnings: array # Call warnings from the provider, when returned.
```
#### Examples
###### Summarize text in an API endpoint routine:
```yaml
api:
- id: summarize-text
type: Api
routine:
- id: summarize
type: GenerateText
connectionId: claude
properties:
model: claude-haiku-4-5
system: You are a concise summarizer.
prompt:
_payload: text
- ':return':
summary:
_step: summarize.text
```
###### Text generation as a page request:
```yaml
requests:
- id: generate_reply
type: GenerateText
connectionId: claude
payload:
message:
_state: customer_message
properties:
model: claude-haiku-4-5
system: Draft a friendly reply to the customer message.
prompt:
_payload: message
```
### GenerateObject
Generates a structured object matching a JSON Schema. Ideal for classification, extraction, and routing decisions — the result lands in `_step` (or `_request`) as plain data your config can act on.
#### Properties
Takes the same properties as `GenerateText`, except `stopSequences`, plus:
- `schema: object`: **Required** - JSON Schema describing the object the model must generate.
- `schemaName: string`: Optional name for the output schema, passed to the model.
- `schemaDescription: string`: Optional description of the output schema, passed to the model.
#### Response
```yaml
object: object # The generated object, matching the schema.
reasoningText: string # Reasoning text, when the model produced any.
finishReason: string # 'stop', 'length', 'content-filter', ...
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens, ... }).
providerMetadata: object # Provider-specific metadata, when returned.
warnings: array # Call warnings from the provider, when returned.
```
#### Examples
###### Classify then route in an API endpoint routine:
```yaml
api:
- id: triage-ticket
type: Api
routine:
- id: classify
type: GenerateObject
connectionId: claude
properties:
model: claude-haiku-4-5
prompt:
_payload: ticket_text
schema:
type: object
properties:
category:
type: string
enum:
- billing
- technical
- other
urgent:
type: boolean
- ':if':
_eq:
- _step: classify.object.urgent
- true
':then':
- id: escalate
type: CallApi
properties:
endpointId: escalate-ticket
payload:
category:
_step: classify.object.category
```
### Decide
Makes typed decisions about a piece of state: pick one of a set of options, judge a statement true or false, or place something on an ordered scale. Every answer comes back in the shape you declared, with a confidence, so a routine can branch on it — and send a low-confidence answer to a person instead.
The build knows every option, so a routine branch that compares an answer with a name that is not one of its options — `_eq: [{ _step: triage.team.choice }, bil-ling]` — fails the build rather than silently never matching. A `_step` reference to a question the step does not ask, or to a field its answer does not have, fails the build the same way.
`Decide` has two backends behind the same interface:
- `evaluation` — an evaluation model, such as TypeSafe's Jev (`typesafe-ai/jev`) on the [AI Gateway](/AIGateway). It returns a probability for every option in one pass, in under a second, and bills input tokens only. The default, and only available, on the `AIGateway` connection.
- `structured-output` — any language model, asked for the answers as structured output that follows a schema of the questions. Providers do not all enforce the schema, so Lowdefy checks each answer against its question (see `null` answers below). Available on every AI connection, and the default on `Anthropic`, `OpenAI` and `Google`. Its confidence is the model's own estimate, not a calibrated probability.
Keep the state to what the questions need: an evaluation model reads the state literally, and accuracy drops as it grows. A `Decide` is never a security boundary — text in the state can argue for its own answer.
#### Properties
- `model: string`: **Required** - Model id to decide with, e.g. `typesafe-ai/jev`. Pin a version wherever a confidence threshold is tuned — a `latest` alias changes answers on release.
- `state: string | object | array`: **Required** - What the questions are about.
- `questions: object`: **Required** - Named questions, answered together against the state. Each question id becomes a key of the response (`usage` is reserved). A question is one of:
- `{ choice: string, options: object }` - Pick exactly one option. `options` maps option names (2 to 255) to what each one means (`null` for no description), or to an object with a `description` — its other keys are ignored, so one file can describe the options for `Decide` and for an [`IntentInput`](/IntentInput) block.
- `{ yesno: string, criteria?: { yes: string, no: string } }` - Judge a statement true or false. `criteria` optionally says what counts as yes and as no.
- `{ score: string, levels: string[] }` - Place the state on 2 to 10 ordered levels, lowest first.
- `backend: enum`: `evaluation` or `structured-output`. Defaults to `evaluation` on `AIGateway` and `structured-output` elsewhere.
- `maxOutputTokens: number`: Maximum number of tokens to generate, on the `structured-output` backend (an evaluation model generates no text). Defaults to the connection's `maxOutputTokens`.
- `timeout: number`: Milliseconds the model call may take, retries included, before it is cancelled. Defaults to the connection's `timeout`.
- `maxRetries: number`: Maximum number of retries. Defaults to 2.
- `providerOptions: object`: Provider-specific options, keyed by provider (e.g. `gateway: { zeroDataRetention: true }`).
#### Response
One key per question, plus `usage`:
```yaml
:
choice: string # The chosen option.
confidence: number # 0 to 1.
probabilities: object # Probability per option (evaluation backend), else null.
:
answer: boolean # true when the statement holds.
probability: number # Probability that it holds.
confidence: number # Probability of the given answer.
:
level: string # The most likely level.
index: number # Its position, from 0.
score: number # Fractional position on the scale (evaluation backend).
confidence: number # 0 to 1.
probabilities: object # Probability per level (evaluation backend), else null.
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens }).
```
An answer outside its question's terms (an option or level the question does not have, a yes/no that is not true or false, or no answer at all) comes back with every field `null`, its confidence included. `_lt` compares `null` below any number, so a confidence gate such as `_lt: [{ _step: triage.team.confidence }, 0.7]` holds it back like a low-confidence answer, and a branch on the choice matches none of the options.
#### Examples
###### Route a support ticket, and queue uncertain ones for a person:
```yaml
api:
- id: triage-ticket
type: Api
routine:
- id: triage
type: Decide
connectionId: gateway
properties:
model: typesafe-ai/jev
state:
subject:
_payload: subject
body:
_payload: body
questions:
team:
choice: Which team handles this ticket
options:
billing: Invoices, charges and refunds
tech: Outages and bugs
sales: Plans and quotes
down:
yesno: The customer says the service is down
providerOptions:
gateway:
zeroDataRetention: true
- ':if':
_lt:
- _step: triage.team.confidence
- 0.7
':then':
- id: queue_review
type: MongoDBInsertOne
connectionId: review_queue
properties:
doc:
subject:
_payload: subject
suggested_team:
_step: triage.team.choice
- ':return':
status: review
- ':if':
_eq:
- _step: triage.team.choice
- billing
':then':
- id: open_billing_case
type: CallApi
properties:
endpointId: open-billing-case
- ':return':
team:
_step: triage.team.choice
urgent:
_step: triage.down.answer
```
###### The same decision with any language model:
```yaml
requests:
- id: rate_review
type: Decide
connectionId: claude
payload:
review:
_state: review_text
properties:
model: claude-haiku-4-5
state:
_payload: review
questions:
sentiment:
score: How positive is this review
levels:
- Very negative
- Negative
- Neutral
- Positive
- Very positive
```
---
url: https://docs.lowdefy.com/md/connections/anthropic.md
---
# Anthropic
The Anthropic connection connects to the [Anthropic API](https://docs.anthropic.com/) and provides the `ClaudeAgent` agent type for use with [Lowdefy agents](/agents-introduction).
> The Anthropic connection is provided by the `@lowdefy/connection-anthropic` package, which is included by default.
## Connections
### Anthropic
#### Properties
- `apiKey: string`: __Required__ - Anthropic API key. Use [`_secret`](/_secret) to reference this securely.
- `baseURL: string`: Optional base URL for the Anthropic API. Use this to connect to a proxy or compatible endpoint.
- `maxOutputTokens: number`: Default maximum number of tokens a model call generates, for the requests and agents on this connection that do not set their own.
- `timeout: number`: Default milliseconds a model call may take, retries included, before it is cancelled, for the requests and agents on this connection that do not set their own. See _Limits and cancellation_ below.
###### Connection example:
```yaml
connections:
- id: anthropic
type: Anthropic
properties:
apiKey:
_secret: ANTHROPIC_API_KEY
```
## Agent Types
### ClaudeAgent
The `ClaudeAgent` supports all [common agent properties](/agents-introduction) plus the following:
| Property | Type | Description |
| --- | --- | --- |
| `thinking` | object | Extended thinking configuration. The model shows its reasoning before responding. |
| `thinking.type` | string | Set to `'enabled'` to turn on extended thinking. |
| `thinking.budgetTokens` | integer | Maximum tokens the model can use for thinking. |
| `effort` | string | Thinking effort level: `'low'`, `'medium'`, or `'high'`. Simpler alternative to `thinking`. |
> Use `effort` for a simple control or `thinking` for fine-grained token budget control — not both at the same time.
###### Agent with extended thinking:
```yaml
connections:
- id: anthropic
type: Anthropic
properties:
apiKey:
_secret: ANTHROPIC_API_KEY
agents:
- id: analyst
type: ClaudeAgent
connectionId: anthropic
properties:
model: claude-sonnet-4-20250514
thinking:
type: enabled
budgetTokens: 10000
instructions: |
You are a data analyst. Think carefully through each
question before answering. Show your reasoning.
maxSteps: 8
tools:
- query-analytics
- get-dashboard-data
```
###### Agent with effort level:
```yaml
agents:
- id: support_agent
type: ClaudeAgent
connectionId: anthropic
properties:
model: claude-sonnet-4-20250514
effort: high
instructions: |
You are a customer support agent. Search the knowledge
base before answering questions. Be concise and friendly.
maxSteps: 5
temperature: 0.3
tools:
- search-knowledge-base
- get-account-info
- endpointId: create-ticket
confirm: true
```
## Requests
Request types:
- GenerateText
- GenerateObject
- Decide
All AI provider connections (`Anthropic`, `OpenAI`, `Google`, `AIGateway`) provide the same `GenerateText`, `GenerateObject` and `Decide` request types — the `connectionId` selects the provider. These make a single, one-shot model call and return the result. They can be used as page requests, or as steps in [API endpoint routines](/api) — useful for classify, extract, summarize, or decide steps where the surrounding logic stays in your routine. For a closed-vocabulary decision — pick one of these options, yes or no, rate on this scale — use `Decide`.
For multi-step tool use, see [agents](/agents-introduction) instead.
### Limits and cancellation
Two limits bound every AI request. Set them on the request, or on the connection as the default for every request and agent that uses it:
- `maxOutputTokens` caps the tokens one call generates. Without it, the provider's default applies.
- `timeout` cancels a call, retries included, that runs longer than this many milliseconds. The request fails with a `ServiceError`.
A call is also cancelled when the request that started it closes, so a provider call that nobody is waiting for stops instead of running, and billing, to its end:
- A page request, or an API endpoint called over HTTP, is cancelled when the server's request timeout (`config.requestTimeout`, default 30 seconds) answers first, which fails it with a `ServiceError`. On the Node server it is also cancelled when the client disconnects; that is logged as a warning, not an error.
- On [Vercel](/vercel), only the request timeout cancels a call: a client disconnect does not, and the call runs until it finishes, times out, or the function reaches `config.vercel.maxDuration`. Keep `config.requestTimeout` below `maxDuration`, or Vercel stops the function before the timeout can cancel anything (the build warns when it is not).
- Endpoints with `async: true`, `detached: true` calls, and scheduled runs answer at once and then run to their end: the closing request does not cancel them.
- An agent chat turn runs to its end after the client disconnects, so its `onFinish` hooks still save the conversation. Bound it with the agent's `timeout` and `maxSteps`. A `CallAgent` step is cancelled with the routine that runs it.
### Files in messages
A file part in `messages` (`{ type: 'file', data: , mediaType }`) goes to the model as a link when the provider takes that media type as a link (the main providers do for images and PDFs). Any other file, such as a CSV or text file, is downloaded by the server and sent as content, within the request's `fileDownload` limits. The server downloads only an `https:` link to a public address, checking the address on every redirect, and a failed download names the file's host, never its link, so a signed link stays out of the server log. `Decide` takes no files.
When a provider rate-limits a call (HTTP 429), the model client retries it (`maxRetries`), waiting as long as the provider's `Retry-After` asks, up to a minute. If the retries run out, the request fails with a `ServiceError`, as a 429 does on every connection, and the server log records the `Retry-After` value.
### GenerateText
Generates text from a prompt.
#### Properties
- `model: string`: **Required** - Model id to generate with.
- `prompt: string`: Text prompt. Use either `prompt` or `messages`, not both.
- `messages: object[]`: Model messages (`{ role, content }`). Use either `prompt` or `messages`, not both.
- `system: string`: System prompt.
- `allowSystemInMessages: boolean`: Default: `false` - Allow `system` role messages in `messages`. A system message instructs the model as the app itself, so without this a request whose `messages` include one fails. Only set it when the messages come from the app, never from a user (for example a message list built from `_payload`). Use `system` for the system prompt.
- `maxOutputTokens: number`: Maximum number of tokens to generate. Defaults to the connection's `maxOutputTokens`.
- `timeout: number`: Milliseconds the model call may take, retries included, before it is cancelled. Defaults to the connection's `timeout`.
- `fileDownload: object`: Limits on a file in `messages` the server downloads (see [Files in messages](#files-in-messages)).
- `maxBytes: integer`: Default: `20971520` (20 MB) - Largest file the server downloads. A larger file fails the request.
- `timeout: integer`: Default: `30000` - Milliseconds a file download may take.
- `temperature: number`: Sampling temperature (0 to 2).
- `topP: number`: Nucleus sampling.
- `topK: number`: Only sample from the top K options for each subsequent token.
- `frequencyPenalty: number`: Penalize repeated tokens by frequency.
- `presencePenalty: number`: Penalize tokens that have already appeared.
- `seed: number`: Seed for deterministic sampling, if supported by the model.
- `stopSequences: string[]`: Sequences that stop generation.
- `maxRetries: number`: Maximum number of retries. Defaults to 2.
- `providerOptions: object`: Provider-specific options, keyed by provider (e.g. `anthropic`, `openai`, `google`).
#### Response
```yaml
text: string # The generated text.
reasoningText: string # Reasoning text, when the model produced any.
finishReason: string # 'stop', 'length', 'content-filter', ...
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens, ... }).
providerMetadata: object # Provider-specific metadata, when returned.
warnings: array # Call warnings from the provider, when returned.
```
#### Examples
###### Summarize text in an API endpoint routine:
```yaml
api:
- id: summarize-text
type: Api
routine:
- id: summarize
type: GenerateText
connectionId: claude
properties:
model: claude-haiku-4-5
system: You are a concise summarizer.
prompt:
_payload: text
- ':return':
summary:
_step: summarize.text
```
###### Text generation as a page request:
```yaml
requests:
- id: generate_reply
type: GenerateText
connectionId: claude
payload:
message:
_state: customer_message
properties:
model: claude-haiku-4-5
system: Draft a friendly reply to the customer message.
prompt:
_payload: message
```
### GenerateObject
Generates a structured object matching a JSON Schema. Ideal for classification, extraction, and routing decisions — the result lands in `_step` (or `_request`) as plain data your config can act on.
#### Properties
Takes the same properties as `GenerateText`, except `stopSequences`, plus:
- `schema: object`: **Required** - JSON Schema describing the object the model must generate.
- `schemaName: string`: Optional name for the output schema, passed to the model.
- `schemaDescription: string`: Optional description of the output schema, passed to the model.
#### Response
```yaml
object: object # The generated object, matching the schema.
reasoningText: string # Reasoning text, when the model produced any.
finishReason: string # 'stop', 'length', 'content-filter', ...
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens, ... }).
providerMetadata: object # Provider-specific metadata, when returned.
warnings: array # Call warnings from the provider, when returned.
```
#### Examples
###### Classify then route in an API endpoint routine:
```yaml
api:
- id: triage-ticket
type: Api
routine:
- id: classify
type: GenerateObject
connectionId: claude
properties:
model: claude-haiku-4-5
prompt:
_payload: ticket_text
schema:
type: object
properties:
category:
type: string
enum:
- billing
- technical
- other
urgent:
type: boolean
- ':if':
_eq:
- _step: classify.object.urgent
- true
':then':
- id: escalate
type: CallApi
properties:
endpointId: escalate-ticket
payload:
category:
_step: classify.object.category
```
### Decide
Makes typed decisions about a piece of state: pick one of a set of options, judge a statement true or false, or place something on an ordered scale. Every answer comes back in the shape you declared, with a confidence, so a routine can branch on it — and send a low-confidence answer to a person instead.
The build knows every option, so a routine branch that compares an answer with a name that is not one of its options — `_eq: [{ _step: triage.team.choice }, bil-ling]` — fails the build rather than silently never matching. A `_step` reference to a question the step does not ask, or to a field its answer does not have, fails the build the same way.
`Decide` has two backends behind the same interface:
- `evaluation` — an evaluation model, such as TypeSafe's Jev (`typesafe-ai/jev`) on the [AI Gateway](/AIGateway). It returns a probability for every option in one pass, in under a second, and bills input tokens only. The default, and only available, on the `AIGateway` connection.
- `structured-output` — any language model, asked for the answers as structured output that follows a schema of the questions. Providers do not all enforce the schema, so Lowdefy checks each answer against its question (see `null` answers below). Available on every AI connection, and the default on `Anthropic`, `OpenAI` and `Google`. Its confidence is the model's own estimate, not a calibrated probability.
Keep the state to what the questions need: an evaluation model reads the state literally, and accuracy drops as it grows. A `Decide` is never a security boundary — text in the state can argue for its own answer.
#### Properties
- `model: string`: **Required** - Model id to decide with, e.g. `typesafe-ai/jev`. Pin a version wherever a confidence threshold is tuned — a `latest` alias changes answers on release.
- `state: string | object | array`: **Required** - What the questions are about.
- `questions: object`: **Required** - Named questions, answered together against the state. Each question id becomes a key of the response (`usage` is reserved). A question is one of:
- `{ choice: string, options: object }` - Pick exactly one option. `options` maps option names (2 to 255) to what each one means (`null` for no description), or to an object with a `description` — its other keys are ignored, so one file can describe the options for `Decide` and for an [`IntentInput`](/IntentInput) block.
- `{ yesno: string, criteria?: { yes: string, no: string } }` - Judge a statement true or false. `criteria` optionally says what counts as yes and as no.
- `{ score: string, levels: string[] }` - Place the state on 2 to 10 ordered levels, lowest first.
- `backend: enum`: `evaluation` or `structured-output`. Defaults to `evaluation` on `AIGateway` and `structured-output` elsewhere.
- `maxOutputTokens: number`: Maximum number of tokens to generate, on the `structured-output` backend (an evaluation model generates no text). Defaults to the connection's `maxOutputTokens`.
- `timeout: number`: Milliseconds the model call may take, retries included, before it is cancelled. Defaults to the connection's `timeout`.
- `maxRetries: number`: Maximum number of retries. Defaults to 2.
- `providerOptions: object`: Provider-specific options, keyed by provider (e.g. `gateway: { zeroDataRetention: true }`).
#### Response
One key per question, plus `usage`:
```yaml
:
choice: string # The chosen option.
confidence: number # 0 to 1.
probabilities: object # Probability per option (evaluation backend), else null.
:
answer: boolean # true when the statement holds.
probability: number # Probability that it holds.
confidence: number # Probability of the given answer.
:
level: string # The most likely level.
index: number # Its position, from 0.
score: number # Fractional position on the scale (evaluation backend).
confidence: number # 0 to 1.
probabilities: object # Probability per level (evaluation backend), else null.
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens }).
```
An answer outside its question's terms (an option or level the question does not have, a yes/no that is not true or false, or no answer at all) comes back with every field `null`, its confidence included. `_lt` compares `null` below any number, so a confidence gate such as `_lt: [{ _step: triage.team.confidence }, 0.7]` holds it back like a low-confidence answer, and a branch on the choice matches none of the options.
#### Examples
###### Route a support ticket, and queue uncertain ones for a person:
```yaml
api:
- id: triage-ticket
type: Api
routine:
- id: triage
type: Decide
connectionId: gateway
properties:
model: typesafe-ai/jev
state:
subject:
_payload: subject
body:
_payload: body
questions:
team:
choice: Which team handles this ticket
options:
billing: Invoices, charges and refunds
tech: Outages and bugs
sales: Plans and quotes
down:
yesno: The customer says the service is down
providerOptions:
gateway:
zeroDataRetention: true
- ':if':
_lt:
- _step: triage.team.confidence
- 0.7
':then':
- id: queue_review
type: MongoDBInsertOne
connectionId: review_queue
properties:
doc:
subject:
_payload: subject
suggested_team:
_step: triage.team.choice
- ':return':
status: review
- ':if':
_eq:
- _step: triage.team.choice
- billing
':then':
- id: open_billing_case
type: CallApi
properties:
endpointId: open-billing-case
- ':return':
team:
_step: triage.team.choice
urgent:
_step: triage.down.answer
```
###### The same decision with any language model:
```yaml
requests:
- id: rate_review
type: Decide
connectionId: claude
payload:
review:
_state: review_text
properties:
model: claude-haiku-4-5
state:
_payload: review
questions:
sentiment:
score: How positive is this review
levels:
- Very negative
- Negative
- Neutral
- Positive
- Very positive
```
---
url: https://docs.lowdefy.com/md/connections/google.md
---
# Google
The Google connection connects to the [Google Gemini API](https://ai.google.dev/docs) and provides the `GeminiAgent` agent type for use with [Lowdefy agents](/agents-introduction).
> The Google connection is provided by the `@lowdefy/connection-google` package, which is included by default.
## Connections
### Google
#### Properties
- `apiKey: string`: __Required__ - Google API key. Use [`_secret`](/_secret) to reference this securely.
- `baseURL: string`: Optional base URL for the Google API.
- `maxOutputTokens: number`: Default maximum number of tokens a model call generates, for the requests and agents on this connection that do not set their own.
- `timeout: number`: Default milliseconds a model call may take, retries included, before it is cancelled, for the requests and agents on this connection that do not set their own. See _Limits and cancellation_ below.
###### Connection example:
```yaml
connections:
- id: google
type: Google
properties:
apiKey:
_secret: GOOGLE_API_KEY
```
## Agent Types
### GeminiAgent
The `GeminiAgent` supports all [common agent properties](/agents-introduction) plus the following:
| Property | Type | Description |
| --- | --- | --- |
| `thinkingConfig` | object | Configuration for the model's thinking process. |
| `thinkingConfig.thinkingBudget` | integer | Maximum thinking tokens (Gemini 2.5 models). Set to `0` to disable. |
| `thinkingConfig.thinkingLevel` | string | Thinking depth (Gemini 3 models): `'minimal'`, `'low'`, `'medium'`, or `'high'`. |
| `thinkingConfig.includeThoughts` | boolean | Return thought summaries in the response. |
| `safetySettings` | object[] | Safety filter settings. |
| `safetySettings[].category` | string | Safety category (e.g. `'HARM_CATEGORY_DANGEROUS_CONTENT'`). |
| `safetySettings[].threshold` | string | Block threshold (e.g. `'BLOCK_ONLY_HIGH'`, `'BLOCK_NONE'`). |
###### Agent with thinking enabled:
```yaml
connections:
- id: google
type: Google
properties:
apiKey:
_secret: GOOGLE_API_KEY
agents:
- id: research_agent
type: GeminiAgent
connectionId: google
properties:
model: gemini-2.5-pro
thinkingConfig:
thinkingBudget: 8000
includeThoughts: true
instructions: |
You are a research assistant. Search for information
and provide well-sourced answers. Think through
complex questions step by step.
maxSteps: 8
tools:
- search-knowledge-base
- get-document
```
###### Agent with safety settings:
```yaml
agents:
- id: creative_writer
type: GeminiAgent
connectionId: google
properties:
model: gemini-2.5-pro
temperature: 0.9
safetySettings:
- category: HARM_CATEGORY_DANGEROUS_CONTENT
threshold: BLOCK_ONLY_HIGH
instructions: You are a creative writing assistant.
```
## Requests
Request types:
- GenerateText
- GenerateObject
- Decide
All AI provider connections (`Anthropic`, `OpenAI`, `Google`, `AIGateway`) provide the same `GenerateText`, `GenerateObject` and `Decide` request types — the `connectionId` selects the provider. These make a single, one-shot model call and return the result. They can be used as page requests, or as steps in [API endpoint routines](/api) — useful for classify, extract, summarize, or decide steps where the surrounding logic stays in your routine. For a closed-vocabulary decision — pick one of these options, yes or no, rate on this scale — use `Decide`.
For multi-step tool use, see [agents](/agents-introduction) instead.
### Limits and cancellation
Two limits bound every AI request. Set them on the request, or on the connection as the default for every request and agent that uses it:
- `maxOutputTokens` caps the tokens one call generates. Without it, the provider's default applies.
- `timeout` cancels a call, retries included, that runs longer than this many milliseconds. The request fails with a `ServiceError`.
A call is also cancelled when the request that started it closes, so a provider call that nobody is waiting for stops instead of running, and billing, to its end:
- A page request, or an API endpoint called over HTTP, is cancelled when the server's request timeout (`config.requestTimeout`, default 30 seconds) answers first, which fails it with a `ServiceError`. On the Node server it is also cancelled when the client disconnects; that is logged as a warning, not an error.
- On [Vercel](/vercel), only the request timeout cancels a call: a client disconnect does not, and the call runs until it finishes, times out, or the function reaches `config.vercel.maxDuration`. Keep `config.requestTimeout` below `maxDuration`, or Vercel stops the function before the timeout can cancel anything (the build warns when it is not).
- Endpoints with `async: true`, `detached: true` calls, and scheduled runs answer at once and then run to their end: the closing request does not cancel them.
- An agent chat turn runs to its end after the client disconnects, so its `onFinish` hooks still save the conversation. Bound it with the agent's `timeout` and `maxSteps`. A `CallAgent` step is cancelled with the routine that runs it.
### Files in messages
A file part in `messages` (`{ type: 'file', data: , mediaType }`) goes to the model as a link when the provider takes that media type as a link (the main providers do for images and PDFs). Any other file, such as a CSV or text file, is downloaded by the server and sent as content, within the request's `fileDownload` limits. The server downloads only an `https:` link to a public address, checking the address on every redirect, and a failed download names the file's host, never its link, so a signed link stays out of the server log. `Decide` takes no files.
When a provider rate-limits a call (HTTP 429), the model client retries it (`maxRetries`), waiting as long as the provider's `Retry-After` asks, up to a minute. If the retries run out, the request fails with a `ServiceError`, as a 429 does on every connection, and the server log records the `Retry-After` value.
### GenerateText
Generates text from a prompt.
#### Properties
- `model: string`: **Required** - Model id to generate with.
- `prompt: string`: Text prompt. Use either `prompt` or `messages`, not both.
- `messages: object[]`: Model messages (`{ role, content }`). Use either `prompt` or `messages`, not both.
- `system: string`: System prompt.
- `allowSystemInMessages: boolean`: Default: `false` - Allow `system` role messages in `messages`. A system message instructs the model as the app itself, so without this a request whose `messages` include one fails. Only set it when the messages come from the app, never from a user (for example a message list built from `_payload`). Use `system` for the system prompt.
- `maxOutputTokens: number`: Maximum number of tokens to generate. Defaults to the connection's `maxOutputTokens`.
- `timeout: number`: Milliseconds the model call may take, retries included, before it is cancelled. Defaults to the connection's `timeout`.
- `fileDownload: object`: Limits on a file in `messages` the server downloads (see [Files in messages](#files-in-messages)).
- `maxBytes: integer`: Default: `20971520` (20 MB) - Largest file the server downloads. A larger file fails the request.
- `timeout: integer`: Default: `30000` - Milliseconds a file download may take.
- `temperature: number`: Sampling temperature (0 to 2).
- `topP: number`: Nucleus sampling.
- `topK: number`: Only sample from the top K options for each subsequent token.
- `frequencyPenalty: number`: Penalize repeated tokens by frequency.
- `presencePenalty: number`: Penalize tokens that have already appeared.
- `seed: number`: Seed for deterministic sampling, if supported by the model.
- `stopSequences: string[]`: Sequences that stop generation.
- `maxRetries: number`: Maximum number of retries. Defaults to 2.
- `providerOptions: object`: Provider-specific options, keyed by provider (e.g. `anthropic`, `openai`, `google`).
#### Response
```yaml
text: string # The generated text.
reasoningText: string # Reasoning text, when the model produced any.
finishReason: string # 'stop', 'length', 'content-filter', ...
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens, ... }).
providerMetadata: object # Provider-specific metadata, when returned.
warnings: array # Call warnings from the provider, when returned.
```
#### Examples
###### Summarize text in an API endpoint routine:
```yaml
api:
- id: summarize-text
type: Api
routine:
- id: summarize
type: GenerateText
connectionId: claude
properties:
model: claude-haiku-4-5
system: You are a concise summarizer.
prompt:
_payload: text
- ':return':
summary:
_step: summarize.text
```
###### Text generation as a page request:
```yaml
requests:
- id: generate_reply
type: GenerateText
connectionId: claude
payload:
message:
_state: customer_message
properties:
model: claude-haiku-4-5
system: Draft a friendly reply to the customer message.
prompt:
_payload: message
```
### GenerateObject
Generates a structured object matching a JSON Schema. Ideal for classification, extraction, and routing decisions — the result lands in `_step` (or `_request`) as plain data your config can act on.
#### Properties
Takes the same properties as `GenerateText`, except `stopSequences`, plus:
- `schema: object`: **Required** - JSON Schema describing the object the model must generate.
- `schemaName: string`: Optional name for the output schema, passed to the model.
- `schemaDescription: string`: Optional description of the output schema, passed to the model.
#### Response
```yaml
object: object # The generated object, matching the schema.
reasoningText: string # Reasoning text, when the model produced any.
finishReason: string # 'stop', 'length', 'content-filter', ...
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens, ... }).
providerMetadata: object # Provider-specific metadata, when returned.
warnings: array # Call warnings from the provider, when returned.
```
#### Examples
###### Classify then route in an API endpoint routine:
```yaml
api:
- id: triage-ticket
type: Api
routine:
- id: classify
type: GenerateObject
connectionId: claude
properties:
model: claude-haiku-4-5
prompt:
_payload: ticket_text
schema:
type: object
properties:
category:
type: string
enum:
- billing
- technical
- other
urgent:
type: boolean
- ':if':
_eq:
- _step: classify.object.urgent
- true
':then':
- id: escalate
type: CallApi
properties:
endpointId: escalate-ticket
payload:
category:
_step: classify.object.category
```
### Decide
Makes typed decisions about a piece of state: pick one of a set of options, judge a statement true or false, or place something on an ordered scale. Every answer comes back in the shape you declared, with a confidence, so a routine can branch on it — and send a low-confidence answer to a person instead.
The build knows every option, so a routine branch that compares an answer with a name that is not one of its options — `_eq: [{ _step: triage.team.choice }, bil-ling]` — fails the build rather than silently never matching. A `_step` reference to a question the step does not ask, or to a field its answer does not have, fails the build the same way.
`Decide` has two backends behind the same interface:
- `evaluation` — an evaluation model, such as TypeSafe's Jev (`typesafe-ai/jev`) on the [AI Gateway](/AIGateway). It returns a probability for every option in one pass, in under a second, and bills input tokens only. The default, and only available, on the `AIGateway` connection.
- `structured-output` — any language model, asked for the answers as structured output that follows a schema of the questions. Providers do not all enforce the schema, so Lowdefy checks each answer against its question (see `null` answers below). Available on every AI connection, and the default on `Anthropic`, `OpenAI` and `Google`. Its confidence is the model's own estimate, not a calibrated probability.
Keep the state to what the questions need: an evaluation model reads the state literally, and accuracy drops as it grows. A `Decide` is never a security boundary — text in the state can argue for its own answer.
#### Properties
- `model: string`: **Required** - Model id to decide with, e.g. `typesafe-ai/jev`. Pin a version wherever a confidence threshold is tuned — a `latest` alias changes answers on release.
- `state: string | object | array`: **Required** - What the questions are about.
- `questions: object`: **Required** - Named questions, answered together against the state. Each question id becomes a key of the response (`usage` is reserved). A question is one of:
- `{ choice: string, options: object }` - Pick exactly one option. `options` maps option names (2 to 255) to what each one means (`null` for no description), or to an object with a `description` — its other keys are ignored, so one file can describe the options for `Decide` and for an [`IntentInput`](/IntentInput) block.
- `{ yesno: string, criteria?: { yes: string, no: string } }` - Judge a statement true or false. `criteria` optionally says what counts as yes and as no.
- `{ score: string, levels: string[] }` - Place the state on 2 to 10 ordered levels, lowest first.
- `backend: enum`: `evaluation` or `structured-output`. Defaults to `evaluation` on `AIGateway` and `structured-output` elsewhere.
- `maxOutputTokens: number`: Maximum number of tokens to generate, on the `structured-output` backend (an evaluation model generates no text). Defaults to the connection's `maxOutputTokens`.
- `timeout: number`: Milliseconds the model call may take, retries included, before it is cancelled. Defaults to the connection's `timeout`.
- `maxRetries: number`: Maximum number of retries. Defaults to 2.
- `providerOptions: object`: Provider-specific options, keyed by provider (e.g. `gateway: { zeroDataRetention: true }`).
#### Response
One key per question, plus `usage`:
```yaml
:
choice: string # The chosen option.
confidence: number # 0 to 1.
probabilities: object # Probability per option (evaluation backend), else null.
:
answer: boolean # true when the statement holds.
probability: number # Probability that it holds.
confidence: number # Probability of the given answer.
:
level: string # The most likely level.
index: number # Its position, from 0.
score: number # Fractional position on the scale (evaluation backend).
confidence: number # 0 to 1.
probabilities: object # Probability per level (evaluation backend), else null.
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens }).
```
An answer outside its question's terms (an option or level the question does not have, a yes/no that is not true or false, or no answer at all) comes back with every field `null`, its confidence included. `_lt` compares `null` below any number, so a confidence gate such as `_lt: [{ _step: triage.team.confidence }, 0.7]` holds it back like a low-confidence answer, and a branch on the choice matches none of the options.
#### Examples
###### Route a support ticket, and queue uncertain ones for a person:
```yaml
api:
- id: triage-ticket
type: Api
routine:
- id: triage
type: Decide
connectionId: gateway
properties:
model: typesafe-ai/jev
state:
subject:
_payload: subject
body:
_payload: body
questions:
team:
choice: Which team handles this ticket
options:
billing: Invoices, charges and refunds
tech: Outages and bugs
sales: Plans and quotes
down:
yesno: The customer says the service is down
providerOptions:
gateway:
zeroDataRetention: true
- ':if':
_lt:
- _step: triage.team.confidence
- 0.7
':then':
- id: queue_review
type: MongoDBInsertOne
connectionId: review_queue
properties:
doc:
subject:
_payload: subject
suggested_team:
_step: triage.team.choice
- ':return':
status: review
- ':if':
_eq:
- _step: triage.team.choice
- billing
':then':
- id: open_billing_case
type: CallApi
properties:
endpointId: open-billing-case
- ':return':
team:
_step: triage.team.choice
urgent:
_step: triage.down.answer
```
###### The same decision with any language model:
```yaml
requests:
- id: rate_review
type: Decide
connectionId: claude
payload:
review:
_state: review_text
properties:
model: claude-haiku-4-5
state:
_payload: review
questions:
sentiment:
score: How positive is this review
levels:
- Very negative
- Negative
- Neutral
- Positive
- Very positive
```
---
url: https://docs.lowdefy.com/md/connections/mcp.md
---
# MCP
The MCP connection defines a [Model Context Protocol](https://modelcontextprotocol.io/) server that provides tools to [Lowdefy agents](/agents-introduction). MCP is an open standard for connecting AI models to external tools and data sources.
> The MCP connection is provided by the `@lowdefy/connection-mcp` package, which is included by default.
MCP connections are referenced from the `mcp` array on an agent. The agent automatically discovers and uses the tools the MCP server provides. See [MCP Tools](/agent-mcp-tools) for details on using MCP with agents and for inline configuration without a connection.
## Connections
### Mcp
#### Properties
| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `transport` | string | `'http'` | Transport protocol: `'http'`, `'sse'`, or `'stdio'`. |
| `url` | string | | URL for the MCP server. Required for `http` and `sse` transports. |
| `headers` | object | | HTTP headers. Only for `http` and `sse`. __Operators are evaluated__. |
| `command` | string | | Command to run. Required for `stdio` transport. |
| `args` | string[] | | Arguments for the stdio command. |
| `env` | object | | Environment variables for the stdio command. __Operators are evaluated__. |
### HTTP Transport
Connect to a remote MCP server over HTTP:
```yaml
connections:
- id: mcp_tools
type: Mcp
properties:
url: https://mcp.example.com/tools
transport: http
```
###### With authentication:
```yaml
connections:
- id: mcp_tools
type: Mcp
properties:
url: https://mcp.example.com/tools
transport: http
headers:
Authorization:
_string.concat:
- 'Bearer '
- _secret: MCP_API_KEY
```
### SSE Transport
Connect using Server-Sent Events:
```yaml
connections:
- id: mcp_sse
type: Mcp
properties:
url: https://mcp.example.com/sse
transport: sse
```
### Stdio Transport
Launch a local MCP server process. Useful for npm-published MCP servers:
###### File system access:
```yaml
connections:
- id: mcp_filesystem
type: Mcp
properties:
transport: stdio
command: npx
args:
- '-y'
- '@modelcontextprotocol/server-filesystem'
- '/data/documents'
```
###### GitHub integration:
```yaml
connections:
- id: mcp_github
type: Mcp
properties:
transport: stdio
command: npx
args:
- '-y'
- '@modelcontextprotocol/server-github'
env:
GITHUB_TOKEN:
_secret: GITHUB_TOKEN
```
###### Custom server with environment variables:
```yaml
connections:
- id: mcp_database
type: Mcp
properties:
transport: stdio
command: node
args:
- ./mcp-servers/database.js
env:
DATABASE_URL:
_secret: DATABASE_URL
```
## Usage
Reference MCP connections in the `mcp` array on an agent:
```yaml
agents:
- id: dev_assistant
type: ClaudeAgent
connectionId: anthropic
properties:
model: claude-sonnet-4-20250514
instructions: |
You help developers with code and GitHub issues.
Use GitHub tools to search issues, read files,
and create pull requests.
mcp:
- mcp_github
- mcp_filesystem
```
MCP servers can also be defined inline on the agent without a connection. See [MCP Tools](/agent-mcp-tools) for inline configuration.
---
url: https://docs.lowdefy.com/md/connections/openai-connection.md
---
# OpenAI
The OpenAI connection connects to the [OpenAI API](https://platform.openai.com/docs/) and provides the `OpenAIAgent` agent type for use with [Lowdefy agents](/agents-introduction).
> The OpenAI connection is provided by the `@lowdefy/connection-openai` package, which is included by default.
## Connections
### OpenAI
#### Properties
- `apiKey: string`: __Required__ - OpenAI API key. Use [`_secret`](/_secret) to reference this securely.
- `baseURL: string`: Optional base URL. Use this to connect to Azure OpenAI or any OpenAI-compatible endpoint.
- `maxOutputTokens: number`: Default maximum number of tokens a model call generates, for the requests and agents on this connection that do not set their own.
- `timeout: number`: Default milliseconds a model call may take, retries included, before it is cancelled, for the requests and agents on this connection that do not set their own. See _Limits and cancellation_ below.
###### Connection example:
```yaml
connections:
- id: openai
type: OpenAI
properties:
apiKey:
_secret: OPENAI_API_KEY
```
###### Azure OpenAI:
```yaml
connections:
- id: azure_openai
type: OpenAI
properties:
apiKey:
_secret: AZURE_OPENAI_API_KEY
baseURL: https://my-resource.openai.azure.com/openai/deployments/my-deployment
```
## Agent Types
### OpenAIAgent
The `OpenAIAgent` supports all [common agent properties](/agents-introduction) plus the following:
| Property | Type | Description |
| --- | --- | --- |
| `reasoningEffort` | string | Reasoning effort for reasoning models (o3, o4-mini): `'none'`, `'minimal'`, `'low'`, `'medium'`, `'high'`, or `'xhigh'`. |
| `reasoningSummary` | string | Reasoning summary mode: `'auto'` or `'detailed'`. |
> `reasoningEffort` and `reasoningSummary` only apply to OpenAI reasoning models (o3, o4-mini). They are ignored for standard models like gpt-4o.
###### Standard model:
```yaml
agents:
- id: assistant
type: OpenAIAgent
connectionId: openai
properties:
model: gpt-4o
instructions: |
You are a helpful assistant for our internal tools.
Search the documentation when users ask questions.
maxSteps: 5
tools:
- search-docs
- get-user-permissions
```
###### Reasoning model for complex analysis:
```yaml
agents:
- id: code_reviewer
type: OpenAIAgent
connectionId: openai
properties:
model: o4-mini
reasoningEffort: high
reasoningSummary: detailed
instructions: |
You review code changes for bugs, security issues, and
performance problems. Be thorough and specific.
tools:
- get-pull-request
- get-file-contents
```
## Requests
Request types:
- GenerateText
- GenerateObject
- Decide
All AI provider connections (`Anthropic`, `OpenAI`, `Google`, `AIGateway`) provide the same `GenerateText`, `GenerateObject` and `Decide` request types — the `connectionId` selects the provider. These make a single, one-shot model call and return the result. They can be used as page requests, or as steps in [API endpoint routines](/api) — useful for classify, extract, summarize, or decide steps where the surrounding logic stays in your routine. For a closed-vocabulary decision — pick one of these options, yes or no, rate on this scale — use `Decide`.
For multi-step tool use, see [agents](/agents-introduction) instead.
### Limits and cancellation
Two limits bound every AI request. Set them on the request, or on the connection as the default for every request and agent that uses it:
- `maxOutputTokens` caps the tokens one call generates. Without it, the provider's default applies.
- `timeout` cancels a call, retries included, that runs longer than this many milliseconds. The request fails with a `ServiceError`.
A call is also cancelled when the request that started it closes, so a provider call that nobody is waiting for stops instead of running, and billing, to its end:
- A page request, or an API endpoint called over HTTP, is cancelled when the server's request timeout (`config.requestTimeout`, default 30 seconds) answers first, which fails it with a `ServiceError`. On the Node server it is also cancelled when the client disconnects; that is logged as a warning, not an error.
- On [Vercel](/vercel), only the request timeout cancels a call: a client disconnect does not, and the call runs until it finishes, times out, or the function reaches `config.vercel.maxDuration`. Keep `config.requestTimeout` below `maxDuration`, or Vercel stops the function before the timeout can cancel anything (the build warns when it is not).
- Endpoints with `async: true`, `detached: true` calls, and scheduled runs answer at once and then run to their end: the closing request does not cancel them.
- An agent chat turn runs to its end after the client disconnects, so its `onFinish` hooks still save the conversation. Bound it with the agent's `timeout` and `maxSteps`. A `CallAgent` step is cancelled with the routine that runs it.
### Files in messages
A file part in `messages` (`{ type: 'file', data: , mediaType }`) goes to the model as a link when the provider takes that media type as a link (the main providers do for images and PDFs). Any other file, such as a CSV or text file, is downloaded by the server and sent as content, within the request's `fileDownload` limits. The server downloads only an `https:` link to a public address, checking the address on every redirect, and a failed download names the file's host, never its link, so a signed link stays out of the server log. `Decide` takes no files.
When a provider rate-limits a call (HTTP 429), the model client retries it (`maxRetries`), waiting as long as the provider's `Retry-After` asks, up to a minute. If the retries run out, the request fails with a `ServiceError`, as a 429 does on every connection, and the server log records the `Retry-After` value.
### GenerateText
Generates text from a prompt.
#### Properties
- `model: string`: **Required** - Model id to generate with.
- `prompt: string`: Text prompt. Use either `prompt` or `messages`, not both.
- `messages: object[]`: Model messages (`{ role, content }`). Use either `prompt` or `messages`, not both.
- `system: string`: System prompt.
- `allowSystemInMessages: boolean`: Default: `false` - Allow `system` role messages in `messages`. A system message instructs the model as the app itself, so without this a request whose `messages` include one fails. Only set it when the messages come from the app, never from a user (for example a message list built from `_payload`). Use `system` for the system prompt.
- `maxOutputTokens: number`: Maximum number of tokens to generate. Defaults to the connection's `maxOutputTokens`.
- `timeout: number`: Milliseconds the model call may take, retries included, before it is cancelled. Defaults to the connection's `timeout`.
- `fileDownload: object`: Limits on a file in `messages` the server downloads (see [Files in messages](#files-in-messages)).
- `maxBytes: integer`: Default: `20971520` (20 MB) - Largest file the server downloads. A larger file fails the request.
- `timeout: integer`: Default: `30000` - Milliseconds a file download may take.
- `temperature: number`: Sampling temperature (0 to 2).
- `topP: number`: Nucleus sampling.
- `topK: number`: Only sample from the top K options for each subsequent token.
- `frequencyPenalty: number`: Penalize repeated tokens by frequency.
- `presencePenalty: number`: Penalize tokens that have already appeared.
- `seed: number`: Seed for deterministic sampling, if supported by the model.
- `stopSequences: string[]`: Sequences that stop generation.
- `maxRetries: number`: Maximum number of retries. Defaults to 2.
- `providerOptions: object`: Provider-specific options, keyed by provider (e.g. `anthropic`, `openai`, `google`).
#### Response
```yaml
text: string # The generated text.
reasoningText: string # Reasoning text, when the model produced any.
finishReason: string # 'stop', 'length', 'content-filter', ...
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens, ... }).
providerMetadata: object # Provider-specific metadata, when returned.
warnings: array # Call warnings from the provider, when returned.
```
#### Examples
###### Summarize text in an API endpoint routine:
```yaml
api:
- id: summarize-text
type: Api
routine:
- id: summarize
type: GenerateText
connectionId: claude
properties:
model: claude-haiku-4-5
system: You are a concise summarizer.
prompt:
_payload: text
- ':return':
summary:
_step: summarize.text
```
###### Text generation as a page request:
```yaml
requests:
- id: generate_reply
type: GenerateText
connectionId: claude
payload:
message:
_state: customer_message
properties:
model: claude-haiku-4-5
system: Draft a friendly reply to the customer message.
prompt:
_payload: message
```
### GenerateObject
Generates a structured object matching a JSON Schema. Ideal for classification, extraction, and routing decisions — the result lands in `_step` (or `_request`) as plain data your config can act on.
#### Properties
Takes the same properties as `GenerateText`, except `stopSequences`, plus:
- `schema: object`: **Required** - JSON Schema describing the object the model must generate.
- `schemaName: string`: Optional name for the output schema, passed to the model.
- `schemaDescription: string`: Optional description of the output schema, passed to the model.
#### Response
```yaml
object: object # The generated object, matching the schema.
reasoningText: string # Reasoning text, when the model produced any.
finishReason: string # 'stop', 'length', 'content-filter', ...
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens, ... }).
providerMetadata: object # Provider-specific metadata, when returned.
warnings: array # Call warnings from the provider, when returned.
```
#### Examples
###### Classify then route in an API endpoint routine:
```yaml
api:
- id: triage-ticket
type: Api
routine:
- id: classify
type: GenerateObject
connectionId: claude
properties:
model: claude-haiku-4-5
prompt:
_payload: ticket_text
schema:
type: object
properties:
category:
type: string
enum:
- billing
- technical
- other
urgent:
type: boolean
- ':if':
_eq:
- _step: classify.object.urgent
- true
':then':
- id: escalate
type: CallApi
properties:
endpointId: escalate-ticket
payload:
category:
_step: classify.object.category
```
### Decide
Makes typed decisions about a piece of state: pick one of a set of options, judge a statement true or false, or place something on an ordered scale. Every answer comes back in the shape you declared, with a confidence, so a routine can branch on it — and send a low-confidence answer to a person instead.
The build knows every option, so a routine branch that compares an answer with a name that is not one of its options — `_eq: [{ _step: triage.team.choice }, bil-ling]` — fails the build rather than silently never matching. A `_step` reference to a question the step does not ask, or to a field its answer does not have, fails the build the same way.
`Decide` has two backends behind the same interface:
- `evaluation` — an evaluation model, such as TypeSafe's Jev (`typesafe-ai/jev`) on the [AI Gateway](/AIGateway). It returns a probability for every option in one pass, in under a second, and bills input tokens only. The default, and only available, on the `AIGateway` connection.
- `structured-output` — any language model, asked for the answers as structured output that follows a schema of the questions. Providers do not all enforce the schema, so Lowdefy checks each answer against its question (see `null` answers below). Available on every AI connection, and the default on `Anthropic`, `OpenAI` and `Google`. Its confidence is the model's own estimate, not a calibrated probability.
Keep the state to what the questions need: an evaluation model reads the state literally, and accuracy drops as it grows. A `Decide` is never a security boundary — text in the state can argue for its own answer.
#### Properties
- `model: string`: **Required** - Model id to decide with, e.g. `typesafe-ai/jev`. Pin a version wherever a confidence threshold is tuned — a `latest` alias changes answers on release.
- `state: string | object | array`: **Required** - What the questions are about.
- `questions: object`: **Required** - Named questions, answered together against the state. Each question id becomes a key of the response (`usage` is reserved). A question is one of:
- `{ choice: string, options: object }` - Pick exactly one option. `options` maps option names (2 to 255) to what each one means (`null` for no description), or to an object with a `description` — its other keys are ignored, so one file can describe the options for `Decide` and for an [`IntentInput`](/IntentInput) block.
- `{ yesno: string, criteria?: { yes: string, no: string } }` - Judge a statement true or false. `criteria` optionally says what counts as yes and as no.
- `{ score: string, levels: string[] }` - Place the state on 2 to 10 ordered levels, lowest first.
- `backend: enum`: `evaluation` or `structured-output`. Defaults to `evaluation` on `AIGateway` and `structured-output` elsewhere.
- `maxOutputTokens: number`: Maximum number of tokens to generate, on the `structured-output` backend (an evaluation model generates no text). Defaults to the connection's `maxOutputTokens`.
- `timeout: number`: Milliseconds the model call may take, retries included, before it is cancelled. Defaults to the connection's `timeout`.
- `maxRetries: number`: Maximum number of retries. Defaults to 2.
- `providerOptions: object`: Provider-specific options, keyed by provider (e.g. `gateway: { zeroDataRetention: true }`).
#### Response
One key per question, plus `usage`:
```yaml
:
choice: string # The chosen option.
confidence: number # 0 to 1.
probabilities: object # Probability per option (evaluation backend), else null.
:
answer: boolean # true when the statement holds.
probability: number # Probability that it holds.
confidence: number # Probability of the given answer.
:
level: string # The most likely level.
index: number # Its position, from 0.
score: number # Fractional position on the scale (evaluation backend).
confidence: number # 0 to 1.
probabilities: object # Probability per level (evaluation backend), else null.
usage: object # Token usage ({ inputTokens, outputTokens, totalTokens }).
```
An answer outside its question's terms (an option or level the question does not have, a yes/no that is not true or false, or no answer at all) comes back with every field `null`, its confidence included. `_lt` compares `null` below any number, so a confidence gate such as `_lt: [{ _step: triage.team.confidence }, 0.7]` holds it back like a low-confidence answer, and a branch on the choice matches none of the options.
#### Examples
###### Route a support ticket, and queue uncertain ones for a person:
```yaml
api:
- id: triage-ticket
type: Api
routine:
- id: triage
type: Decide
connectionId: gateway
properties:
model: typesafe-ai/jev
state:
subject:
_payload: subject
body:
_payload: body
questions:
team:
choice: Which team handles this ticket
options:
billing: Invoices, charges and refunds
tech: Outages and bugs
sales: Plans and quotes
down:
yesno: The customer says the service is down
providerOptions:
gateway:
zeroDataRetention: true
- ':if':
_lt:
- _step: triage.team.confidence
- 0.7
':then':
- id: queue_review
type: MongoDBInsertOne
connectionId: review_queue
properties:
doc:
subject:
_payload: subject
suggested_team:
_step: triage.team.choice
- ':return':
status: review
- ':if':
_eq:
- _step: triage.team.choice
- billing
':then':
- id: open_billing_case
type: CallApi
properties:
endpointId: open-billing-case
- ':return':
team:
_step: triage.team.choice
urgent:
_step: triage.down.answer
```
###### The same decision with any language model:
```yaml
requests:
- id: rate_review
type: Decide
connectionId: claude
payload:
review:
_state: review_text
properties:
model: claude-haiku-4-5
state:
_payload: review
questions:
sentiment:
score: How positive is this review
levels:
- Very negative
- Negative
- Neutral
- Positive
- Very positive
```
---
url: https://docs.lowdefy.com/md/connections/amazonredshift.md
---
# Amazon Redshift
The [Knex](/Knex) connection can be used to connect to a [Amazon Redshift](https://aws.amazon.com/redshift) database.
## Connections
Connection types:
- Knex
### Knex
#### Properties
- `client: enum`: __Required__ - Should be `redshift` to connect to Amazon Redshift.
- `connection: object | string`: __Required__ - Connection string or object to pass to the [`pg`](https://www.npmjs.com/package/pg) database client.
- `useNullAsDefault: boolean`: If true, undefined keys are replaced with NULL instead of DEFAULT.
#### Examples
###### Connection object:
```yaml
connections:
- id: redshift
type: Knex
properties:
client: redshift
connection:
host:
_secret: REDSHIFT_HOST
database:
_secret: REDSHIFT_DB
user:
_secret: REDSHIFT_USER
password:
_secret: REDSHIFT_PASSWORD
```
Environment variables:
```
LOWDEFY_SECRET_REDSHIFT_HOST = examplecluster.XXXXXXXXXXXX.us-west-2.redshift.amazonaws.com
LOWDEFY_SECRET_REDSHIFT_REDSHIFT_DB = db
LOWDEFY_SECRET_REDSHIFT_USER = user
LOWDEFY_SECRET_REDSHIFT_PASSWORD = password
```
## Requests
Request types:
- KnexBuilder
- KnexRaw
### KnexBuilder
#### Properties
- `query: object[]`: **Required** - SQL query builder array. An array of objects, with a single key which is the name of the knex builder function. The value should be an array of arguments to pass to the builder function.
- `tableName: string | object`: The name of the table to query from.
#### Examples
###### Build a query:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
query:
- select:
- '*'
- from:
- users
- where:
- name
- _payload: name
```
###### Using `tableName`:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
tableName: users
query:
- select:
- '*'
- where:
- name
- _payload: name
```
###### Aliases:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
properties:
tableName:
a: tableA
b: tableB
query:
- select:
- aField: 'a.field'
- bField: 'b.field'
- limit:
- 1
```
### KnexRaw
#### Properties
- `query: string`: **Required** - SQL query string.
- `parameters: string | number | array | object`: SQL query parameters.
#### Examples
###### Simple raw query:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query: SELECT * FROM "my_table";
```
###### Query with named parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = :name
parameters:
name:
_payload: selected_name
```
###### Query with positional parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = ?
parameters:
- _payload: selected_name
```
###### Reference a `.sql` file:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query:
_ref: my_query.sql
```
---
url: https://docs.lowdefy.com/md/connections/awss3.md
---
# Amazon S3
AWS S3 is a file or data storage solution, provided by Amazon Web Services. S3 does not work like a traditional file system, data is stored as objects in a collection of objects called a bucket.
Objects can be read from S3 and stored in S3 using web requests. These objects can be public or private. You can read more [here](https://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html).
Lowdefy integrates with AWS S3 using presigned links. These are links that are authorized to give access to private objects, or that allow you to create new objects, and that expire after a certain amount of time. This allows you to upload or download directly from S3 from the browser.
A guide to creating and connecting to an S3 bucket is given at the bottom of this page.
## Connections
Connection types:
- AwsS3Bucket
### AwsS3Bucket
The `AwsS3Bucket` connection is used to connect to a AWS S3 bucket. AWS S3 is the file storage solution provided by Amazon Web services.
#### Properties
- `accessKeyId: string`: __Required__ - AWS IAM access key id with s3 access.
- `secretAccessKey: string`: __Required__ - AWS IAM secret access key with s3 access.
- `region: string`: __Required__ - AWS region bucket is located in.
- `bucket: string`: __Required__ - S3 bucket name.
- `endpoint: string`: Custom S3 API endpoint for S3-compatible providers like Cloudflare R2, MinIO, DigitalOcean Spaces, Backblaze B2, and Wasabi.
- `forcePathStyle: boolean`: Force path-style bucket addressing (`https://endpoint/bucket/key`). Required by MinIO and some self-hosted S3-compatible setups.
- `publicUrlBase: string`: Base URL used to construct stable public object URLs (e.g. a CloudFront or CDN domain in front of the bucket). Used by download requests when the request sets `public: true`.
- `read: boolean`: Default: `true` - Allow reads from the bucket.
- `write: boolean`: Default: `false` - Allow writes to the bucket.
#### Examples
###### Read and writes on a bucket:
```yaml
connections:
- id: my_bucket
type: AwsS3Bucket
properties:
accessKeyId:
_secret: S3_ACCESS_KEY_ID
secretAccessKey:
_secret: S3_SECRET_ACCESS_KEY
region: eu-west-1
bucket: my-bucket-name
write: true
```
Environment variables:
```
LOWDEFY_SECRET_S3_ACCESS_KEY_ID = AKIAIOSFODNN7EXAMPLE
LOWDEFY_SECRET_S3_SECRET_ACCESS_KEY = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```
###### S3-compatible provider (Cloudflare R2):
```yaml
connections:
- id: r2
type: AwsS3Bucket
properties:
endpoint: https://.r2.cloudflarestorage.com
region: auto
bucket: my-bucket
accessKeyId:
_secret: R2_ACCESS_KEY_ID
secretAccessKey:
_secret: R2_SECRET_ACCESS_KEY
write: true
```
The same connection and requests work against any S3-compatible service — set `endpoint` (and `forcePathStyle: true` for MinIO and most self-hosted setups). Remember to configure CORS on the provider for direct browser uploads.
## Requests
Request types:
- AwsS3DeleteObject
- AwsS3GetObject
- AwsS3HeadObject
- AwsS3PresignedGetObject
- AwsS3PresignedPostPolicy
- AwsS3PutObject
### AwsS3PresignedGetObject
The `AwsS3PresignedGetObject` request is used to get a download link for an object in AWS S3. Reference the request id in the Download block's `downloadPolicyRequestId` property, or open the returned URL with the `Link` action.
#### Properties
- `versionId: string`: VersionId used to reference a specific version of the object.
- `expires: number`: Number of seconds for which the policy should be valid.
- `key: string`: __Required__ - Key (or filename) under which object will be stored. If another file is saved with the same key, that file will be overwritten, so a random string in this field is probably needed.
- `responseContentType: string`: Sets the Content-Type header of the response.
- `responseContentDisposition: string`: Sets the Content-Disposition header of the response.
- `public: boolean`: Default: `false` - Return a stable, non-expiring public URL instead of a signed URL — virtual-hosted style by default, path-style on a custom `endpoint`, or `${publicUrlBase}/${key}` when the connection sets `publicUrlBase`. The object must be publicly readable (e.g. uploaded with acl `public-read`); this is author-declared and never checked at runtime. `versionId`, `responseContentType` and `responseContentDisposition` do not apply to public URLs (providers only honor them on signed requests).
#### Examples
###### Download a pdf and open in a new tab:
```yaml
requests:
- id: my_file_link
type: AwsS3PresignedGetObject
connectionId: my_bucket_connection
properties:
key: pdf-filename-as4dacd.pdf
responseContentType: application/pdf
...
blocks:
- id: getFileButton
type: Button
events:
onClick:
- id: open_file
type: Link
params:
url:
_request: my_file_link
newTab: true
```
### AwsS3PresignedPostPolicy
The `AwsS3PresignedPostPolicy` request is used to create a policy that allows a file to be uploaded to AWS S3. It returns the standard upload-policy descriptor `{ method: 'POST', url, key, bucket, fields }` used by the Upload , UploadPhoto and UploadDragger blocks — reference the request id in the block's `uploadPolicyRequestId` property.
#### Properties
- `acl: enum`: Access control lists used to grant read and write access.
- private
- public-read
- public-read-write
- aws-exec-read
- authenticated-read
- bucket-owner-read
- bucket-owner-full-control
- `conditions: object[] | string[][]`: Conditions to be enforced on the request. An array of objects, or condition arrays. See [here](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html).
- `expires: number`: Number of seconds for which the policy should be valid.
- `key: string`: __Required__ - Key (or filename) under which object will be stored. If another file is saved with the same key, that file will be overwritten, so a random string in this field is probably needed.
- `fields: object`: Fields to be included in the form. Useful for adding metadata to the object such as `Content-Type`. See [S3 POST policy](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html).
#### Examples
###### Upload a file with user filename and random id:
```yaml
- id: my_post_policy
type: AwsS3PresignedPostPolicy
connectionId: my_bucket_connection
payload:
filename:
_args: filename
uid:
_args: uid
properties:
key:
_nunjucks:
template: uploads/{{filename}}-{{uid}}
on:
filename:
_payload: filename
uid:
_payload: uid
```
### AwsS3GetObject
The `AwsS3GetObject` request reads an object from the bucket on the server and returns its
content as a base64 encoded string, so [API endpoint](/lowdefy-api) routine steps can process
file content with operators and pass it to other steps (e.g. transform an uploaded file and
store the result with `AwsS3PutObject`). The connection must allow reads (`read` is `true`
by default). Content rides through the routine as base64, so this suits small and medium files.
#### Properties
- `key: string`: __Required__ - Key under which the object is stored.
- `versionId: string`: VersionId used to reference a specific version of the object.
Returns `{ bucket, key, content, contentType, size }` — `content` is the base64 encoded object.
#### Examples
###### Read a stored file and re-store a processed copy:
```yaml
api:
- id: copy_report
type: Api
routine:
- id: get_object
type: AwsS3GetObject
connectionId: my_bucket
properties:
key:
_payload: key
- id: put_copy
type: AwsS3PutObject
connectionId: my_bucket
properties:
key:
_string.concat: ['copies/', { _payload: key }]
content:
_step: get_object.content
contentType:
_step: get_object.contentType
- ':return':
key:
_step: put_copy.key
```
### AwsS3HeadObject
The `AwsS3HeadObject` request checks on the server whether an object exists in the bucket and
returns its metadata without reading its content. Use it in an [API endpoint](/lowdefy-api) routine
to confirm a file uploaded from the browser with an `AwsS3PresignedPostPolicy` actually arrived, and
to take its size and content type from S3 rather than from the caller. The connection must allow
reads (`read` is `true` by default).
#### Properties
- `key: string`: __Required__ - Key under which the object is stored.
- `versionId: string`: VersionId used to reference a specific version of the object.
Returns `{ exists: true, bucket, key, size, contentType, etag, lastModified, versionId }` for an
object that exists (`size` in bytes, `lastModified` a date, `contentType` and `versionId` only when
S3 returns them), and `{ exists: false, bucket, key }` when S3 answers not found. Any other S3 error
throws. S3 answers not found only when the credentials may list the bucket (`s3:ListBucket`);
without that permission a missing object is a 403 error, which throws.
#### Examples
###### Record an upload only once it is in the bucket:
```yaml
api:
- id: record_upload
type: Api
routine:
- id: head_object
type: AwsS3HeadObject
connectionId: my_bucket
properties:
key:
_payload: key
- :if:
_not:
_step: head_object.exists
:then:
- :reject: The upload did not arrive.
- id: insert_file
type: MongoDBInsertOne
connectionId: files
properties:
doc:
key:
_step: head_object.key
size:
_step: head_object.size
contentType:
_step: head_object.contentType
- ':return':
size:
_step: head_object.size
```
### AwsS3PutObject
The `AwsS3PutObject` request writes an object to the bucket from the server. It accepts base64 encoded
content, which makes it the storage half of the server-side file handling pattern: an upload block with
`emitFileContent: true` sends the file as a base64 payload to an [API endpoint](/lowdefy-api) with the
`CallAPI` action, and a routine step stores it. The connection must set `write: true`.
In place of `content`, it takes a `url` and streams what that https link answers into the bucket, so a
routine can copy a file it is handed as a presigned link without the bytes passing through the routine.
The copy is capped at `maxBytes`, can be limited to `contentTypes`, and must finish within `timeout`.
#### Properties
- `key: string`: __Required__ - Key under which the object will be stored.
- `content: string`: Object content as a base64 encoded string. Give either `content` or `url`.
- `url: string`: An `https:` link to a public address whose answer is streamed into the bucket. Give either `content` or `url`.
- `maxBytes: integer`: __Required with `url`__ - The most bytes the link may answer with. A `Content-Length` over it is refused before the body is read, and a body that passes it is cut off and refused, so nothing larger is stored.
- `contentTypes: string[]`: With `url`, the content types the link may answer with, such as `image/png`, `image/*` or `application/pdf`. Any other answer is refused.
- `timeout: integer`: Default: `20000` - With `url`, the milliseconds the whole fetch and upload may take.
- `contentType: string`: MIME type of the object (sets the Content-Type of the stored object). With `url`, the stored object takes the link's `Content-Type` unless this is given.
- `acl: enum`: Access control lists used to grant read and write access (same values as AwsS3PresignedPostPolicy).
Returns `{ bucket, key, size, contentType }`, with `size` in bytes and `contentType` the stored content type, or `null` when there is none.
A refused copy from a `url` stores nothing and throws an error whose `code` names the reason, so a `:catch` can answer each its own way (`_error: code`):
- `url_not_https`: the link, or a link it redirects to, is not `https:`. Refused before that link is requested.
- `url_not_public`: the link, or a link it redirects to, leads to an address that is not public: loopback, private, link-local (such as a cloud metadata address), unique-local, carrier-grade NAT, unspecified or multicast. The address is checked as the connection is opened, so nothing is sent to it.
- `too_large`: the answer is larger than `maxBytes`.
- `content_type`: the answer's `Content-Type` is not one of `contentTypes`.
- `fetch_failed`: the link answered with a status that is not 2xx (the error's `statusCode` holds it), could not be reached, or sent a body that does not match its `Content-Length`.
- `timeout`: the fetch and upload took longer than `timeout`.
#### Examples
###### Store a file sent as an endpoint payload:
```yaml
api:
- id: store_report
type: Api
routine:
- id: put_object
type: AwsS3PutObject
connectionId: my_bucket
properties:
key:
_string.concat:
- 'reports/'
- _payload: name
content:
_payload: content
contentType:
_payload: type
- ':return':
key:
_step: put_object.key
```
###### Copy a screenshot handed over as a presigned link:
```yaml
api:
- id: copy_screenshot
type: InternalApi
routine:
- :try:
- id: copy
type: AwsS3PutObject
connectionId: my_bucket
properties:
key:
_string.concat:
- 'screenshots/'
- _payload: ticket_id
url:
_payload: screenshot_url
maxBytes: 10000000
contentTypes:
- image/*
:catch:
- :if:
_eq:
- _error: code
- too_large
:then:
:reject: The screenshot is larger than 10 MB.
- :throw:
_error: true
- ':return':
size:
_step: copy.size
```
### AwsS3DeleteObject
The `AwsS3DeleteObject` request deletes one object, or up to 1000 objects in one call, from the
connection's bucket. Use it in an [API endpoint](/lowdefy-api) routine to remove objects the routine
stored and no longer wants, such as the files it copied before a later step refused the call. It
deletes only from the bucket the connection names; the request takes no bucket. The connection must
set `write: true`.
#### Properties
- `key: string`: Key of the object to delete. Give either `key` or `keys`.
- `keys: string[]`: Keys of the objects to delete, 1 to 1000. Give either `key` or `keys`.
Returns `{ bucket, deleted, errors }`: `deleted` lists the keys deleted, and `errors` lists each key
S3 could not delete as `{ key, code, message }`, such as `AccessDenied`. A key with no object
counts as deleted, as S3 reports it. A failure of the call itself, such as wrong credentials or a
missing bucket, throws. With one `key`, a key S3 cannot delete throws too, so `errors` is always
empty.
#### Examples
###### Remove both copies when either copy is refused:
```yaml
api:
- id: attach_files
type: Api
routine:
- :try:
- id: copy_screenshot
type: AwsS3PutObject
connectionId: my_bucket
properties:
key:
_string.concat:
- 'tickets/'
- _payload: ticket_id
- '/screenshot'
url:
_payload: screenshot_url
maxBytes: 10000000
- id: copy_log
type: AwsS3PutObject
connectionId: my_bucket
properties:
key:
_string.concat:
- 'tickets/'
- _payload: ticket_id
- '/log'
url:
_payload: log_url
maxBytes: 10000000
:catch:
- id: remove_copies
type: AwsS3DeleteObject
connectionId: my_bucket
properties:
keys:
- _string.concat:
- 'tickets/'
- _payload: ticket_id
- '/screenshot'
- _string.concat:
- 'tickets/'
- _payload: ticket_id
- '/log'
- :reject: The files could not be stored.
```
## Creating a bucket
###### Step 1 - Create an AWS account
Go to the [AWS homepage](https://aws.amazon.com/) and create an account if you don't already have one. you can find more information [here](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/).
###### Step 2 - Create an S3 bucket
1. Once logged in, search for S3 in the search box.
2. Click 'Create Bucket'
3. Choose a name and AWS region for your bucket
4. Continue creating the bucket with any extra settings is needed.
5. Make sure the 'Block all public access' box is ticked if you don't want to allow public access.
6. Click 'Create Bucket'
###### Step 3 - Set the CORS settings for your bucket
CORS, or Cross-Origin Resource Sharing is a security feature that is used to restrict web applications from accessing resources from different origins, or domain names. To allow your Lowdefy app to access the contents of the bucket, you need to add a CORS rule on the bucket that authorizes your app
1. Click on you bucket.
2. Click on the 'Permissions' tab.
3. Click on the 'CORS Configuration' tab.
4. Paste this configuration and save (Fill in your own Lowdefy domain name).
```json
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET", "PUT", "POST", "DELETE", "HEAD"
],
"AllowedOrigins": [
"https://YOUR_LOWDEFY_DOMAIN_HERE"
],
"ExposeHeaders": []
}
]
```
###### Step 4 - Create an IAM user
IAM is the AWS identity and access management system. This can be used to give very granular access permissions. We will create a programmatic user that has the rights to read and write objects in the Bucket.
1. In the 'Services' dropdown in the header, search for 'IAM'.
2. Click on 'Users' in the menu on the left.
3. Click 'Add User'
4. Choose a descriptive name for the user.
5. Choose programmatic access and click next.
6. Choose 'Attach existing policies directly'.
7. Choose 'Create Policy'.
8. Choose the JSON tab and paste the following (Fill in your own bucket name):
```JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::YOUR_BUCKET_NAME_HERE"]
},
{
"Sid": "AllObjectActions",
"Effect": "Allow",
"Action": "s3:*Object",
"Resource": ["arn:aws:s3:::YOUR_BUCKET_NAME_HERE/*"]
}
]
}
```
9. Choose review policy and save.
10. In your previous tab, refresh and search for the policy you just created. Attach it to the user.
11. Click next, review and create the user.
12. Set the access key id and secret access key in your Lowdefy secrets store.
---
url: https://docs.lowdefy.com/md/connections/azureblobstorage.md
---
# Azure Blob Storage
Azure Blob Storage is the object storage service provided by Microsoft Azure. Data is stored as blobs in containers within a storage account. You can read more [here](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction).
Lowdefy integrates with Azure Blob Storage using SAS (shared access signature) tokens — short-lived credentials that let the browser upload and download blobs directly, without file content passing through the Lowdefy server. Azure uploads use a `PUT` request with the file as the raw request body, which the provider-neutral Upload and Download blocks handle automatically.
Direct browser uploads require [CORS configuration on the storage account](https://learn.microsoft.com/en-us/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services) that allows your app's origin.
## Connections
Connection types:
- AzureBlobContainer
### AzureBlobContainer
The `AzureBlobContainer` connection is used to connect to an Azure Blob Storage container.
#### Properties
- `account: string`: __Required__ - Azure storage account name.
- `accountKey: string`: __Required__ - Azure storage account access key.
- `container: string`: __Required__ - Blob container name.
- `publicUrlBase: string`: Base URL used to construct stable public object URLs (e.g. a CDN domain in front of the container). Used by download requests when the request sets `public: true`.
- `read: boolean`: Default: `true` - Allow reads from the container.
- `write: boolean`: Default: `false` - Allow writes to the container.
#### Examples
###### Reads and writes on a container:
```yaml
connections:
- id: blob
type: AzureBlobContainer
properties:
account: mystorageacct
container: uploads
accountKey:
_secret: AZURE_STORAGE_KEY
write: true
```
Environment variables:
```
LOWDEFY_SECRET_AZURE_STORAGE_KEY = your-storage-account-key
```
## Requests
Request types:
- AzureBlobUploadSas
- AzureBlobDownloadSas
- AzureBlobGet
- AzureBlobPut
### AzureBlobUploadSas
The `AzureBlobUploadSas` request mints a write SAS URL for direct browser uploads. It returns the standard upload-policy descriptor `{ method: 'PUT', url, key, bucket, headers }` (with the `x-ms-blob-type: BlockBlob` header) used by the Upload , UploadPhoto and UploadDragger blocks — reference the request id in the block's `uploadPolicyRequestId` property. The connection must set `write: true`.
#### Properties
- `key: string`: __Required__ - Key (blob name) under which the object will be stored. If another file is saved with the same key, that file will be overwritten, so a random string in this field is probably needed.
- `expires: number`: Default: `3600` - Number of seconds for which the SAS token should be valid.
- `contentType: string`: MIME type set as the Content-Type header of the upload.
#### Examples
###### Upload a file with the user's filename:
```yaml
requests:
- id: upload_policy
type: AzureBlobUploadSas
connectionId: blob
payload:
name:
_event: file.name
properties:
key:
_string.concat:
- 'uploads/'
- _payload: name
```
### AzureBlobDownloadSas
The `AzureBlobDownloadSas` request mints a read SAS URL for downloads. Reference the request id in the Download block's `downloadPolicyRequestId` property, or open the returned URL with the `Link` action.
#### Properties
- `key: string`: __Required__ - Key (blob name) under which the object is stored.
- `expires: number`: Default: `3600` - Number of seconds for which the SAS token should be valid.
- `public: boolean`: Default: `false` - Return a stable, non-expiring public URL (`https://{account}.blob.core.windows.net/{container}/{key}`, or `${publicUrlBase}/${key}` when the connection sets `publicUrlBase`) instead of a SAS URL. The blob must be publicly readable (public container access); this is author-declared and never checked at runtime.
- `contentDisposition: string`: Sets the Content-Disposition header of the response.
- `contentType: string`: Sets the Content-Type header of the response.
### AzureBlobGet
The `AzureBlobGet` request reads a blob from the container on the server and returns its content
as a base64 encoded string, so [API endpoint](/lowdefy-api) routine steps can process file content
with operators and pass it to other steps. The connection must allow reads (`read` is `true` by
default). Returns `{ bucket, key, content, contentType, size }`.
#### Properties
- `key: string`: __Required__ - Key (blob name) under which the blob is stored.
### AzureBlobPut
The `AzureBlobPut` request writes a block blob to the container from the server. It accepts base64 encoded content, which makes it the storage half of the server-side file handling pattern: an upload block with `emitFileContent: true` sends the file as a base64 payload to an [API endpoint](/lowdefy-api) with the `CallAPI` action, and a routine step stores it. The connection must set `write: true`.
#### Properties
- `key: string`: __Required__ - Key (blob name) under which the blob will be stored.
- `content: string`: __Required__ - Blob content as a base64 encoded string.
- `contentType: string`: MIME type of the blob (sets the Content-Type of the stored blob).
#### Examples
###### Store a file sent as an endpoint payload:
```yaml
api:
- id: store_report
type: Api
routine:
- id: put_object
type: AzureBlobPut
connectionId: blob
properties:
key:
_string.concat:
- 'reports/'
- _payload: name
content:
_payload: content
contentType:
_payload: type
- ':return':
key:
_step: put_object.key
```
---
url: https://docs.lowdefy.com/md/connections/googlecloudstorage.md
---
# Google Cloud Storage
Google Cloud Storage is the object storage service provided by Google Cloud Platform. Data is stored as objects in buckets, and objects can be public or private. You can read more [here](https://cloud.google.com/storage/docs).
Lowdefy integrates with Google Cloud Storage using signed URLs and signed POST policies — short-lived credentials that let the browser upload and download objects directly, without file content passing through the Lowdefy server. The connection plugs into the provider-neutral Upload and Download blocks.
Direct browser uploads require [CORS configuration on the bucket](https://cloud.google.com/storage/docs/using-cors) that allows your app's origin.
## Connections
Connection types:
- GoogleCloudStorageBucket
### GoogleCloudStorageBucket
The `GoogleCloudStorageBucket` connection is used to connect to a Google Cloud Storage bucket.
#### Properties
- `bucket: string`: __Required__ - Google Cloud Storage bucket name.
- `client_email: string`: The email of your service account. If omitted, Application Default Credentials are used (e.g. the attached service account when running on GCP).
- `private_key: string`: The private key for your service account. If omitted, Application Default Credentials are used.
- `projectId: string`: The Google Cloud project ID the bucket belongs to.
- `publicUrlBase: string`: Base URL used to construct stable public object URLs (e.g. a CDN domain in front of the bucket). Used by download requests when the request sets `public: true`.
- `read: boolean`: Default: `true` - Allow reads from the bucket.
- `write: boolean`: Default: `false` - Allow writes to the bucket.
#### Examples
###### Reads and writes with a service account:
```yaml
connections:
- id: my_bucket
type: GoogleCloudStorageBucket
properties:
bucket: my-bucket-name
projectId: my-project
client_email:
_secret: GCS_CLIENT_EMAIL
private_key:
_secret: GCS_PRIVATE_KEY
write: true
```
Environment variables:
```
LOWDEFY_SECRET_GCS_CLIENT_EMAIL = service-account@my-project.iam.gserviceaccount.com
LOWDEFY_SECRET_GCS_PRIVATE_KEY = -----BEGIN PRIVATE KEY-----\n...
```
## Requests
Request types:
- GcsSignedPostPolicy
- GcsSignedGetUrl
- GcsGetObject
- GcsPutObject
### GcsSignedPostPolicy
The `GcsSignedPostPolicy` request signs a V4 POST policy for direct browser uploads. It returns the standard upload-policy descriptor `{ method: 'POST', url, key, bucket, fields }` used by the Upload , UploadPhoto and UploadDragger blocks — reference the request id in the block's `uploadPolicyRequestId` property. The connection must set `write: true`.
#### Properties
- `key: string`: __Required__ - Key under which the object will be stored. If another file is saved with the same key, that file will be overwritten, so a random string in this field is probably needed.
- `expires: number`: Default: `3600` - Number of seconds for which the policy should be valid.
- `fields: object`: Additional form fields to include in the POST policy (e.g. `acl`).
- `conditions: array`: Conditions to be enforced on the request. See [POST policy conditions](https://cloud.google.com/storage/docs/xml-api/post-object-forms#policy_document).
#### Examples
###### Upload a file with the user's filename:
```yaml
requests:
- id: upload_policy
type: GcsSignedPostPolicy
connectionId: my_bucket
payload:
name:
_event: file.name
properties:
key:
_string.concat:
- 'uploads/'
- _payload: name
```
### GcsSignedGetUrl
The `GcsSignedGetUrl` request signs a V4 read URL for downloads. Reference the request id in the Download block's `downloadPolicyRequestId` property, or open the returned URL with the `Link` action.
#### Properties
- `key: string`: __Required__ - Key under which the object is stored.
- `expires: number`: Default: `3600` - Number of seconds for which the signed URL should be valid.
- `public: boolean`: Default: `false` - Return a stable, non-expiring public URL (`https://storage.googleapis.com/{bucket}/{key}`, or `${publicUrlBase}/${key}` when the connection sets `publicUrlBase`) instead of a signed URL. The object must be publicly readable; this is author-declared and never checked at runtime.
- `responseDisposition: string`: Sets the Content-Disposition header of the response.
- `responseType: string`: Sets the Content-Type header of the response.
### GcsGetObject
The `GcsGetObject` request reads an object from the bucket on the server and returns its content
as a base64 encoded string, so [API endpoint](/lowdefy-api) routine steps can process file content
with operators and pass it to other steps. The connection must allow reads (`read` is `true` by
default). Returns `{ bucket, key, content, contentType, size }`.
#### Properties
- `key: string`: __Required__ - Key under which the object is stored.
### GcsPutObject
The `GcsPutObject` request writes an object to the bucket from the server. It accepts base64 encoded content, which makes it the storage half of the server-side file handling pattern: an upload block with `emitFileContent: true` sends the file as a base64 payload to an [API endpoint](/lowdefy-api) with the `CallAPI` action, and a routine step stores it. The connection must set `write: true`.
#### Properties
- `key: string`: __Required__ - Key under which the object will be stored.
- `content: string`: __Required__ - Object content as a base64 encoded string.
- `contentType: string`: MIME type of the object (sets the Content-Type of the stored object).
- `public: boolean`: Default: `false` - Make the stored object publicly readable.
#### Examples
###### Store a file sent as an endpoint payload:
```yaml
api:
- id: store_report
type: Api
routine:
- id: put_object
type: GcsPutObject
connectionId: my_bucket
properties:
key:
_string.concat:
- 'reports/'
- _payload: name
content:
_payload: content
contentType:
_payload: type
- ':return':
key:
_step: put_object.key
```
---
url: https://docs.lowdefy.com/md/connections/axioshttp.md
---
# AxiosHttp
The `AxiosHttp` connection is used to connect to APIs and web servers using HTTP or HTTPS.
It uses the [axios](https://github.com/axios/axios) library.
The same properties can be set on both connections and requests. The properties will be merged, with the request properties overwriting connection properties. This allows properties like authentication headers and the baseURL to be set on the connection, with request specific properties like the request.
>Secrets like authentication headers and API keys should be stored using the [`_secret`](_secret) operator.
## Connections
Connection types:
- AxiosHttp
## Requests
Request types:
- AxiosHttp
### AxiosHttp
#### Properties
- `url: string`: The server URL that will be used for the request.
- `method: enum`: Default: `'get'` - The request method to be used when making the request. Options are:
- `'get'`
- `'delete'`
- `'head'`
- `'options'`
- `'post'`
- `'put'`
- `'patch'`
- `baseURL: string`: `baseURL` will be prepended to `url` unless `url` is absolute. It can be convenient to set `baseURL` for an axios connection to pass relative URLs to requests or mutations using that connection.
- `headers: object`: An object with custom headers to be sent sent with the request. The object keys should be header names, and the values should be the string header values.
- `params: object`: An object with URL parameters to be sent with the request.
- `data: string | object | array`: The data to be sent as the request body. Only applicable for request methods `'put'`, `'post'`, and `'patch'`. Can be an object, array or a string in the format `'Country=Brasil&City=Belo Horizonte'`.
- `auth: object`: Indicates that HTTP Basic authorization should be used, and supplies credentials. This will set an `Authorization` header, overwriting any existing `Authorization` custom headers you have set using `headers`. Only HTTP Basic auth is configurable through this parameter, for Bearer tokens and such, use `Authorization` custom headers instead. The `auth` object should have the following fields:
- `username: string`
- `password: string`
- `httpAgentOptions: object`: Options to pass to the Node.js [`http.Agent`](https://nodejs.org/api/http.html#http_class_http_agent) class.
- `httpsAgentOptions: object`: Options to pass to the Node.js [`https.Agent`](https://nodejs.org/api/http.html#http_class_http_agent) class.
- `maxContentLength: number`: Defines the max size of the http response content allowed in bytes.
- `maxRedirects: number`: Defines the maximum number of redirects to follow. If set to 0, no redirects will be followed.
- `proxy: object`: Defines the hostname and port of the proxy server. The `proxy` object should have the following fields:
- `host: string`: Host IP address (eg. `'127.0.0.1'`).
- `port: number`: Port number.
- `auth: object`: Object with username and password.
- `responseType: enum`: Default: `'json'` - The type of data that the server will respond with. Options are:
- `'document'`
- `'json'`
- `'text'`
- `responseEncoding: string`: Default: `'utf8'` - Indicates encoding to use for decoding responses.
- `timeout: number`: Default: `0` (no timeout) - The number of milliseconds before the request times out. If the request takes longer than `timeout`, the request will be aborted. Set to `0` for no timeout.
- `transformRequest: function`: A function to transform the request data before it is sent. Receives `data` and `headers` as arguments and should return the data to be sent.
- `transformResponse: function`: A function to transform the received data. Receives `data` as an argument and should return the transformed data.
- `validateStatus: function`: A function to validate whether the response should complete successfully given a status code. Receives `status` as an argument and should `true` if the status code is valid.
#### Examples
Properties for a AxiosHttp can be set on either the connection, the request, or both. However, both a connection and request need to be defined.
###### A basic full example requesting data from https://jsonplaceholder.typicode.com
```yaml
lowdefy: 7.1.0
name: Lowdefy starter
connections:
- id: my_api
type: AxiosHttp
properties:
baseURL: https://jsonplaceholder.typicode.com
pages:
- id: welcome
type: PageHeaderMenu
requests:
- id: get_posts
type: AxiosHttp
connectionId: my_api
properties:
url: /posts
events:
onInit:
- id: fetch_get_posts
type: Request
params: get_posts
blocks:
- id: rest_data
type: Markdown
properties:
content:
_string.concat:
- |
```yaml
- _custom_yaml_stringify:
- _request: get_posts
- |
```
```
###### Using the connection to set baseURL and authorization, and handle specific requests as requests.
```yaml
connections:
- id: app_api
type: AxiosHttp
properties:
baseURL: app.com/api
auth:
username: api_user
password:
_secret: API_PASSWORD
# ...
requests:
- id: get_orders
type: AxiosHttp
connectionId: app_api
properties:
url: /orders
- id: update_order
type: AxiosHttp
connectionId: app_api
payload:
order_id:
_state: order_id
data:
_state: true
properties:
url:
_nunjucks:
template: /orders/{{ order_id }}
on:
order_id:
_payload: order_id
method: post
data:
_payload: data
```
###### Setting properties on only the connection:
```yaml
connections:
- id: get_count
type: AxiosHttp
properties:
url: myapp.com/api/count
headers:
X-Api-Key:
_secret: API_KEY
# ...
requests:
- id: get_count
type: AxiosHttp
connectionId: get_count
```
###### Setting properties on only the request, and using a generic connection:
```yaml
connections:
- id: axios
type: AxiosHttp
# ...
requests:
- id: get_api_1
type: AxiosHttp
connectionId: axios
properties:
url: app1.com/api/things
- id: post_to_api_2
type: AxiosHttp
connectionId: axios
payload:
data:
_state: true
properties:
url: api.otherapp.org/other/thing
method: post
data:
_payload: data
```
---
url: https://docs.lowdefy.com/md/connections/elasticsearch.md
---
# Elasticsearch
## Connections
Connection types:
- Elasticsearch
### Elasticsearch
[`Elasticsearch`](https://www.elastic.co/elasticsearch/) is a distributed, RESTful search and analytics engine capable of addressing a growing number of use cases. As the heart of the Elastic Stack, it centrally stores your data for lightning fast search, fine‑tuned relevancy, and powerful analytics that scale with ease.
The Elasticsearch connection can be used to search for documents in your Elasticsearch cluster. Lowdefy integrates with Elasticsearch using the official [Node.js client from Elastic Co.](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/introduction.html), and provides direct access to the full query DSL supported by Elasticsearch.
#### Properties
- `node: string|string[]`: __Required__ - Elasticsearch node(s) to connect to.
- `index: string`: The default index to query. You can also provide a per-request index to override this setting.
- `auth: BasicAuth|CloudAuth`: The authentication data as an object, containing either basic auth credentials (as `username` and `password`), an API key (as `apiKey`), or Elastic Cloud credentials.
- `maxRetries: number`: Max number of retries for each request.
- `requestTimeout: number`: Max request timeout in milliseconds for each request.
The connection accepts many more advanced configuration options. They will be passed to the Elasticsearch client verbatim, so check out the [configuration instructions](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/basic-config.html) provided by Elastic.
#### Examples
###### Authenticated connection with reads and writes:
```yaml
connections:
- id: elasticsearch
type: Elasticsearch
properties:
write: true
node:
_secret: ELASTICSEARCH_HOST
auth:
username:
_secret: ELASTICSEARCH_USER
password:
_secret: ELASTICSEARCH_PASSWORD
```
Environment variables:
```
LOWDEFY_SECRET_ELASTICSEARCH_HOST = http://localhost:9200
LOWDEFY_SECRET_ELASTICSEARCH_USER = es
LOWDEFY_SECRET_ELASTICSEARCH_PASSWORD = password
```
###### Unauthenticated connection with default index:
```yaml
connections:
- id: elasticsearch
type: Elasticsearch
properties:
write: true
node:
_secret: ELASTICSEARCH_HOST
index:
_secret: ELASTICSEARCH_INDEX
```
Environment variables:
```
LOWDEFY_SECRET_ELASTICSEARCH_HOST = http://localhost:9200
LOWDEFY_SECRET_ELASTICSEARCH_INDEX = articles
```
## Requests
Request types:
- ElasticsearchDelete
- ElasticsearchDeleteByQuery
- ElasticsearchIndex
- ElasticsearchSearch
- ElasticsearchUpdate
- ElasticsearchUpdateByQuery
### ElasticsearchDelete
The `ElasticsearchDelete` request removes a JSON document from the specified index.
#### Properties
- `id: string|number`: __Required__ - Unique identifier for the document to be deleted.
- `if_seq_no: number` Only perform the operation if the document has this sequence number. See [Optimistic concurrency control](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#optimistic-concurrency-control-index).
- `if_primary_term: number` Only perform the operation if the document has this primary term. See [Optimistic concurrency control](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#optimistic-concurrency-control-index).
- `refresh: string|boolean` If `true`, Elasticsearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes. Valid values: `true`, `false`, `wait_for`. Default: `false`.
- `routing: string` Custom value used to route operations to a specific shard.
- `timeout: string` Period to [wait for active shards](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#index-wait-for-active-shards). Defaults to 1m (one minute).
- `version: integer` Explicit version number for concurrency control. The specified version must match the current version of the document for the request to succeed.
- `version_type` Specific version type: `external`, `external_gte`.
- `wait_for_active_shards: string` The number of shard copies that must be active before proceeding with the operation. Set to `all` or any positive integer up to the total number of shards in the index (`number_of_replicas+1`). Default: `1`, the primary shard.
See [Active Shards](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#index-wait-for-active-shards).
#### Examples
###### Delete a document:
```yaml
requests:
- id: delete_document
type: ElasticsearchDelete
payload:
selected_id:
_state: selected_id
properties:
id:
_payload: selected_id
```
### ElasticsearchDeleteByQuery
The `ElasticsearchDeleteByQuery` request deletes documents that match the specified query.
#### Properties
- `body: object` The Elasticsearch query body, expressed in the [JSON Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html).
- `query: object`: The Elasticsearch query.
- `_source: string|string[]|boolean`: True or false to return the `_source` field or not, or a list of fields to return.
- `_source_excludes: string|string[]`: A list of fields to exclude from the returned `_source` field.
- `_source_includes: string|string[]`: A list of fields to extract and return from the `_source` field.
- `allow_no_indices: boolean`: Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified).
- `max_docs: number` Maximum number of documents to process. Defaults to all documents.
- `refresh: string|boolean` If `true`, Elasticsearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes. Valid values: `true`, `false`, `wait_for`. Default: `false`.
- `requests_per_second: number` The throttle for this request in sub-requests per second. Defaults to -1 (no throttle).
- `analyzer: string`: The analyzer to use for the query string
- `default_operator: string`: The default operator for query string query (AND or OR).
- `df: string`: The field to use as default where no field prefix is given in the query string.
- `from: number`: Starting offset.
- `size: number`: Number of hits to return.
- `index: string|string[]`: A comma-separated list of index names to search; use _all or empty string to perform the operation on all indices.
- `lenient: boolean`: Specify whether format-based query failures (such as providing text to a numeric field) should be ignored.
- `scroll: string`: Specify how long a consistent view of the index should be maintained for scrolled search.
- `sort: string|string[]`: A comma-separated list of : pairs.
The request accepts many more advanced configuration options. They will be passed to the Elasticsearch client verbatim, so check out the [available options](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-delete-by-query.html#docs-delete-by-query-api-query-params) provided by Elastic.
#### Examples
###### Delete all comments by a user:
```yaml
requests:
- id: delete_multiple
type: ElasticsearchUpdate
payload:
selected_user:
_state: selected_user
properties:
body:
query:
term:
user.id:
_payload: selected_user
```
### ElasticsearchIndex
The `ElasticsearchIndex` request adds a JSON document to the specified data stream or index and makes it searchable. If the target is an index and the document already exists, the request updates the document and increments its version.
#### Properties
- `body: object` The Elasticsearch request body contains the JSON source for the document data.
- `if_seq_no: number` Only perform the operation if the document has this sequence number. See [Optimistic concurrency control](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#optimistic-concurrency-control-index).
- `if_primary_term: number` Only perform the operation if the document has this primary term. See [Optimistic concurrency control](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#optimistic-concurrency-control-index).
- `op_type: 'create'|'index'` Set to `create` to only index the document if it does not already exist (_put if absent_). If a document with the specified `_id` already exists, the indexing operation will fail. Same as using the `/_create` endpoint. Valid values: `index`, `create`. If document id is specified, it defaults to `index`. Otherwise, it defaults to `create`.
- `pipeline: string` ID of the pipeline to use to preprocess incoming documents.
- `refresh: string|boolean` If `true`, Elasticsearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes. Valid values: `true`, `false`, `wait_for`. Default: `false`.
- `routing: string` Custom value used to route operations to a specific shard.
- `timeout: string` Period the request waits for the following operations:
- [Automatic index creation](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#index-creation)
- [Dynamic mapping](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/dynamic-mapping.html) updates
- [Waiting for active shards](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#index-wait-for-active-shards)
Defaults to `1m` (one minute). This guarantees Elasticsearch waits for at least the timeout before failing. The actual wait time could be longer, particularly when multiple waits occur.
- `version: integer` Explicit version number for concurrency control. The specified version must match the current version of the document for the request to succeed.
- `version_type` Specific version type: `external`, `external_gte`.
- `wait_for_active_shards: string` The number of shard copies that must be active before proceeding with the operation. Set to `all` or any positive integer up to the total number of shards in the index (`number_of_replicas+1`). Default: `1`, the primary shard.
See [Active Shards](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#index-wait-for-active-shards).
- `require_alias: boolean` If `true`, the destination must be an [index alias](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/alias.html). Defaults to `false`.
#### Examples
###### Index a new document.
```yaml
requests:
- id: insert_new_comment
type: Elasticsearch
connectionId: elasticsearch
payload:
comment:
_state: comment_input
properties:
body:
comment:
_payload: comment
user_id:
_user: id
timestamp:
_date: now
```
### ElasticsearchSearch
The `ElasticsearchSearch` request searches the Elasticsearch index.
#### Properties
- `body: object` The Elasticsearch query body, expressed in the [JSON Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html).
- `query: object`: The Elasticsearch query.
- `aggs: object`: The [aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) to request from the server.
- `_source: string|string[]|boolean`: True or false to return the _source field or not, or a list of fields to return.
- `_source_excludes: string|string[]`: A list of fields to exclude from the returned _source field.
- `_source_includes: string|string[]`: A list of fields to extract and return from the _source field.
- `allow_no_indices: boolean`: Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified).
- `allow_partial_search_results: boolean`: Indicate if an error should be returned if there is a partial search failure or timeout.
- `analyzer: string`: The analyzer to use for the query string
- `default_operator: string`: The default operator for query string query (AND or OR).
- `df: string`: The field to use as default where no field prefix is given in the query string.
- `from: number`: Starting offset.
- `size: number`: Number of hits to return.
- `index: string|string[]`: A comma-separated list of index names to search; use _all or empty string to perform the operation on all indices.
- `lenient: boolean`: Specify whether format-based query failures (such as providing text to a numeric field) should be ignored.
- `scroll: string`: Specify how long a consistent view of the index should be maintained for scrolled search.
- `sort: string|string[]`: A comma-separated list of : pairs.
The request accepts many more advanced configuration options. They will be passed to the Elasticsearch client verbatim, so check out the [available options](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#_search) provided by Elastic.
#### Examples
###### Fetch the first 10 matching documents.
```yaml
requests:
- id: fetch_docs
type: Elasticsearch
connectionId: elasticsearch
properties:
size: 10
body:
query:
match_all: {}
```
###### Find a document with ID 42.
```yaml
requests:
- id: fetch_docs
type: Elasticsearch
connectionId: elasticsearch
properties:
size: 1
body:
query:
term:
_id: 42
```
###### Fetch articles between yesterday and today, aggregate by author.
```yaml
requests:
- id: fetch_docs
type: Elasticsearch
connectionId: elasticsearch
properties:
size: 1
type: article
body:
query:
range:
timestamp:
gte: now-1d/d
lt: now/d
aggs:
author_aggregation:
terms:
field: author
```
### ElasticsearchUpdate
The `ElasticsearchUpdate` request updates a document using a script or partial document.
#### Properties
- `id: string|number` Unique identifier for the document to be updated.
- `body: object` The Elasticsearch request body contains either a [script](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/modules-scripting-using.html) or a `doc` property with fields to update.
- `if_seq_no: number` Only perform the operation if the document has this sequence number. See [Optimistic concurrency control](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#optimistic-concurrency-control-index).
- `if_primary_term: number` Only perform the operation if the document has this primary term. See [Optimistic concurrency control](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#optimistic-concurrency-control-index).
- `require_alias: boolean` If `true`, the destination must be an [index alias](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/alias.html). Defaults to `false`.
- `refresh: string|boolean` If `true`, Elasticsearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes. Valid values: `true`, `false`, `wait_for`. Default: `false`.
- `retry_on_conflict: boolean` Specify how many times should the operation be retried when a conflict occurs. Default: `0`.
- `routing: string` Custom value used to route operations to a specific shard.
- `_source: string[]|boolean` Set to `false` to disable source retrieval (default: `true`). You can also specify a comma-separated list of the fields you want to retrieve.
- `_source_excludes: string[]` Specify the source fields you want to exclude.
- `_source_includes: string[]` Specify the source fields you want to include.
- `timeout: string` Period the request waits for the following operations:
- [Dynamic mapping](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/dynamic-mapping.html) updates
- [Waiting for active shards](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#index-wait-for-active-shards)
Defaults to `1m` (one minute). This guarantees Elasticsearch waits for at least the timeout before failing. The actual wait time could be longer, particularly when multiple waits occur.
- `wait_for_active_shards: string` The number of shard copies that must be active before proceeding with the operation. Set to `all` or any positive integer up to the total number of shards in the index (`number_of_replicas+1`). Default: `1`, the primary shard.
See [Active Shards](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-index_.html#index-wait-for-active-shards).
#### Examples
###### Update a document:
```yaml
requests:
- id: update
type: ElasticsearchUpdate
payload:
id:
_state: _id
name:
_state: name
properties:
id:
_payload: id
body:
doc:
_payload: name
```
###### Increase the like counter using a script:
```yaml
requests:
- id: increase_like_counter
type: ElasticsearchUpdate
payload:
id:
_state: _id
properties:
id:
_payload: id
body:
script:
source: |
ctx._source.likes++
```
### ElasticsearchUpdateByQuery
The `ElasticsearchUpdateByQuery` request updates documents that match the specified query. If no query is specified, performs an update on every document in the data stream or index without modifying the source, which is useful for picking up mapping changes.
#### Properties
- `body: object` The Elasticsearch query body, expressed in the [JSON Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html).
- `query: object`: The Elasticsearch query.
- `script: object` A [script](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/modules-scripting-using.html) to update documents.
- `_source: string|string[]|boolean`: True or false to return the `_source` field or not, or a list of fields to return.
- `_source_excludes: string|string[]`: A list of fields to exclude from the returned `_source` field.
- `_source_includes: string|string[]`: A list of fields to extract and return from the `_source` field.
- `allow_no_indices: boolean`: Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes _all string or when no indices have been specified).
- `max_docs: number` Maximum number of documents to process. Defaults to all documents.
- `refresh: string|boolean` If `true`, Elasticsearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes. Valid values: `true`, `false`, `wait_for`. Default: `false`.
- `requests_per_second: number` The throttle for this request in sub-requests per second. Defaults to -1 (no throttle).
- `analyzer: string`: The analyzer to use for the query string
- `default_operator: string`: The default operator for query string query (AND or OR).
- `df: string`: The field to use as default where no field prefix is given in the query string.
- `from: number`: Starting offset.
- `size: number`: Number of hits to return.
- `index: string|string[]`: A comma-separated list of index names to search; use _all or empty string to perform the operation on all indices.
- `lenient: boolean`: Specify whether format-based query failures (such as providing text to a numeric field) should be ignored.
- `scroll: string`: Specify how long a consistent view of the index should be maintained for scrolled search.
- `sort: string|string[]`: A comma-separated list of : pairs.
The request accepts many more advanced configuration options. They will be passed to the Elasticsearch client verbatim, so check out the [available options](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/docs-update-by-query.html#docs-update-by-query-api-query-params) provided by Elastic.
#### Examples
###### Update all red cars:
```yaml
requests:
- id: update_red_cars
type: ElasticsearchUpdateByQuery
properties:
body:
query:
term:
color:
value: red
script:
source: 'ctx._source.out_of_stock=true'
```
---
url: https://docs.lowdefy.com/md/connections/googlesheet.md
---
# Google Sheets
## Connections
Connection types:
- GoogleSheet
### GoogleSheet
The `GoogleSheet` connection offers the flexibility to connect to Google Sheets using either an API key or a service account. While an API key is suitable for read-only access to public sheets, most applications will benefit more from using a service account, which offers broader capabilities. For detailed instructions on creating a service account, you can refer to the [Google Sheets API Quickstart Guide](https://developers.google.com/sheets/api/quickstart/js) and the [Google Workspace Guide on Creating a Project](https://developers.google.com/workspace/guides/create-project).
This connection refers to the entire document as the `spreadsheet`, and the individual sheets in the document as `sheets`. The spreadsheet is identified by it's `spreadsheetId`, and sheets can either be identified by their `sheetId` or their `index` (position in the document starting from 0).
When a sheet is accessed in a browser the url either looks like:
`https://docs.google.com/spreadsheets/d/{spreadsheetId}/edit#gid={sheetId}`
The `GoogleSheet` connection works with sheets as a row based data store. Each row is a data record, and a header row needs to be present to define the column names. This header needs to be created in the Google Sheets web interface. Types can be specified for any of the columns in the sheet. If a type is not specified, the value will be read as a string. The `json` type will stringify a object as JSON before saving it, and parse it again when reading.
#### Properties
- `apiKey: string`: API key for your google project.
- `client_email: string`: The email address of your service account.
- `private_key: string`: The private key for your service account. Base64 encode the string if you have issues with the newline characters in the string.
- `sheetId: string`: The ID of the worksheet. Can be found in the URL as the "gid" parameter. One of `sheetId` or `sheetIndex` is required.
- `sheetIndex: number`: The position of the worksheet as they appear in the Google sheets UI. Starts from 0. One of `sheetId` or `sheetIndex` is required.
- `spreadsheetId: string`: __Required__ - The document ID from the URL of the spreadsheet.
- `columnTypes: object`: An object that defines the data types for each column. Each key should be the column name, and the value should be one of: `string`, `number`, `boolean`, `date`, or `json`.
- `read: boolean`: Default: `true` - Allow read operations like find on the sheet.
- `write: boolean`: Default: `false` - Allow write operations like update on the sheet.
#### Examples
###### Read only access to first sheet in a public spreadsheet:
```yaml
connections:
- id: public_sheet
type: GoogleSheet
properties:
apiKey:
_secret: GOOGLE_SHEETS_API_KEY
sheetIndex: 0
spreadsheetId: ubQsWYNGRUq0gFB1sAp2r9oYE19lZ8yGA1T6y0yBoLPW
```
###### Access with a service account, with defined types:
```yaml
connections:
- id: my_sheet
type: GoogleSheet
properties:
client_email:
_secret: GOOGLE_SHEETS_CLIENT_EMAIL
private_key:
_base64.decode:
_secret: GOOGLE_SHEETS_PRIVATE_KEY
sheetId: '1199545345'
spreadsheetId: ubQsWYNGRUq0gFB1sAp2r9oYE19lZ8yGA1T6y0yBoLPW
columnTypes:
name: string
age: number
birthday: date
subscribed: boolean
address: json
```
## Requests
Request types:
- GoogleSheetAppendMany
- GoogleSheetAppendOne
- GoogleSheetDeleteOne
- GoogleSheetGetMany
- GoogleSheetGetOne
- GoogleSheetUpdateMany
- GoogleSheetUpdateOne
### GoogleSheetAppendMany
The `GoogleSheetAppendMany` request inserts an array of documents as rows in a Google Sheet.
#### Properties
- `rows: object[]`: __Required__ - The rows to insert into the sheet. An an array of objects where keys are the column names and values are the values to insert.
- `options: object`: Optional settings. Supported settings are:
- `raw: boolean`: Store raw values instead of converting as if typed into the sheets UI.
#### Examples
###### Insert a list of rows.
```yaml
requests:
- id: append_rows
type: GoogleSheetAppendMany
connectionId: google_sheets
properties:
rows:
- name: D.Va
role: Tank
- name: Tracer
role: Damage
- name: Genji
role: Damage
- name: Reinhart
role: Tank
- name: Mercy
role: Support
```
### GoogleSheetAppendOne
The `GoogleSheetAppendOne` request inserts a documents as a row in a Google Sheet.
#### Properties
- `row: object`: __Required__ - The row to insert into the sheet. An object where keys are the column names and values are the values to insert.
- `options: object`: Optional settings. Supported settings are:
- `raw: boolean`: Store raw values instead of converting as if typed into the sheets UI.
#### Examples
###### Insert a single row:
```yaml
requests:
- id: insert_dva
type: GoogleSheetAppendOne
connectionId: google_sheets
properties:
row:
name: D.Va
role: Tank
real_name: Hana Song
age: 19
```
### GoogleSheetDeleteOne
The `GoogleSheetDeleteOne` request deletes a row from a Google Sheet. It deletes the first row matched by the filter, written as a MongoDB query expression.
#### Properties
- `filter: object`: __Required__ - A MongoDB query expression to filter the data. The first row matched by the filter will be deleted.
- `options: object`: Optional settings. Supported settings are:
- `limit: number`: The maximum number of rows to fetch.
- `skip: number`: The number of rows to skip from the top of the sheet.
#### Examples
###### Delete the row where name is "Hanzo".
```yaml
requests:
- id: delete_hanzo
type: GoogleSheetDeleteOne
connectionId: google_sheets
properties:
filter:
name:
$eq: Hanzo
```
### GoogleSheetGetMany
The `GoogleSheetGetMany` request fetches a number of rows from the spreadsheet. The `limit` and `skip` options can be used to control which documents are read from the spreadsheet. The filter or pipeline options can then be used to filter or transform the fetched data.
#### Properties
- `filter: object`: A MongoDB query expression to filter the data.
- `pipeline: object[]`: A MongoDB aggregation pipeline to transform the data.
- `options: object`: Optional settings. Supported settings are:
- `limit: number`: The maximum number of rows to fetch.
- `skip: number`: The number of rows to skip from the top of the sheet.
#### Examples
###### Get the first 10 rows.
```yaml
requests:
- id: get_10_rows
type: GoogleSheetGetMany
connectionId: google_sheets
properties:
options:
limit: 10
```
###### Pagination using limit and skip.
```yaml
requests:
- id: get_10_rows
type: GoogleSheetGetMany
connectionId: google_sheets
payload:
page_size:
_state: page_size
page_number:
_state: page_number
properties:
options:
skip:
_product:
- _payload: page_size
- _subtract:
- _payload: page_number
- 1
limit:
_payload: page_size
```
###### Get all records where age is greater than 25.
```yaml
requests:
- id: get_10_rows
type: GoogleSheetGetMany
connectionId: google_sheets
properties:
filter:
age:
$gt: 25
```
###### Use an aggregation pipeline to aggregate data.
```yaml
requests:
- id: get_10_rows
type: GoogleSheetGetMany
connectionId: google_sheets
properties:
pipeline:
- $group:
_id: $region
score:
$avg: $score
- $project:
_id: 0
region: $_id
score: 1
- $sort:
score: 1
```
### GoogleSheetGetOne
The `GoogleSheetGetOne` request fetches a single rows from the spreadsheet. The `limit` and `skip` options can be used to control which documents are read from the spreadsheet. The filter option can then be used to filter or select which row is returned.
#### Properties
- `filter: object`: A MongoDB query expression to filter the data.
- `options: object`: Optional settings. Supported settings are:
- `limit: number`: The maximum number of rows to fetch.
- `skip: number`: The number of rows to skip from the top of the sheet.
#### Examples
###### Get row where name is "Zarya".
```yaml
requests:
- id: get_10_rows
type: GoogleSheetGetOne
connectionId: google_sheets
properties:
filter:
name:
$eq: Zarya
```
### GoogleSheetUpdateMany
The `GoogleSheetUpdateMany` request updates all the rows matched by the filter.
#### Properties
- `filter: object`: A MongoDB query expression to filter the data. . All rows matched by the filter will be updated.
- `update: object`: The update to apply to the row. An object where keys are the column names and values are the updated values.
- `options: object`: Optional settings. Supported settings are:
- `limit: number`: The maximum number of rows to fetch.
- `raw: boolean`: Store raw values instead of converting as if typed into the sheets UI.
- `skip: number`: The number of rows to skip from the top of the sheet.
#### Examples
###### Update all rows where age is less than 18.
```yaml
requests:
- id: get_10_rows
type: GoogleSheetUpdateMany
connectionId: google_sheets
properties:
filter:
age:
$lt: 18
update:
minor: true
```
### GoogleSheetUpdateOne
The `GoogleSheetUpdateOne` request updates the first row matched by the filter.
#### Properties
- `filter: object`: A MongoDB query expression to filter the data. . The first row matched by the filter will be updated.
- `update: object`: The update to apply to the row. An object where keys are the column names and values are the updated values.
- `options: object`: Optional settings. Supported settings are:
- `limit: number`: The maximum number of rows to fetch.
- `raw: boolean`: Store raw values instead of converting as if typed into the sheets UI.
- `skip: number`: The number of rows to skip from the top of the sheet.
- `upsert: boolean`: Insert the row if no rows are matched by the filter.
#### Examples
###### Update the row for "Doomfist"
```yaml
requests:
- id: get_10_rows
type: GoogleSheetUpdateOne
connectionId: google_sheets
properties:
filter:
name:
$eq: Doomfist
update:
overpowered: true
```
---
url: https://docs.lowdefy.com/md/connections/knex.md
---
# Knex
[`Knex.js`](http://knexjs.org) is a SQL query builder that can be used to connect to [PostgreSQL](/PostgreSQL), [MS SQL Server](/MSSQL), [MySQL](/MySQL), [MariaDB](/MariaDB), [SQLite](/SQLite), Oracle, and [Amazon Redshift](/AmazonRedshift) databases.
The Knex connection can be used to execute raw SQL queries using the `KnexRaw` requests, or the Knex query builder can be used with the `KnexBuilder` request.
For more details on specific databases, see the database documentation:
## Connections
Connection types:
- Knex
### Knex
#### Properties
- `client: enum`: __Required__ - The database client to use. One of:
- `better-sqlite3`
- `sqlite` (alias of `better-sqlite3`)
- `mssql`
- `mysql2`
- `oracledb`
- `postgres`
- `pg` (alias of `postgres`)
- `postgresql` (alias of `postgres`)
- `redshift`
- `connection: object | string`: __Required__ - Connection string or object to pass to the database client. See the specific client documentation for more details.
- `searchPath: string`: Set PostgreSQL search path.
- `version: string`: Set database version.
- `useNullAsDefault: boolean`: If true, undefined keys are replaced with NULL instead of DEFAULT.
#### Examples
###### MySQL with connection object:
```yaml
connections:
- id: mysql
type: Knex
properties:
client: mysql2
connection:
host:
_secret: MYSQL_HOST
user:
_secret: MYSQL_USER
database:
_secret: MYSQL_DB
password:
_secret: MYSQL_PASSWORD
```
Environment variables:
```
LOWDEFY_SECRET_MYSQL_HOST = database.server.com
LOWDEFY_SECRET_MYSQL_DB = db
LOWDEFY_SECRET_MYSQL_USER = user
LOWDEFY_SECRET_MYSQL_PASSWORD = password
```
###### PostgreSQL with secret connection string:
```yaml
connections:
- id: postgres
type: Knex
properties:
client: postgres
connection:
_secret: PG_CONNECTION_STRING
```
Environment variables:
```
LOWDEFY_SECRET_PG_CONNECTION_STRING = postgresql://user:password@database.server.com:5432/db
```
## Requests
Request types:
- KnexBuilder
- KnexRaw
### KnexBuilder
#### Properties
- `query: object[]`: **Required** - SQL query builder array. An array of objects, with a single key which is the name of the knex builder function. The value should be an array of arguments to pass to the builder function.
- `tableName: string | object`: The name of the table to query from.
#### Examples
###### Build a query:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
query:
- select:
- '*'
- from:
- users
- where:
- name
- _payload: name
```
###### Using `tableName`:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
tableName: users
query:
- select:
- '*'
- where:
- name
- _payload: name
```
###### Aliases:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
properties:
tableName:
a: tableA
b: tableB
query:
- select:
- aField: 'a.field'
- bField: 'b.field'
- limit:
- 1
```
### KnexRaw
#### Properties
- `query: string`: **Required** - SQL query string.
- `parameters: string | number | array | object`: SQL query parameters.
#### Examples
###### Simple raw query:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query: SELECT * FROM "my_table";
```
###### Query with named parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = :name
parameters:
name:
_payload: selected_name
```
###### Query with positional parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = ?
parameters:
- _payload: selected_name
```
###### Reference a `.sql` file:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query:
_ref: my_query.sql
```
---
url: https://docs.lowdefy.com/md/connections/mariadb.md
---
# MariaDB
The [Knex](/Knex) connection can be used to connect to a [MariaDB](https://www.mysql.com) database. To connect to a MariaDB database, use the `mysql2` client — knex does not have a separate `mariadb` client.
## Connections
Connection types:
- Knex
### Knex
#### Properties
- `client: enum`: __Required__ - Use the `mysql2` client to connect to MariaDB.
- `connection: object | string `: __Required__ - Connection object or string to pass to the [`mysql2`](https://www.npmjs.com/package/mysql2) database client.
- `version: string`: Set database version.
- `useNullAsDefault: boolean`: If true, undefined keys are replaced with NULL instead of DEFAULT.
#### Examples
###### Connection object:
```yaml
connections:
- id: mariadb
type: Knex
properties:
client: mysql2
connection:
host:
_secret: MARIADB_HOST
database:
_secret: MARIADB_DB
user:
_secret: MARIADB_USER
password:
_secret: MARIADB_PASSWORD
```
Environment variables:
```
LOWDEFY_SECRET_MARIADB_HOST = database.server.com
LOWDEFY_SECRET_MARIADB_DB = db
LOWDEFY_SECRET_MARIADB_USER = user
LOWDEFY_SECRET_MARIADB_PASSWORD = password
```
## Requests
Request types:
- KnexBuilder
- KnexRaw
### KnexBuilder
#### Properties
- `query: object[]`: **Required** - SQL query builder array. An array of objects, with a single key which is the name of the knex builder function. The value should be an array of arguments to pass to the builder function.
- `tableName: string | object`: The name of the table to query from.
#### Examples
###### Build a query:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
query:
- select:
- '*'
- from:
- users
- where:
- name
- _payload: name
```
###### Using `tableName`:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
tableName: users
query:
- select:
- '*'
- where:
- name
- _payload: name
```
###### Aliases:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
properties:
tableName:
a: tableA
b: tableB
query:
- select:
- aField: 'a.field'
- bField: 'b.field'
- limit:
- 1
```
### KnexRaw
#### Properties
- `query: string`: **Required** - SQL query string.
- `parameters: string | number | array | object`: SQL query parameters.
#### Examples
###### Simple raw query:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query: SELECT * FROM "my_table";
```
###### Query with named parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = :name
parameters:
name:
_payload: selected_name
```
###### Query with positional parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = ?
parameters:
- _payload: selected_name
```
###### Reference a `.sql` file:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query:
_ref: my_query.sql
```
---
url: https://docs.lowdefy.com/md/connections/mongodb.md
---
# MongoDB
MongoDB is a NoSQL database that stores JSON-like documents. These documents are stored in collections, which are like database tables. The fields inside these document can differ from document to document, but generally they are all more or less the same. However documents with different schemas can be stored in the same collection.
##### ObjectIds
MongoDB uses the _id field as the id for a document. This has to be unique for every document in the collection. If no _id is provided when the document is created, a MongoDB [ObjectId](https://docs.mongodb.com/manual/reference/method/ObjectId/) is created for that document. This id includes a timestamp, a random element and an incrementing counter, to ensure it is unique even if multiple ids are created at the same time.
The _id is often represented as:
```js
{
_id: ObjectId("507f1f77bcf86cd799439011")
}
```
To be able to transmit these ids over JSON network connections, and to use them in Lowdefy apps, Lowdefy serializes these ids as (in YAML):
```yaml
_id:
_oid: 507f1f77bcf86cd799439011
```
Ids specified in this way will be treated as ObjectIds by MongoDB requests and mutations.
## Connections
Connection types:
- MongoDBCollection
### MongoDBCollection
The `MongoDBCollection` connection sets up a connection to a MongoDB deployment. A [connection URI](https://docs.mongodb.com/manual/reference/connection-string/index.html) with authentication credentials (username and password) is required. The URI can be in the standard or dns seedlist (srv) formats. Connections are defined on a collection level, since this allows for read/write access control on a per collection level. Access control can also be managed using the roles in the database.
>Since the connection URI contains authentication secrets, it should be stored using the [`_secret`](operators/secret.md) operator.
When the connection has a `changeLog` collection, all write requests log a change record to that collection. The record contains the request arguments, the request context (`blockId`, `pageId`, `requestId`, `connectionId`, `payload`), a `timestamp`, the request `type`, the connection's `changeLog.meta` value, and either the driver response or `before`/`after` document snapshots (for `MongoDBUpdateOne`, `MongoDBVersionedUpdateOne` and `MongoDBDeleteOne`). The response shape of every request stays the same whether or not a log collection is configured.
#### Properties
- `databaseUri: string`: __Required__ - Connection uri string for the MongoDb deployment. Should be stored using the [_secret](operators/secret.md) operator.
- `databaseName: string`: Default: Database specified in connection string - The name of the database in the MongoDB deployment.
- `collection: string`: __Required__ - The name of the MongoDB collection.
- `changeLog: object`: Log all changes made by write requests to a log collection.
- `collection: string`: __Required__ - The name of the collection change log records are written to.
- `meta: object`: Additional data to include in every change log record, for example the user making the change.
- `read: boolean`: Default: `true` - Allow read operations like find on the collection.
- `write: boolean`: Default: `false` - Allow write operations like update on the collection.
- `options: object`: See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/interfaces/mongoclientoptions.html) for more information.
#### Connection pooling
The MongoDB client is created once per unique `databaseUri` and `options` combination and reused for all requests, so requests share the driver's connection pool instead of opening a new connection for every request. The pool can be tuned with the standard driver options, for example:
```yaml
connections:
- id: my_collection
type: MongoDBCollection
properties:
databaseUri:
_secret: MONGODB_URI
collection: my_collection_name
options:
maxPoolSize: 20
minPoolSize: 0
maxIdleTimeMS: 60000
```
#### Examples
###### MongoDB collection with reads and writes:
```yaml
connections:
- id: my_collection
type: MongoDBCollection
properties:
databaseUri:
_secret: MONGODB_URI
collection: my_collection_name
write: true
```
###### MongoDB collection with reads, writes and a log collection:
```yaml
connections:
- id: my_collection
type: MongoDBCollection
properties:
databaseUri:
_secret: MONGODB_URI
collection: my_collection_name
write: true
changeLog:
collection: log_collection_name
meta:
user:
_user: true
```
Environment variables:
```
LOWDEFY_SECRET_MONGODB_URI = mongodb+srv://username:password@server.example.com/database
```
## Requests
Request types:
- MongoDBAggregation
- MongoDBBulkWrite
- MongoDBDeleteMany
- MongoDBDeleteOne
- MongoDBEnrichmentClaim
- MongoDBEnrichmentComplete
- MongoDBEnrichmentEnqueue
- MongoDBFind
- MongoDBFindOne
- MongoDBInsertConsecutiveId
- MongoDBInsertMany
- MongoDBInsertManyConsecutiveIds
- MongoDBInsertOne
- MongoDBTableChanges
- MongoDBTableQuery
- MongoDBUpdateMany
- MongoDBUpdateOne
- MongoDBVersionedUpdateOne
### MongoDBAggregation
The `MongoDBAggregation` request executes an [aggregation pipeline](https://docs.mongodb.com/manual/core/aggregation-pipeline/) in the collection specified in the connectionId. It returns the array of documents returned by the aggregation. Aggregation pipelines are MongoDB's data processing and aggregation framework. They are based on a series of stages, each of which apply a transformation to the data passed through them, like sorting, grouping or calculating additional fields.
>Cursors are not supported. The request will return the whole body of the response as an array.
#### Properties
- `pipeline: object[]`: __Required__ - Array containing all the aggregation framework commands for the execution.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#aggregate) for more information. Supported settings are:
- `allowDiskUse: boolean`: Default: `false` - Allow disk use on the MongoDB server to store temporary results for the aggregation.
- `authdb: string`: Specifies the authentication information to be used.
- `batchSize: number`: The number of documents to return per batch.
- `bsonRegExp: boolean`: Return the BSON regular expressions as BSONRegExp instances.
- `bypassDocumentValidation: boolean`: Default: `false` - Allow driver to bypass schema validation in MongoDB 3.2 or higher.
- `checkKeys: boolean`: The serializer will check if keys are valid.
- `collation: object`: Specify collation (MongoDB 3.4 or higher) settings for update operation.
- `comment: string`: Add a [comment](https://docs.mongodb.com/manual/reference/operator/query/comment/index.html) to the aggregation. These comments are visible in the MongoDB profile log, making them easier to interpret.
- `dbName: string`: The database name.
- `explain: boolean`: Specifies to return the information on the processing of the pipeline.
- `fullResponse: boolean`: Return the full server response for the command.
- `hint: string | object`: Add an index selection hint to an aggregation command.
- `ignoreUndefined: boolean`: Default: `true` - Serialize will not emit undefined fields.
- `let: object`: Specifies an object with a list of variables. This allows you to improve command readability by separating the variables from the query text.
- `maxAwaitTimeMS: number`: The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query.
- `maxTimeMS: number`: Specifies a cumulative time limit in milliseconds for processing operations on the cursor.
- `noResponse: boolean`: Admin command option.
- `readConcern: object`: Specifies the level of isolation for read operations.
- `readPreference: string | object`: The read preference.
- `retryWrites: boolean`: Should retry failed writes.
- `serializeFunctions: boolean`: Default: `false` - Serialize the javascript functions.
- `willRetryWrites: boolean`: Option whether to retry writes.
- `writeConcern: object`: An object that expresses the write concern to use with the $out or $merge stage.
#### Examples
###### Calculate average score by region:
```yaml
requests:
- id: avg_spend_by_region
type: MongoDBAggregation
connectionId: my_mongodb_collection_id
properties:
pipeline:
- $group:
_id: $region
score:
$avg: $score
- $project:
_id: 0
region: $_id
score: 1
- $sort:
score: 1
```
### MongoDBBulkWrite
The `MongoDBBulkWrite` request executes [bulkWrite operations](https://www.mongodb.com/docs/manual/reference/method/db.collection.bulkWrite/#write-operations) in the collection specified in the connectionId.
#### Properties
- `operations: object[]`: __Required__ - Array containing all the bulkWrite operations for the execution.
- `insertOne: object`:
- `document: object`: The document to be inserted.
- `deleteOne: object`:
- `filter: object`: __Required__ - The filter used to select the document to delete.
- `collation: object`: Specify collation settings for update operation.
- `deleteMany: object`:
- `filter: object`: __Required__ - The filter used to select the documents to delete.
- `collation: object`: Specify collation settings for update operation.
- `updateOne: object`:
- `filter: object`: __Required__ - The filter used to select the document to update.
- `update: object | object[]`: __Required__ - The update operations to be applied to the document.
- `upsert: object`: Insert document if no match is found.
- `arrayFilters: string[]`: Array filters for the [`$[]`](https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/) array update operator.
- `collation: object`: Specify collation settings for update operation.
- `hint: object | string`: 'An optional hint for query optimization.'
- `updateMany: object`:
- `filter: object`: __Required__ - The filter used to select the documents to update.
- `update: object | object[]`: __Required__ - The update operations to be applied to the documents.
- `upsert: object`: Insert document if no match is found.
- `arrayFilters: string[]`: Array filters for the [`$[]`](https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/) array update operator.
- `collation: object`: Specify collation settings for update operation.
- `hint: object | string`: An optional hint for query optimization.
- `replaceOne: object`:
- `filter: object`: __Required__ - The filter used to select the document to replace.
- `replacement: object`: __Required__ - The document to be inserted.
- `upsert: object`: Insert document if no match is found.
- `collation: object`: Specify collation settings for update operation.
- `hint: object | string`: An optional hint for query optimization.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#aggregate) for more information. Supported settings are:
- `ordered: boolean`: Default: `true` - A boolean specifying whether the mongod instance should perform an ordered or unordered operation execution.
- `writeConcern: object`: An object that expresses the write concern to use.
#### Examples
###### Update pizzas:
```yaml
requests:
- id: update_pizzas
type: MongoDBBulkWrite
connectionId: my_mongodb_collection_id
properties:
operations:
- insertOne:
document:
_id: 3
type: "beef"
size: "medium"
price: 6
- insertOne:
document:
_id: 4
type: "sausage"
size: "large"
price: 10
- updateOne:
filter:
type: "cheese"
update:
$set:
price: 8
- deleteOne:
filter:
type: "pepperoni"
- replaceOne:
filter:
type: "vegan"
replacement:
type: "tofu"
size: "small"
price: 4
```
### MongoDBDeleteMany
The `MongoDBDeleteMany` request deletes multiple documents in the collection specified in the connectionId. It requires a filter, which is written in the query syntax, to select a documents to delete.
#### Properties
- `filter: object`: __Required__ - The filter used to select the document to update.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#deletemany) for more information. Supported settings are:
- `authdb: string`: Specifies the authentication information to be used.
- `bsonRegExp: boolean`: Return the BSON regular expressions as BSONRegExp instances.
- `checkKeys: boolean`: Default: `false` - If true, will throw if bson documents start with $ or include a . in any key value.
- `collation: object`: Specify collation (MongoDB 3.4 or higher) settings for update operation.
- `comment: string`: A user-provided comment to attach to this command.
- `dbName: string`: The database name.
- `explain: boolean`: Specifies the verbosity mode for the explain output.
- `fullResponse: boolean`: Return the full server response for the command.
- `hint: string | object`: An optional hint for query optimization.
- `ignoreUndefined: boolean`: Default: `false` - Specify if the BSON serializer should ignore undefined fields.
- `let: object`: Map of parameter names and values that can be accessed using `$$var` (requires MongoDB 5.0).
- `maxTimeMS: number`: Specifies a cumulative time limit in milliseconds for processing operations on the cursor.
- `noResponse: boolean`: Admin command option.
- `ordered: boolean`: If true, when an insert fails, don't execute the remaining writes. If false, continue with remaining inserts when one fails.
- `readConcern: object`: Specify a read concern and level for the collection. (only MongoDB 3.2 or higher supported).
- `readPreference: string | object`: The read preference.
- `retryWrites: boolean`: Should retry failed writes.
- `serializeFunctions: boolean`: Default: `false` - Serialize the javascript functions.
- `willRetryWrites: boolean`: Option whether to retry writes.
- `writeConcern: object`: An object that expresses the write concern.
#### Examples
###### Delete all documents older than a specific date:
```yaml
requests:
- id: delete_old_documents
type: MongoDBDeleteMany
connectionId: my_mongodb_collection_id
properties:
filter:
created_date:
$lt:
_date: 2020-01-01
```
### MongoDBDeleteOne
The `MongoDBDeleteOne` request deletes a single document in the collection specified in the connectionId. It requires a filter, which is written in the query syntax, to select a document to delete. It will delete the first document that matches the filter.
> When the connection has a log collection, a findOneAndDelete operation is performed instead of the standard deleteOne operation so the deleted document can be captured in the change log. The response shape is the same in both cases.
#### Properties
- `filter: object`: __Required__ - The filter used to select the document to update.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#deleteone) for more information. Supported settings are:
- `authdb: string`: Specifies the authentication information to be used.
- `bsonRegExp: boolean`: Return the BSON regular expressions as BSONRegExp instances.
- `checkKeys: boolean`: Default: `false` - If true, will throw if bson documents start with $ or include a . in any key value.
- `collation: object`: Specify collation (MongoDB 3.4 or higher) settings for update operation.
- `comment: string`: A user-provided comment to attach to this command.
- `dbName: string`: The database name.
- `explain: boolean`: Specifies the verbosity mode for the explain output.
- `fullResponse: boolean`: Return the full server response for the command.
- `hint: string | object`: An optional hint for query optimization.
- `ignoreUndefined: boolean`: Default: `false` - Specify if the BSON serializer should ignore undefined fields.
- `let: object`: Map of parameter names and values that can be accessed using `$$var` (requires MongoDB 5.0).
- `maxTimeMS: number`: Specifies a cumulative time limit in milliseconds for processing operations on the cursor.
- `noResponse: boolean`: Admin command option.
- `ordered: boolean`: If true, when an insert fails, don't execute the remaining writes. If false, continue with remaining inserts when one fails.
- `readConcern: object`: Specify a read concern and level for the collection. (only MongoDB 3.2 or higher supported).
- `readPreference: string | object`: The read preference.
- `retryWrites: boolean`: Should retry failed writes.
- `serializeFunctions: boolean`: Default: `false` - Serialize the javascript functions.
- `willRetryWrites: boolean`: Option whether to retry writes.
- `writeConcern: object`: An object that expresses the write concern.
#### Examples
###### Delete a document by _id:
```yaml
requests:
- id: delete_selected_document
type: MongoDBDeleteOne
connectionId: my_mongodb_collection_id
payload:
selected_id
_state: selected_id
properties:
filter:
_id:
_payload: selected_id
```
### Enrichment run queue
Three requests run the enrichment columns of a `Table`: columns whose cells are computed per row by a provider (an API endpoint of the app) or an AI prompt, from the values of other columns. `MongoDBEnrichmentEnqueue` marks cells queued, `MongoDBEnrichmentClaim` hands a worker a batch of queued cells, and `MongoDBEnrichmentComplete` writes the worker's results. There is no queue collection: each cell's run state is stored in its row, under `_enrich.`, next to the row's data.
```yaml
_enrich:
email: # the column key
status: ok # queued | running | ok | error | empty
value: ada@acme.test # the result the column shows (its field is _enrich.email.value)
raw: { ... } # the provider's response, for the details panel
error: null # the message, with status error (or the last failed attempt, while queued again)
inputHash: 0659b6fcca796a # the hash of the inputs the value was computed from
runId: 66f9… # the enqueue that queued the cell
attempts: 1
claimToken: … # the claim of the worker that ran it
queuedAt, startedAt, finishedAt, leaseUntil
waitingFor: [company] # while queued behind the enrichment columns it reads
```
A cell moves from `queued` to `running` (claimed by a worker, with a lease) to `ok`, `empty` (the provider found nothing) or `error`. A failed attempt goes back to `queued` after a backoff until `maxAttempts`. While a cell is queued or running again, its previous `value`, `raw` and `inputHash` stay, so the table keeps showing the old value until a new result lands.
The three requests take the table's columns as `columnDefs`, the declared and user-defined columns merged, as the app passes them to the `Table` (a Table columns list can be passed as it is). Enrichment and ai columns run; other columns are only looked up by key:
```yaml
- key: email
kind: enrichment # or ai
provider: finder # the worker calls the endpoint enrich_finder; ai columns default to ai
inputs:
domain: { column: domain } # another column's value; required unless required: false
country: { value: ZA } # a literal value
autoRun: true # run when an input column completes
- key: pitch
kind: ai # provider defaults to ai (the enrich_ai endpoint)
prompt: Write a two line pitch for {{ name }}
inputs:
name: { column: name } # list every column the prompt uses
email: { column: email } # an enrichment column: its value, once its cell is ok
output: { type: tag, options: [Hot, Warm, Cold] } # text, number, boolean, tag or tags
```
>Read the columns on the server, never from the browser. A request payload is whatever the browser sends: an endpoint that passes `_payload: columnDefs` to these requests lets any user run any column config (another provider, other inputs, another prompt) against the rows the filter allows. Build `columnDefs` in the endpoint from your declared columns and the stored user columns, as the examples below do, and check user columns when they are saved.
>AI prompts and formula templates are user content: they only take `{{ column }}` placeholders, filled in as plain text. Never render a prompt with a template engine (`_nunjucks` or a `_js` template) on the server: a template can run code. The `Table` refuses prompts and formulas with tags (`{% %}`), comments (`{# #}`) or expressions (`{{ a | upper }}`); check the same when you save a user column.
A `{ column }` input reads another enrichment or ai column's value (only when that cell is `ok`; while it is queued or running, the cell waits for it: it is queued with `waitingFor`, out of claims until that cell finishes), or a field of `fields`, the table's `MongoDBTableQuery` fields keyed by column key, at its `path`. A column outside both is refused, so a user-defined column can never send a field the table does not list to a provider. A required input that is `null`, missing or `''` sets the cell to `empty` with `error: Missing input: ` instead of running it. A chain of inputs that comes back to a column is refused, since `autoRun` would run it forever.
The browser never sends MongoDB syntax, and the requests only ever write the cell properties above, under `_enrich.` of an enrichment or ai column of `columnDefs` (column keys are 1 to 128 letters, digits, `_` or `-`). Every read and write is scoped by the base `filter` (required unless the connection is tenant-scoped; `filter: {}` for every document) and, on a tenant connection, by the tenant; the `filter` may not name `_enrich`. No request runs JavaScript on the database server.
##### Input hash
`inputHash` is the hash of a cell's inputs, `{ [param]: value }` with optional inputs that have no value left out: [cyrb53](https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js) (seed 0) of the canonical JSON of the inputs, as 14 lowercase hex digits. The canonical JSON has object keys sorted at every depth, no whitespace, dates as ISO strings, ObjectIds as hex strings and undefined values left out. The `Table` computes the same hash in the browser, so a cell whose row's inputs changed since its value was computed shows as stale, and `mode: stale` re-runs exactly those cells. A claim hashes the inputs it gives the worker, and the result is stored with that hash.
##### Columns and fields on the server
Every endpoint that runs these requests reads the table's columns itself, with a request or step (declared columns merged with the stored user columns), and builds `fields` the same way: the declared `MongoDBTableQuery` fields, plus one field per user-defined input column. The recommended layout keeps what users type under `values.` (set the Table's `inputFieldPrefix: values`), so a user column can never name, read or write another field of the row:
```yaml
# leads/load_table.yaml, referenced by every enrichment endpoint
- id: load_columns
type: MongoDBAggregation
connectionId: table_columns
properties:
pipeline:
- $match: { tableId: leads }
- $sort: { position: 1 }
- :set_state:
columnDefs:
_array.concat:
- _ref: leads/columns.yaml # the declared columns
- _step: load_columns # the user columns, as stored
fields:
_js:
fn: |
const fields = { ...args.declared };
args.columns
.filter((column) => column.userDefined === true && column.kind === 'input')
.forEach((column) => {
fields[column.key] = { type: column.type ?? 'text', path: `values.${column.key}` };
});
return fields;
args:
declared:
_ref: leads/fields.yaml # the declared MongoDBTableQuery fields
columns:
_step: load_columns
```
`columnDefs` and `fields` may come from any operator (`_state`, `_step`, `_payload` for data you checked); the requests validate them each time they run.
##### The worker
The worker is an API endpoint: it claims a batch of cells, calls each cell's provider endpoint with `:parallel_for` (`:concurrency` limits how many run at once), and completes each cell. Complete queues the `autoRun` columns a completed cell feeds (a waterfall between columns) and releases the cells waiting for it, so a later round runs them. It loops until a claim returns nothing, or for at most ten rounds. A schedule runs it every minute, and the endpoint that enqueues a run starts it at once with a detached call. A worker that crashes loses nothing: its cells are claimed again when their lease runs out, and a result from a worker whose lease ran out is ignored.
```yaml
api:
- id: enrichment_worker
type: InternalApi
schedules:
- cron: '* * * * *'
routine:
- _ref: leads/load_table.yaml # columnDefs and fields, read on the server
- :set_state:
claimed: 1
rounds: 0
- :while:
_and:
- _gt: [{ _state: claimed }, 0]
- _lt: [{ _state: rounds }, 10]
:do:
- id: claim
type: MongoDBEnrichmentClaim
connectionId: leads
properties:
filter: {} # cells were scoped when they were queued
fields:
_state: fields
columnDefs:
_state: columnDefs
limit: 20
- :parallel_for: cell
:in:
_step: claim
:concurrency: 5 # at most five provider calls at once
:do:
- :try:
- id: call_provider
type: CallApi
properties:
endpointId:
_string.concat: [enrich_, { _item: cell.provider }]
payload:
inputs:
_item: cell.inputs
prompt:
_item: cell.prompt # ai columns
output:
_item: cell.output # the column's output config
- id: complete
type: MongoDBEnrichmentComplete
connectionId: leads
properties:
filter: {}
columnDefs:
_state: columnDefs
results:
# The claim's cell, with the provider's answer merged in:
# { status, value, raw } or { status, error, retry }.
- _object.assign:
- rowKey:
_item: cell.rowKey
columnKey:
_item: cell.columnKey
claimToken:
_item: cell.claimToken
- _step: call_provider.$
:catch:
- id: complete_error
type: MongoDBEnrichmentComplete
connectionId: leads
properties:
filter: {}
columnDefs:
_state: columnDefs
results:
- rowKey:
_item: cell.rowKey
columnKey:
_item: cell.columnKey
claimToken:
_item: cell.claimToken
status: error
error:
_error: message
- :set_state:
claimed:
_array.length:
_step: claim
rounds:
_sum: [{ _state: rounds }, 1]
```
A request or service error a `:catch` handles is logged at debug, so a provider that fails on purpose (a 404 in a waterfall) does not fill the log with errors. Config, operator and internal errors are still logged as errors, with their config location, even when a `:catch` handles them.
Each provider endpoint `enrich_` takes `{ inputs, prompt, output }` and returns `{ status: ok | empty, value, raw }`, or `{ status: error, error, retry: false }` for a final failure; throwing is a failed attempt that is retried. `null` for `error` or `retry` (what `_step` gives for a key the provider did not return) is the same as leaving it out. The app declares these endpoints, so a column can only call what the app exposes, and API keys stay on the server. For a concurrency per provider, group the claimed cells by `provider` and run each group with its own `:concurrency`, or run a worker per provider with `providers` on the claim.
The AI provider (`enrich_ai`) fills the prompt's `{{ input }}` and `{{ input.path }}` placeholders (a dot path reads into the input's value, the pattern the Table accepts) with the cell's inputs by plain string replacement, in one pass, so a row value that looks like a template stays text, and asks the model for an answer of the column's `output.type`.
The endpoint the table's run events call queues the cells, then starts the worker without waiting for it (a detached call needs the `CRON_SECRET` environment variable):
```yaml
api:
- id: run_enrichment
type: Api
routine:
- _ref: leads/load_table.yaml
- id: enqueue
type: MongoDBEnrichmentEnqueue
connectionId: leads
properties:
filter:
org_id:
_user: organization.id
fields:
_state: fields
columnDefs:
_state: columnDefs # read on the server, never _payload
columns:
_payload: columns
mode:
_payload: mode
selection:
_payload: selection
user:
_user: true
- id: start_worker
type: CallApi
properties:
endpointId: enrichment_worker
detached: true
- :return:
_step: enqueue
```
A claim reads the oldest due cells of each column. On a large table, index each enrichment column's queue fields, for example `{ "_enrich.email.status": 1, "_enrich.email.queuedAt": 1 }`, with the base filter fields first when every run is scoped by them.
### MongoDBEnrichmentClaim
The `MongoDBEnrichmentClaim` request claims up to `limit` enrichment cells for a worker: the oldest cells that are queued and due (`queuedAt` passed, so a retry waits out its backoff), and running cells whose lease ran out. Each claimed cell is set to `running` with `startedAt`, `leaseUntil` (now plus `leaseMs`), `attempts` plus one and a new random `claimToken`. See [Enrichment run queue](#enrichment-run-queue).
Each claim carries the column config the worker needs (`kind`, `title`, `provider`, `prompt`, `output`), so the worker never looks the column up again.
Concurrent workers never claim the same cell. Every claim is a compare-and-set: the write matches the cell only in the state the claim read (its status, token, attempts and run) and while it is still claimable, so when two workers read the same cell, only the first write changes it. A worker that lost cells to another reads further candidates, up to five rounds, so it does not stop while cells are still queued.
A claim also settles cells it can not hand out: a cell whose required input is now missing is set to `empty` with the missing column named, a cell whose enrichment input is queued or running again waits for it (queued with `waitingFor`, released when that input finishes), and a running cell whose lease ran out on its last attempt (`maxAttempts`) becomes an `error`. A cell a claim sets to `empty` or `error` releases the cells waiting for it, as a final result does.
##### Response
```yaml
- rowKey: 66f9… # the row key (rowKeyField)
columnKey: email
kind: enrichment # or ai
title: Email # when the column has one
provider: finder # ai columns: ai unless they name another
prompt: … # ai columns
output: email # when set: the enrichment result path, or the ai answer's { type, options? }
runId: 66f9…
claimToken: 3b1f…:0659b6fcca796a
attempt: 1
inputHash: 0659b6fcca796a
inputs: # resolved from columnDefs
domain: acme.test
row: # _id, the row key and the fields paths only
_id: …
name: Acme
domain: acme.test
```
#### Properties
- `columnDefs: object[]`: __Required__ - The table columns, declared and user-defined merged. See [Enrichment run queue](#enrichment-run-queue).
- `fields: object`: __Required__ - The table's `MongoDBTableQuery` fields, keyed by column key: the fields column inputs read and claimed rows return.
- `columns: string[]`: Claim only cells of these enrichment or ai columns. Defaults to every enrichment and ai column.
- `providers: string[]`: Claim only cells of columns that use these providers, for a worker per provider.
- `filter: object`: The base filter every read and write is scoped by. Required unless the connection is tenant-scoped. Set it to `{}` to claim cells of every document.
- `limit: integer`: Default: `20` - The most cells one claim returns, at most 200.
- `leaseMs: integer`: Default: `120000` - How long a claimed cell stays with its worker. After it, the cell can be claimed again, and the first worker's result is ignored. Keep it longer than a provider call, and keep the servers' clocks in sync.
- `maxAttempts: integer`: Default: `3` - A cell whose lease ran out on this attempt becomes an error instead of being claimed again. Use the same value as `MongoDBEnrichmentComplete`.
- `rowKeyField: string`: Default: `_id` - The document field returned as `rowKey`.
### MongoDBEnrichmentComplete
The `MongoDBEnrichmentComplete` request writes a worker's results to the cells it claimed. A result is applied only while its cell still holds the claim, its `claimToken` with status `running`, so a worker whose lease ran out (and whose cell was claimed again or queued again since) changes nothing, and a result sent twice is applied once. See [Enrichment run queue](#enrichment-run-queue).
- `ok` and `empty` results replace the cell's `value` and `raw` (an empty result has no value), and store `finishedAt` and the `inputHash` of the inputs the claim gave the worker.
- An `error` below `maxAttempts` goes back to `queued` with its error message, due after `backoffMs * 2^(attempt - 1)` (30 seconds, then 60, …, at most a day), or after the result's `retryAfterMs` when the provider said how long to wait (a rate limit's `Retry-After`). On the last attempt, or with `retry: false`, the error is final. The previous value stays in both cases.
- A final result (`ok`, `empty`, or an error that is not retried) releases the cells of the row waiting for it (`waitingFor`), so they are claimed next; one whose input failed then finds it missing.
- An `ok` result queues the `autoRun` columns that read the column, in its row, unless they are queued or running already.
- A `raw` larger than `rawMaxBytes` is stored as `{ _truncated: true, bytes, maxBytes, preview }`, with the first 1000 characters of its JSON, so one large response can not fill the row. A `value` larger than `rawMaxBytes` makes the result a final error.
##### Response
```yaml
applied: 18 # results written
ignored: 2 # results whose claim no cell holds any more
requeued: 1 # errors queued again for a retry
released: 4 # waiting cells released by the results
downstream: # autoRun columns that read a column that just completed ok, now queued
- rowKey: 66f9…
columns: [pitch]
```
The `downstream` columns are already queued: the worker's next claim runs them.
#### Properties
- `results: object[]`: __Required__ - At most 1000 results, each:
- `rowKey: any`: __Required__ - The `rowKey` of the claim.
- `columnKey: string`: __Required__ - The `columnKey` of the claim.
- `claimToken: string`: __Required__ - The `claimToken` of the claim.
- `status: enum`: __Required__ - `ok`, `empty` (no result) or `error`.
- `value: any`: The result the column shows.
- `raw: any`: The provider's response.
- `cost: integer`: What the provider call behind the result cost, in micro-USD, such as a [`TregCall`](/Treg) `cost.micro`. Stored as the cell's `cost` with any status; a result without a cost leaves the cell's cost as it was.
- `error: string | null`: The error message, with status `error`. `null` is the same as leaving it out.
- `retry: boolean | null`: Default: `true` - With status `error`, `false` makes the error final. `null` is the same as leaving it out.
- `retryAfterMs: integer | null`: With status `error` below `maxAttempts`, the wait before the cell is claimed again, in place of the exponential backoff, at most a day. A worker passes a `ServiceError`'s `retryAfter` (seconds, such as a [`TregCall`](/Treg) 429 or 503) times 1000. `null` is the same as leaving it out.
- `columnDefs: object[]`: __Required__ - The table columns, declared and user-defined merged.
- `filter: object`: The base filter every read and write is scoped by. Required unless the connection is tenant-scoped.
- `maxAttempts: integer`: Default: `3` - The attempts a cell gets.
- `backoffMs: integer`: Default: `30000` - The wait before a failed cell is claimed again, doubled per attempt made.
- `rawMaxBytes: integer`: Default: `65536` - The largest raw response (BSON bytes) stored as it is.
- `rowKeyField: string`: Default: `_id` - The document field a row key matches.
- `rowKeyType: enum`: Default: `auto` - How row keys are read, as for `MongoDBTableChanges`.
### MongoDBEnrichmentEnqueue
The `MongoDBEnrichmentEnqueue` request queues cells of enrichment columns: the cells of `columns` in the selected rows that `mode` names. See [Enrichment run queue](#enrichment-run-queue).
- `all`: every cell that is not queued, or running with a live lease. A run in progress is never restarted, whatever the mode.
- `empty`: cells never run, or whose last result was empty.
- `errors`: cells that failed.
- `stale`: cells with a result whose inputs changed since it was computed. The request reads each candidate row's inputs (in batches of 1000 rows, with only the input paths projected) and compares their hash with the cell's `inputHash`.
A queued cell gets `status: queued`, the `runId`, `queuedAt` and `attempts: 0`; its previous value, raw and inputHash stay until a new result lands. A cell whose required input has no value is set to `empty` with `error: Missing input: ` instead, and its previous result is cleared.
Columns can run together with the columns they read: the request plans them upstream first, and a cell whose required enrichment input is queued in the same call (or is queued or running already) is queued with `waitingFor: []`, out of claims until that input finishes, never `Missing input`. So one call can run `[email, pitch]` where the pitch reads the email.
`selection` is the table's `selected` value: row keys, or `{ all: true, except, filter, search }`, compiled against `fields` like `MongoDBTableChanges` compiles it, with the same limits. Leave it out to run every row inside the base `filter`. Row keys are read as in `MongoDBTableChanges` Row keys: an ObjectId as `{ _oid }` or its Table key text, and a numeric key as the number or its text.
The cells are written as unordered bulkWrites of 1000 cells, each write guarded by the mode's condition, so a cell a worker took since it was read is left alone. When more than `maxCells` cells would be written, nothing is written and the request throws, so a large run can be confirmed first.
##### Response
```yaml
queued: 2400 # cells queued, those waiting for an input column included
skipped: 12 # selected cells the mode left alone (live, fresh or not matching)
missingInputs: 3 # cells set to empty for a missing input
byColumn: # the same counts for each column run, summing to the totals
email: { queued: 1200, missingInputs: 3 }
pitch: { queued: 1200, missingInputs: 0 }
runId: 66f9…
```
##### Dry run
With `dryRun: true` the request reads and plans exactly as a run does (the same selection, mode, `maxCells`, `maxTimeMS` and tenant scope) and returns the counts the run would write, writing no cell and no change log record. The response is `{ dryRun: true, queued, missingInputs, skipped, byColumn }`, with no `runId`. Over `maxCells` it throws as a run would, so an app learns a run is too large before it asks.
Use it to confirm a run that costs money before it starts: in the run event, call the request with `dryRun: true`, show a confirm with each column's `queued` count times that column's provider cost, and on a yes call it again without `dryRun`. Cells can change between the two calls, so the run's own response, whose `byColumn` has the same shape, says what was queued.
#### Properties
- `columns: string[]`: __Required__ - The keys of the enrichment or ai columns to run.
- `columnDefs: object[]`: __Required__ - The table columns, declared and user-defined merged.
- `fields: object`: __Required__ - The table's `MongoDBTableQuery` fields, keyed by column key: the fields column inputs read and a select-all selection is compiled against.
- `selection: object | any[]`: The rows to run, the `Table` `selected` value. Defaults to every row inside `filter`.
- `mode: enum`: Default: `all` - `all`, `empty`, `errors` or `stale`.
- `filter: object`: The base filter every read and write is scoped by, for example `{ org_id: { _user: organization.id } }`. Required unless the connection is tenant-scoped. Set it to `{}` to run on every document.
- `maxCells: integer`: Default: `10000` - The most cells one enqueue may write, queued and missing input cells together.
- `maxTimeMS: integer`: Default: `30000` - The time limit of each read.
- `dryRun: boolean`: Default: `false` - Count the cells the run would queue and set empty, by column, and write nothing. See [Dry run](#dry-run).
- `runId: string`: The `runId` the queued cells get, 1 to 64 letters, digits, `_` or `-`. Generated when left out.
- `user: object`: The user that `{ $user: path }` values in a selection filter resolve from. Set it to `{ _user: true }`.
- `timezone: string`: Default: `UTC` - The IANA time zone whose days the date filters of a selection compare.
- `rowKeyField: string`: Default: `_id` - The document field a row key matches.
- `rowKeyType: enum`: Default: `auto` - How row keys are read, as for `MongoDBTableChanges`.
### MongoDBFind
The `MongoDBFind` request executes a MongoDB [query](https://docs.mongodb.com/manual/tutorial/query-documents/) on the collection specified in the connectionId. It returns the array of documents returned by the query.
>Cursors are not supported. The request will return the whole body of the response as an array.
#### Properties
- `query: object`: __Required__ - A MongoDB query object.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#find) for more information. Supported settings are:
- `allowDiskUse: boolean`: Allows disk use for blocking sort operations exceeding 100MB memory. (MongoDB 3.2 or higher)
- `allowPartialResults: boolean`: For queries against a sharded collection, allows the command (or subsequent getMore commands) to return partial results, rather than an error, if one or more queried shards are available.
- `authdb: string`: Specifies the authentication information to be used.
- `awaitData: boolean`: Specify if the cursor is a tailable-await cursor. Requires `tailable` to be true.
- `batchSize: number`: Set the batchSize for the getMoreCommand when iterating over the query results.
- `bsonRegExp: boolean`: Return the BSON regular expressions as BSONRegExp instances.
- `checkKeys: boolean`: The serializer will check if keys are valid.
- `collation: object`: Specify collation (MongoDB 3.4 or higher) settings for update operation.
- `comment: string | object`: Add a [comment](https://docs.mongodb.com/manual/reference/operator/query/comment/index.html) to the query. These comments are visible in the MongoDB profile log, making them easier to interpret.
- `dbName: string`: The database name.
- `explain: boolean`: Specifies the verbosity mode for the explain output.
- `fullResponse: boolean`: Return the full server response for the command.
- `hint: string | object`: Tell the query to use specific indexes in the query. Object of indexes to use, `{'_id':1}`.
- `ignoreUndefined: boolean`: Default: `true` - Serialize will not emit undefined fields.
- `let: object`: Map of parameter names and values that can be accessed using `$$var` (requires MongoDB 5.0).
- `limit: number`: Sets the limit of documents returned in the query.
- `max: object`: The exclusive upper bound for a specific index.
- `maxAwaitTimeMS: number`: The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Requires `tailable` and `awaitData` to be true.
- `maxTimeMS: number`: Number of milliseconds to wait before aborting the command.
- `min: object`: The inclusive lower bound for a specific index.
- `noCursorTimeout: boolean`: The server normally times out idle cursors after an inactivity period (10 minutes) to prevent excess memory use. Set this option to prevent that.
- `noResponse: boolean`: Admin command option.
- `projection: object`: The fields to return in the query. Object of fields to either include or exclude (one of, not both), `{'a':1, 'b': 1}` or `{'a': 0, 'b': 0}`.
- `readConcern: object`: Specify a read concern and level for the collection. (only MongoDB 3.2 or higher supported).
- `readPreference: string | object`: The preferred read preference.
- `retryWrites: boolean`: Should retry failed writes.
- `returnKey: boolean`: If true, returns only the index keys in the resulting documents.
- `serializeFunctions: boolean`: Default: `false` - Serialize the javascript functions.
- `showRecordId: boolean`: Determine whether to return the record identifier for each document. If true, adds a field $recordId to the returned documents.
- `singleBatch: boolean`: Default: `false` - Determines whether to close the cursor after the first batch.
- `skip: number`: Set to skip N documents ahead in your query (useful for pagination).
- `sort: array | object`: Set to sort the documents coming back from the query.
- `tailable: boolean`: Specify if the cursor is tailable.
- `timeout: boolean`: Specify if the cursor can timeout.
- `willRetryWrites: boolean`: Option whether to retry writes.
- `writeConcern: object`: An object that expresses the write concern.
#### Examples
###### Find top ten scores above 90:
```yaml
requests:
- id: scores_top_ten_scores_above_90
type: MongoDBFind
connectionId: my_mongodb_collection_id
properties:
query:
score:
$gt: 90
options:
sort:
- - score
- -1
limit: 10
projection:
score: 1
name: 1
```
### MongoDBFindOne
The `MongoDBFindOne` request executes a MongoDB [query](https://docs.mongodb.com/manual/tutorial/query-documents/) on the collection specified in the connectionId. It returns the first document that matches the specified query.
>Cursors are not supported. The request will return the whole body of the response as an array.
#### Properties
- `query: object`: __Required__ - A MongoDB query object.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#findone) for more information. Supported settings are:
- `allowDiskUse: boolean`: Allows disk use for blocking sort operations exceeding 100MB memory. (MongoDB 3.2 or higher)
- `allowPartialResults: boolean`: For queries against a sharded collection, allows the command (or subsequent getMore commands) to return partial results, rather than an error, if one or more queried shards are available.
- `authdb: string`: Specifies the authentication information to be used.
- `awaitData: boolean`: Specify if the cursor is a tailable-await cursor. Requires `tailable` to be true.
- `batchSize: number`: Set the batchSize for the getMoreCommand when iterating over the query results.
- `bsonRegExp: boolean`: Return the BSON regular expressions as BSONRegExp instances.
- `checkKeys: boolean`: The serializer will check if keys are valid.
- `collation: object`: Specify collation (MongoDB 3.4 or higher) settings for update operation.
- `comment: string | object`: Add a [comment](https://docs.mongodb.com/manual/reference/operator/query/comment/index.html) to the query. These comments are visible in the MongoDB profile log, making them easier to interpret.
- `dbName: string`: The database name.
- `explain: boolean`: Specifies the verbosity mode for the explain output.
- `fullResponse: boolean`: Return the full server response for the command.
- `hint: string | object`: Tell the query to use specific indexes in the query. Object of indexes to use, `{'_id':1}`.
- `ignoreUndefined: boolean`: Default: `true` - Serialize will not emit undefined fields.
- `let: object`: Map of parameter names and values that can be accessed using `$$var` (requires MongoDB 5.0).
- `limit: number`: Sets the limit of documents returned in the query.
- `max: object`: The exclusive upper bound for a specific index.
- `maxAwaitTimeMS: number`: The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Requires `tailable` and `awaitData` to be true.
- `maxTimeMS: number`: Number of milliseconds to wait before aborting the command.
- `min: object`: The inclusive lower bound for a specific index.
- `noCursorTimeout: boolean`: The server normally times out idle cursors after an inactivity period (10 minutes) to prevent excess memory use. Set this option to prevent that.
- `noResponse: boolean`: Admin command option.
- `projection: object`: The fields to return in the query. Object of fields to either include or exclude (one of, not both), `{'a':1, 'b': 1}` or `{'a': 0, 'b': 0}`.
- `readConcern: object`: Specify a read concern and level for the collection. (only MongoDB 3.2 or higher supported).
- `readPreference: string | object`: The preferred read preference.
- `retryWrites: boolean`: Should retry failed writes.
- `returnKey: boolean`: If true, returns only the index keys in the resulting documents.
- `serializeFunctions: boolean`: Default: `false` - Serialize the javascript functions.
- `showRecordId: boolean`: Determine whether to return the record identifier for each document. If true, adds a field $recordId to the returned documents.
- `singleBatch: boolean`: Default: `false` - Determines whether to close the cursor after the first batch.
- `skip: number`: Set to skip N documents ahead in your query (useful for pagination).
- `sort: array | object`: Set to sort the documents coming back from the query.
- `tailable: boolean`: Specify if the cursor is tailable.
- `timeout: boolean`: Specify if the cursor can timeout.
- `willRetryWrites: boolean`: Option whether to retry writes.
- `writeConcern: object`: An object that expresses the write concern.
#### Examples
###### Find a document by id:
```yaml
requests:
- id: find_by_id
type: MongoDBFindOne
connectionId: my_mongodb_collection_id
payload:
_id:
_input: _id
properties:
query:
_id:
_payload: _id
```
### MongoDBInsertConsecutiveId
The `MongoDBInsertConsecutiveId` request inserts a single document into the collection specified in the connectionId, assigning a sequential, human-readable `_id` like `INV0001`. The id is built from a prefix and the next consecutive number for that prefix, zero-padded to `length` digits. The id read and the insert run inside a transaction so concurrent requests cannot claim the same id.
> Transactions require MongoDB to run as a replica set. Standalone deployments are not supported by this request.
#### Properties
- `doc: object`: __Required__ - The document to be inserted. The `_id` is assigned by the request.
- `prefix: string`: __Required__ - Prefix to add to the id, for example `INV`.
- `length: number`: The numeric part of the id is zero-padded to this number of digits. If omitted, the number is not padded.
- `options: object`: Optional settings passed to the insert. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#insertone) for more information.
#### Examples
###### Insert an invoice with a sequential id (INV0001, INV0002, ...):
```yaml
requests:
- id: insert_invoice
type: MongoDBInsertConsecutiveId
connectionId: my_mongodb_collection_id
properties:
prefix: INV
length: 4
doc:
amount:
_state: amount
```
### MongoDBInsertMany
The `MongoDBInsertMany` request inserts an array of documents into the collection specified in the connectionId. If a `_id` field is not specified on a document, a MongoDB `ObjectID` will be generated.
#### Properties
- `docs: object[]`: __Required__ - The array of documents to be inserted.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#insertmany) for more information. Supported settings are:
- `authdb: string`: Specifies the authentication information to be used.
- `bsonRegExp: boolean`: Return the BSON regular expressions as BSONRegExp instances.
- `bypassDocumentValidation: boolean`: Default: `false` - Allow driver to bypass schema validation in MongoDB 3.2 or higher
- `checkKeys: boolean`: Default: `true` - If true, will throw if bson documents start with $ or include a . in any key value.
- `collation: object`: Specify collation (MongoDB 3.4 or higher) settings for update operation.
- `comment: string | object`: Add a [comment](https://docs.mongodb.com/manual/reference/operator/query/comment/index.html) to the query. These comments are visible in the MongoDB profile log, making them easier to interpret.
- `dbName: string`: The database name.
- `explain: object`: Specifies the verbosity mode for the explain output.
- `forcesServerObjectId: boolean`: Default: `false` - Force server to assign _id values instead of driver.
- `fullResponse: boolean`: Return the full server response for the command.
- `ignoreUndefined: boolean`: Default: `false` - Specify if the BSON serializer should ignore undefined fields.
- `maxTimeMS: number`: Number of milliseconds to wait before aborting the command.
- `noResponse: boolean`: Admin command option.
- `ordered: boolean`: If true, when an insert fails, don't execute the remaining writes. If false, continue with remaining inserts when one fails.
- `readConcern: object`: Specify a read concern and level for the collection. (only MongoDB 3.2 or higher supported).
- `readPreference: object`: The preferred read preference.
- `retryWrites: boolean`: Should retry failed writes.
- `serializeFunctions: boolean`: Default: `false` - Serialize the javascript functions.
- `willRetryWrites: boolean`: Option whether to retry writes.
- `writeConcern: object`: An object that expresses the write concern.
#### Examples
###### Insert a set of documents:
```yaml
requests:
- id: insert_documents
type: MongoDBInsertMany
connectionId: my_mongodb_collection_id
properties:
docs:
- _id: 1
value: 4
- _id: 2
value: 1
- _id: 3
value: 7
```
### MongoDBInsertManyConsecutiveIds
The `MongoDBInsertManyConsecutiveIds` request inserts an array of documents into the collection specified in the connectionId, assigning each document a sequential, human-readable `_id` like `INV0001`. Ids continue from the highest existing id for the prefix. The id read and the insert run inside a transaction so concurrent requests cannot claim the same ids.
> Transactions require MongoDB to run as a replica set. Standalone deployments are not supported by this request.
#### Properties
- `docs: object[]`: __Required__ - The documents to be inserted. The `_id` values are assigned by the request.
- `prefix: string`: __Required__ - Prefix to add to the ids, for example `INV`.
- `length: number`: The numeric part of each id is zero-padded to this number of digits. If omitted, the numbers are not padded.
- `options: object`: Optional settings passed to the insert. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#insertmany) for more information.
#### Examples
###### Insert order lines with sequential ids:
```yaml
requests:
- id: insert_order_lines
type: MongoDBInsertManyConsecutiveIds
connectionId: my_mongodb_collection_id
properties:
prefix: LINE
length: 6
docs:
_state: order_lines
```
### MongoDBInsertOne
The `MongoDBInsertOne` request inserts a document into the collection specified in the connectionId. If a `_id` field is not specified, a MongoDB `ObjectID` will be generated.
#### Properties
- `doc: object`: __Required__ - The document to be inserted.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#insertone) for more information. Supported settings are:
- `authdb: string`: Specifies the authentication information to be used.
- `bsonRegExp: boolean`: Return the BSON regular expressions as BSONRegExp instances.
- `bypassDocumentValidation: boolean`: Default: `false` - Allow driver to bypass schema validation in MongoDB 3.2 or higher
- `checkKeys: boolean`: Default: `true` - If true, will throw if bson documents start with $ or include a . in any key value.
- `collation: object`: Specify collation (MongoDB 3.4 or higher) settings for update operation.
- `comment: string | object`: Add a [comment](https://docs.mongodb.com/manual/reference/operator/query/comment/index.html) to the query. These comments are visible in the MongoDB profile log, making them easier to interpret.
- `dbName: string`: The database name.
- `explain: object`: Specifies the verbosity mode for the explain output.
- `forcesServerObjectId: boolean`: Default: `false` - Force server to assign _id values instead of driver.
- `fullResponse: boolean`: Return the full server response for the command.
- `ignoreUndefined: boolean`: Default: `false` - Specify if the BSON serializer should ignore undefined fields.
- `maxTimeMS: number`: Number of milliseconds to wait before aborting the command.
- `noResponse: boolean`: Admin command option.
- `readConcern: object`: Specify a read concern and level for the collection. (only MongoDB 3.2 or higher supported).
- `readPreference: object`: The preferred read preference.
- `retryWrites: boolean`: Should retry failed writes.
- `serializeFunctions: boolean`: Default: `false` - Serialize the javascript functions.
- `willRetryWrites: boolean`: Option whether to retry writes.
- `writeConcern: object`: An object that expresses the write concern.
#### Examples
###### Insert a document:
```yaml
requests:
- id: insert_new_comment
type: MongoDBInsertOne
connectionId: my_mongodb_collection_id
payload:
comment:
_state: comment_input
properties:
doc:
comment:
_payload: comment
user_id:
_user: id
timestamp:
_date: now
```
### MongoDBTableChanges
The `MongoDBTableChanges` request saves the value of a `TableInput` block. The value of a `TableInput` is not its rows but a changeset: only what changed since `data`. The request validates the changeset against an allowlist of `fields` and compiles it to one `bulkWrite` on the server. The browser never sends MongoDB syntax: keys that are not in `fields`, keys that start with `$` (operators such as `$where`, positional paths such as `items.$[x]`), values of the wrong type, and operator objects such as `{ $ne: null }` as values or row keys are refused before anything is written.
The changeset is the `TableInput` value:
```yaml
updated: # changed fields of existing rows: { [rowKey]: { [field]: value } }
flour:
qty: 450 # the key is the column field, a dot path
details.note: strong
added: # new rows: [{ rowKey, ...fields }]
- rowKey: 3f2c9a61-… # a temporary key the browser generated
ingredient: Yeast
qty: 7
removed: # existing rows to delete: [rowKey]
- salt
moved: # with rowDrag.positionField: { [rowKey]: position }
water: 1536
order: [salt, flour] # with rowDrag and no positionField: every row key in the new order
```
The `fields` keys are the column `field` dot paths, because those are the keys of the changeset, and only those fields can be written (at their `path`). This differs from `MongoDBTableQuery`, whose `fields` are keyed by the column `key`: a `TableInput` column `{ key: owner, field: owner.name }` is `owner.name` here and `owner` (with `path: owner.name`) in `MongoDBTableQuery`. A changeset key that is the `path` of a field keyed otherwise is refused with an error that names the mismatch. Values are coerced to the field type like `MongoDBTableQuery` values: numbers from numeric strings, dates from date strings and timestamps, and `null` clears a value of any type. `avatar`, `image` and `json` fields accept documents, but not with keys that start with `$`.
Every operation is scoped by the base `filter`, for example the organization or owner of the rows. The row key is combined with the filter using `$and`, so it can only narrow it. `filter` is required, unless the connection is tenant-scoped: then the tenant is merged into every operation and stamped on new rows, as for `MongoDBBulkWrite`. Set `filter: {}` to allow writes to every document in the collection.
##### Scope fields
The `filter` and `insertDefaults` fields are the scope of the rows, such as their organization or owner, and the table can never write them:
- A field (or the `positionField`) whose path is a `filter` field, or inside or over one, is refused (with a `filter` on `owner.id`, the fields `owner.id`, `owner` and `owner.id.name` are all refused). Otherwise an update could move a row out of scope. This includes fields named inside `$and`, `$or` and `$nor`.
- A field whose path is set by `insertDefaults`, or inside or over one of its values, is refused, so a new row can not replace a default. A default `{ address: { country: FR } }` still leaves `address.city` writable. For a starting value the user may change, give the `TableInput` column a default instead.
- New rows are stamped with the equality conditions of the `filter`: `{ org_id: X }`, `{ org_id: { $eq: X } }` and the equalities inside `$and`. A row added with a `filter` of `{ org_id: { _user: organization.id } }` belongs to that organization without an `insertDefaults` entry. `insertDefaults` may repeat such a value, but a different value is refused.
- Any other `filter` condition (`$ne`, `$in`, a regex, the clauses of `$or`) can not be stamped. A save that adds rows then needs that field set by `insertDefaults`. A `filter` with an operator such as `$expr` or `$where` refuses added rows. Saves that only update, move or remove rows are not affected.
In array mode the `filter` scopes the document: every operation, the `$push` of new items included, matches only the document with `array.documentId` inside the `filter`. Item fields are compared with the `filter` at their path in the document (`items.`), and new items are not stamped, since they are not documents of the collection.
##### Collection mode
By default every row is a document, matched by `rowKeyField` (default `_id`). The changeset compiles to:
```yaml
- deleteOne: { filter: { $and: [, { _id: }] } } # one per removed row
- updateOne: # one per updated or moved row
filter: { $and: [, { _id: }] }
update: { $set: { qty: 450, details.note: strong, position: 1536 } } # its fields and position in one $set
- insertOne: { document: { , , _id: } } # one per added row
```
An update sets only the changed dot paths, so the rest of the document is kept. A move writes one position field on one row. An `order` needs a `positionField` in collection mode: it writes positions 1024, 2048, … to every row in the order.
##### Array mode
With `array: { documentId, path }`, the rows are the items of an embedded array in one document, such as the ingredients of a recipe. Every operation matches that document inside the base filter, and field paths and `positionField` are paths in the item. MongoDB can not `$set` into, `$pull` from and `$push` to the same array in one update, so the changeset compiles to up to four updates of that document, run in order:
```yaml
- $set: { items.$[r0].qty: 450, items.$[r1].position: 1536 } # arrayFilters: [{ r0._id: flour }, { r1._id: water }]
- $pull: { items: { _id: { $in: [salt] } } }
- $push: { items: { $each: [] } }
- # only for an order without a positionField
```
New items get a generated ObjectId `_id` when `itemKeyField` is `_id`. Without a `positionField`, the array order is the row order, and an `order` is applied by a pipeline update that reorders the items on the server, as the array is when the update runs. Items are moved, never rewritten, so an edit someone else saved to an item in the meantime is kept; items the order does not name (added since the table loaded) follow in their current order, and keys of items that are gone are skipped. Setting the whole array from the browser's copy instead would overwrite such edits.
When the document is not found inside the filter, nothing is written and the request throws.
##### Response
```yaml
matchedCount: 2 # collection mode: rows matched by updates and moves
modifiedCount: 2
insertedCount: 1
deletedCount: 1
insertedKeys: # the key each added row got, by its temporary rowKey
3f2c9a61-…: { _oid: 66f9… }
unmatchedKeys: [] # updated, moved or removed rows that matched nothing
```
In array mode `matchedCount` and `modifiedCount` count the document (0 or 1), `insertedCount` is the items pushed and `deletedCount` the removed items that were in the array.
`unmatchedKeys` lists the existing rows the changeset named that matched nothing: outside the `filter` (another organization's row), deleted by someone else, or never there. Treat a non-empty `unmatchedKeys` as a failed save, for example with a `Throw` action after the request, since nothing was written for those rows. Numeric keys are listed as numbers and ObjectId keys as `{ _oid }`. The rows are found with a read of their keys, scoped like the writes: removed rows are read before the write (a removed row that someone else deletes between that read and the write counts as matched, since it is gone as asked), and updated rows after it, only when fewer rows matched than were updated. A save that only updates rows that all match is one round trip.
The operations are one `bulkWrite`, not a transaction: with `ordered: true` the first failing operation stops the rest, and the ones before it stay written.
##### Row keys
The `TableInput` keys rows by `rowKey` (default `_id`, then `id`). An ObjectId key comes back from the browser as the text `{"_oid":"…"}`, which the default `rowKeyType: auto` reads as an ObjectId. Object keys are always strings, so a numeric key `5` arrives as `"5"` in `updated` and `moved`, and as `5` in `removed` and `order`. With `rowKeyType: auto` both are the same row, and it matches a document key `5` or `"5"` (`{ $in: [5, "5"] }`). A string is read as a number only when it is exactly how that number prints (`"5"`, `"-2"`, `"1.5"`; not `"05"` or `"1e3"`). If a collection holds both `5` and `"5"` as different rows, set `rowKeyType: number` or `rowKeyType: string` to match one form only. `rowKeyType: objectId` also reads 24 character hex strings as ObjectIds.
##### Bulk selection
Set `selection` instead of `changes` to write the same values to many rows, such as a bulk "Assign owner" action on the rows selected in a `Table`. `selection` is the table's `selected` value:
- an array of row keys, which compiles to `{ : { $in: [keys] } }`;
- `{ all: true, except, filter, search }` when the header checkbox selects every row the view matches: the keys in `except` were deselected since, and `filter` and `search` are the view's. It compiles to the view's filter and search, validated and compiled like `MongoDBTableQuery` against `queryFields` (the table's `MongoDBTableQuery` `fields`, with the same limits and refusals), and `{ : { $nin: [except] } }`.
`set` is `{ [field]: value }` and `unset` a list of fields, both `fields` keys, checked and coerced like `updated` values, and never a scope field. The save is one `updateMany`:
```yaml
- updateMany:
filter: { $and: [, , , { _id: { $nin: [] } }] }
update: { $set: { owner.name: Ada }, $unset: { due: '' } }
```
The base `filter` (and the tenant, on a tenant connection) is one clause of the `$and`, so a crafted view can only narrow it. Row keys are read as in Row keys, and a `selection` has at most `maxChanges` keys. The response is `{ matchedCount, modifiedCount }`. `selection` can not be used in array mode.
#### Properties
- `changes: object`: The `TableInput` value, `{ _payload: changes }`: `{ updated, added, removed, moved, order }`. Required unless `selection` is set.
- `selection: object | any[]`: Bulk mode: the rows to write `set` and `unset` to, the `Table` `selected` value, `{ _payload: selected }`. See Bulk selection.
- `set: object`: Bulk mode: `{ [field]: value }` to set on every selected row.
- `unset: string[]`: Bulk mode: fields to remove from every selected row.
- `queryFields: object`: Bulk mode: the `MongoDBTableQuery` `fields` of the table, keyed by column key. Needed when a `selection` has a `filter` or `search`.
- `user: object`: Bulk mode: the user that `{ $user: path }` values in a `selection` filter resolve from. Set it to `{ _user: true }`.
- `timezone: string`: Default: `UTC` - Bulk mode: the IANA time zone whose days the date filters of a `selection` compare, as for `MongoDBTableQuery`.
- `fields: object`: __Required__ - The allowlist, keyed by the `TableInput` column `field` (its dot path, the changeset key), not the column `key` that `MongoDBTableQuery` fields use. Each field is an object:
- `type: enum`: __Required__ - The column type, as for `MongoDBTableQuery`. Values are checked and coerced to it.
- `path: string`: Default: the field key - Dot path the value is written to, in the document or, in array mode, in the item.
- `filter: object`: The base filter that scopes every operation, for example `{ org_id: { _user: organization.id } }`. New rows are stamped with its equality conditions, and `fields` can not write its fields. Required unless the connection is tenant-scoped. Set it to `{}` to allow writes to every document. See Scope fields.
- `rowKeyField: string`: Default: `_id` - The document field a row key matches, in collection mode. With any other field, added rows need their key from a column or `insertDefaults`.
- `rowKeyType: enum`: Default: `auto` - How row keys are read and matched: `auto`, `objectId`, `string` or `number`. See Row keys.
- `array: object`: Array mode: the rows are the items of an embedded array in one document.
- `documentId: any`: __Required__ - The `_id` of the document. Use `{ _oid: }` for an ObjectId from a string.
- `path: string`: __Required__ - Dot path of the array in the document.
- `itemKeyField: string`: Default: `_id` - The item field a row key matches.
- `positionField: string`: Dot path of the numeric position field, the `TableInput` `rowDrag.positionField`. Needed to save `moved`, and to save `order` in collection mode.
- `insertDefaults: object`: Values every added row gets, for example `{ created_by: { _user: id } }` or a created date. `fields` can not write them. Keys may be dot paths. See Scope fields.
- `ordered: boolean`: Default: `true` - Run the operations in order and stop at the first error. `false` (collection mode only) runs every operation and reports every error.
- `maxChanges: integer`: Default: `1000` - The most row changes one request may apply (updated, added, removed and moved rows, plus order entries). A larger changeset throws.
- `options: object`: Optional `bulkWrite` settings, for example `writeConcern`, `bypassDocumentValidation` or `comment`. See `MongoDBBulkWrite`.
#### Examples
###### Save the ingredients of a recipe (array mode):
The ingredients are an array in the recipe document, ordered by a `position` field. Dragging a row gives it a position between its neighbours, so a move saves one field on one item.
```yaml
id: recipe
type: Box
requests:
- id: get_recipe
type: MongoDBAggregation
connectionId: recipes
payload:
recipe_id:
_url_query: id
properties:
pipeline:
- $match:
_id:
_payload: recipe_id
org_id:
_user: organization.id
- $project:
title: 1
items:
$sortArray:
input: $items
sortBy:
position: 1
- id: save_items
type: MongoDBTableChanges
connectionId: recipes
payload:
recipe_id:
_url_query: id
changes:
_state: items
properties:
array:
documentId:
_payload: recipe_id
path: items
filter:
org_id:
_user: organization.id
positionField: position
fields:
ingredient:
type: text
qty:
type: number
unit:
type: text
changes:
_payload: changes
events:
onMount:
- id: fetch
type: Request
params: get_recipe
blocks:
- id: items
type: TableInput
properties:
data:
_request: get_recipe.0.items
addRow: true
rowDrag:
positionField: position
rowActions:
delete: true
columns:
- key: ingredient
editable: true
- key: qty
type: number
editable: true
- key: unit
editable: true
- id: save
type: Button
properties:
title: Save
events:
onClick:
- id: save_items
type: Request
params: save_items
- id: check_saved
type: Throw
params:
throw:
_gt:
- _array.length:
_if_none:
- _request: save_items.unmatchedKeys
- []
- 0
message: Some items were changed or removed by someone else. Reload and try again.
- id: refetch
type: Request
params: get_recipe
- id: reset
type: CallMethod
params:
blockId: items
method: resetChanges
```
###### Save edits to a list of deals (collection mode):
Every row is a document. New deals get the organization from the `filter` and the creator from `insertDefaults`. The table can not set either, and a `fields` entry for `org_id` or `created_by` would be refused.
```yaml
requests:
- id: save_deals
type: MongoDBTableChanges
connectionId: deals
payload:
changes:
_state: deals_table
properties:
filter:
org_id:
_user: organization.id
fields:
# Keyed by the TableInput column field, the changeset keys.
name:
type: text
stage:
type: tag
amount:
type: currency
owner.name:
type: text
close_date:
type: date
insertDefaults:
org_id:
_user: organization.id
created_by:
_user: id
created:
_date: now
changes:
_payload: changes
```
###### Assign an owner to the selected deals (bulk selection):
The `deals_table` `Table` in server mode shows the deals of `deals_page` (the `MongoDBTableQuery` example below). A button in its `bulkActions` sends the table's `selected` value, a list of keys or every row matching the view, and the request sets the owner on those rows inside the organization.
```yaml
requests:
- id: assign_owner
type: MongoDBTableChanges
connectionId: deals
payload:
selected:
_state: deals_table.selected
owner:
_state: new_owner
properties:
filter:
org_id:
_user: organization.id
fields:
owner.name:
type: text
# The table's MongoDBTableQuery fields, keyed by column key.
queryFields:
name:
type: text
search: true
stage:
type: tag
owner:
type: text
path: owner.name
search: true
amount:
type: currency
user:
_user: true
selection:
_payload: selected
set:
owner.name:
_payload: owner
```
### MongoDBTableQuery
The `MongoDBTableQuery` request serves a `Table` block in server mode. The table sends its view (sort, filter, search, grouping and aggregates) and the rows it needs, and the request compiles them to one aggregation on the server, against an allowlist of `fields`. The browser never sends MongoDB syntax: view keys that are not in `fields`, operators the field type does not allow and values of the wrong type are refused, regex input is escaped, and no `$where`, `$expr` or raw stages are accepted from the view.
The base `pipeline` always runs first, so use it for tenant or permission scoping. The view can only narrow what the base pipeline returns. On a tenant connection the tenant scope is added before the base pipeline, as for `MongoDBAggregation`.
Rows return only `_id`, the `fields` paths and the `returnFields` paths (`project: true`, the default), so a field the table does not list never reaches the browser, even when the documents hold it. Add the paths that cells read without a field of their own to `returnFields`, such as an avatar `srcField`, a link `labelField` or a `rowKey` other than `_id`. Set `project: false` to return the documents as the base pipeline leaves them, for example when it ends with its own `$project`.
The request compiles to:
```yaml
-
- $match:
- $match:
- $match:
- $sort: # when rows are returned
- $facet:
rows: [$skip, $limit, $project] # or groups: [$group, $sort, $skip, $limit]
total: [$count]
aggregates: [$group] # when the view has aggregates
distinct_a0: [$group, $count] # one per countDistinct
```
Rows are sorted by the view sort with `_id` as a tiebreak, so blocks of rows never repeat or skip a row. The sort runs before `$facet`, so an index on the base pipeline match, filter and sort fields (for example `{ org_id: 1, amount: -1, _id: 1 }` for a table of one organization sorted by amount) serves it, and each block reads the rows in index order. Without such an index, MongoDB sorts every matching document for each block, so add indexes for the sorts a large table offers.
##### Response
```yaml
rows: [...] # the rows from startRow to endRow, [] when groups are returned
total: 12408 # rows matching the view, or the number of groups at this level
groups: # only when view.group has more levels than groupPath
- key: won # the group value (null for missing values)
count: 210
aggregates: { amount: 125000 }
aggregates: # only when view.aggregates is set, over the rows this request matches
amount: 3400000
sentence: Stage is any of Lead or Won # only when view.filter is set
```
`sentence` is the filter in words, from the field `title` and `options` (`describeCondition` in `@lowdefy/helpers`). It reads the same as the Table's Filter button tooltip when each field carries its column's plain-text `title` and its options as `[{ value, label }]`; a field without a `title` reads as its key, where the Table shows the key humanized. An agent or a server routine that runs the request with no browser can then say what a saved view matches.
When `view.group` is set and `groupPath` is shorter than it, the request returns the groups of the next level, inside the groups in `groupPath`. When `groupPath` has a value for every level, it returns the leaf rows of that group.
##### Filters
The view `filter` is a condition: `{ and: [...] }`, `{ or: [...] }` or `{ key, op, value }`. The operators each field type allows:
| Field types | Operators |
| --- | --- |
| all | `eq`, `ne`, `in`, `nin`, `empty`, `notEmpty` |
| `text`, `email`, `phone`, `url`, `link`, `html`, `relation`, `tag`, `status`, `avatar` | `contains`, `notContains`, `startsWith`, `endsWith` |
| `number`, `currency`, `percent`, `progress`, `rating` | `gt`, `gte`, `lt`, `lte`, `between` (`value: [from, to]`) |
| `date`, `datetime` | `before`, `after`, `between`, `within` (`value: { last or next: n, unit: day, week, month or year }`); `before` and `after` take a date or the same relative value |
| `boolean` | `isTrue`, `isFalse` |
| `tags`, `people` | `contains` (has the value), `notContains` (does not have the value); `in` is has any of, `nin` is has none of |
| `image`, `json` | the operators for all types only |
These are the operators the `Table` filter menus offer for each column type, so any filter a user builds is accepted. An `avatar` field filters on the text at its `path` (the name the cell shows), like a `text` field.
- Text comparisons are case-insensitive.
- `empty` matches null, missing, `''` and `[]`.
- `eq` and `ne` on dates compare whole days, and so do `before`, `after` and `between` on `date` fields. `within` covers whole days, from the start of the day `n` units ago to the end of today (or from the start of today to the end of the day `n` units ahead), as the table filters in the browser.
- `before` and `after` with a relative value, such as `{ last: 3, unit: month }`, resolve when the query runs to the day it names in `timezone`: `before` matches values before the start of that day and `after` values from the end of it, on `date` and `datetime` fields alike. A bad relative value is refused with the message `within` gives.
- Days are the days of `timezone`, UTC by default. The browser filters by the user's local days, so pass the user's time zone for day-based filters, for example `timezone: { _payload: timezone }` with `timezone: { _js: 'return Intl.DateTimeFormat().resolvedOptions().timeZone;' }` in the request `payload`. A date-only value such as `2026-03-01` (what `date` column filters send) is that day in the time zone. An instant is compared by the day it falls on there.
- `isFalse` matches every value that is not `true`.
- Numeric values may be numbers or numeric strings, and date values dates, date strings or timestamps.
A value can be `{ $user: path }`, for example `{ key: owner, op: eq, value: { $user: id } }`. It is resolved on the server from the request's `user` property, which should be set to `{ _user: true }` (evaluated on the server from the session), never from a value the browser sends. The request throws when the user value is not set, rather than matching rows where the field is empty.
##### Aggregates
`view.aggregates` maps field keys to a function. All field types allow `count`, `countDistinct`, `countEmpty`, `countNotEmpty` and `percentEmpty` (a fraction from 0 to 1). Numeric types also allow `sum`, `avg`, `min` and `max`, text types (`text`, `email`, `phone`, `url`, `link`, `html`, `relation`, `tag`, `status`, `avatar`) `min` and `max`, and date types `earliest` and `latest`. `min` and `max` of text leave out empty values and compare strings as MongoDB does: by code point, so `Z` comes before `a`, unless `options.collation` sets a locale.
`countDistinct` groups by the field's values, so it needs `groupable: true` on the field, like grouping by it. Over the whole result it counts the groups in their own `$facet` branch, so a field with many distinct values never builds them all into one document; in a group level it collects the values of each group.
##### Limits
The view comes from the browser, so the work one request can ask of MongoDB is bounded:
- A filter has at most 200 conditions and groups (empty groups count), nested at most 8 levels deep.
- A filter has at most 1000 values in all, and `in` and `nin` at most 500 each.
- A string value (a `contains` text, an `eq` value, a list item) has at most 200 characters, like the search.
- A sort has at most 10 keys, and a view at most 5 group levels.
- One request returns at most `maxRows` rows or groups (default 1000).
- The aggregation stops after `options.maxTimeMS`, 10000 (10 seconds) by default. Set a larger value in `options` for a slow collection, or add indexes for the filters and sorts the table uses.
A request over a limit throws before the query runs.
#### Properties
- `fields: object`: __Required__ - The allowlist, keyed by the Table column `key` (the view's keys), not the column `field` that `MongoDBTableChanges` fields use; `path` gives the field path. Each field is an object:
- `type: enum`: __Required__ - The column type: `text`, `email`, `phone`, `url`, `link`, `html`, `relation`, `tag`, `status`, `number`, `currency`, `percent`, `progress`, `rating`, `date`, `datetime`, `boolean`, `tags`, `people`, `avatar`, `image` or `json`. It decides the operators and aggregates the field allows.
- `path: string`: Default: the field key - Dot path of the value in the documents the base pipeline returns.
- `search: boolean`: Default: `false` - Include the field in the view search. Each search word must match at least one search field.
- `sortable: boolean`: Default: `true` - Allow sorting by the field.
- `filterable: boolean`: Default: `true` - Allow filtering by the field.
- `groupable: boolean`: Default: `false` - Allow grouping by the field, and `countDistinct` on it. `tags` and `people` fields can not be grouped.
- `title: string`: Default: the field key - The field's name in the response `sentence`, as the Table column's title.
- `options: object[]`: The field's options as `[{ value, label }]`. The response `sentence` reads option values as their labels.
- `pipeline: object[]`: Default: `[]` - Base aggregation stages that always run first, for example tenant scoping and a `$project`. `$out` and `$merge` are not allowed.
- `view: object`: The Table view, `{ _payload: view }`. Only `sort`, `filter`, `search`, `group` and `aggregates` are read.
- `startRow: integer`: Default: `0` - Index of the first row to return, `{ _payload: startRow }`.
- `endRow: integer`: Default: `startRow + maxRows` - Index after the last row to return, `{ _payload: endRow }`.
- `groupPath: any[]`: Default: `[]` - The group values of the expanded group, one per group level, `{ _payload: groupPath }`.
- `maxRows: integer`: Default: `1000` - The most rows or groups one request may return. A request for more throws.
- `user: object`: The user that `{ $user: path }` filter values resolve from. Set it to `{ _user: true }`.
- `timezone: string`: Default: `UTC` - The IANA time zone, for example `Europe/London`, whose days date filters compare. See Filters.
- `project: boolean`: Default: `true` - Return only `_id`, the `fields` paths and `returnFields` in each row. Set it to `false` to return the documents as the base pipeline leaves them.
- `returnFields: string[]`: More dot paths each row returns, for values that cells read without a field of their own, for example an avatar `srcField` or a link `labelField`.
- `options: object`: Optional aggregate settings, for example `collation`, `maxTimeMS` (default `10000`), `allowDiskUse` or `hint`. See `MongoDBAggregation`.
#### Examples
###### A Table in server mode:
The Table sends `{ startRow, endRow, view, groupPath }` as the fetch event. The request `payload` reads it with `_event`, and the properties read the payload with `_payload`. Field keys match the Table column keys.
```yaml
id: deals
type: PageHeaderMenu
requests:
- id: deals_page
type: MongoDBTableQuery
connectionId: deals
payload:
view:
_event: view
startRow:
_event: startRow
endRow:
_event: endRow
groupPath:
_event: groupPath
properties:
pipeline:
- $match:
org_id:
_user: organization.id
# Rows return _id, the field paths and these paths only.
returnFields:
- owner.avatar
fields:
name:
type: text
search: true
stage:
type: tag
groupable: true
owner:
type: text
path: owner.name
search: true
groupable: true
amount:
type: currency
created:
type: date
user:
_user: true
view:
_payload: view
startRow:
_payload: startRow
endRow:
_payload: endRow
groupPath:
_payload: groupPath
blocks:
- id: deals_table
type: Table
properties:
data:
mode: server
request: deals_page
columns:
- key: name
- key: stage
type: tag
groupable: true
- key: owner
field: owner.name
type: avatar
groupable: true
cell:
srcField: owner.avatar
- key: amount
type: currency
aggregate: sum
- key: created
type: date
```
###### Only the current user's deals, with a filter the table can not remove:
```yaml
requests:
- id: my_deals_page
type: MongoDBTableQuery
connectionId: deals
payload:
view:
_event: view
startRow:
_event: startRow
endRow:
_event: endRow
properties:
pipeline:
- $match:
owner_id:
_user: id
fields:
name:
type: text
search: true
amount:
type: currency
closed:
type: boolean
view:
_payload: view
startRow:
_payload: startRow
endRow:
_payload: endRow
maxRows: 500
```
### MongoDBUpdateMany
The `MongoDBUpdateMany` request updates multiple documents that match a certain criteria in the collection specified in the connectionId. It requires a filter, which is written in the query syntax, to select the documents to update.
#### Properties
- `filter: object`: __Required__ - The filter used to select the document to update.
- `update: object | object[]`: __Required__ - The update operations to be applied to the document.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#updateOne) for more information. Supported settings are:
- `arrayFilters: string[]`: Array filters for the [`$[]`](https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/) array update operator.
- `bypassDocumentValidation: boolean`: Default: `false` - Allow driver to bypass schema validation in MongoDB 3.2 or higher.
- `checkKeys: boolean`: Default: `false` - If true, will throw if bson documents start with $ or include a . in any key value.
- `collation: object`: Specify collation (MongoDB 3.4 or higher) settings for update operation.
- `forceServerObjectId: boolean`: Force server to assign _id values instead of driver.
- `hint: object`: An optional hint for query optimization.
- `ignoreUndefined: boolean`: Default: `false` - Specify if the BSON serializer should ignore undefined fields.
- `j: boolean`: Specify a journal write concern.
- `upsert: boolean`: Default: `false` - Insert document if no match is found.
- `w: number | string`: The write concern.
- `wtimeout: number`: The write concern timeout.
#### Examples
###### Set a list of documents as resolved:
```yaml
requests:
- id: set_resolved
type: MongoDBUpdateMany
connectionId: my_mongodb_collection_id
payload:
selected_issues_list:
_state: selected_issues_list
properties:
# Select all documents where the _id is in selected_issues_list in state
filter:
_id:
$in:
_payload: selected_issues_list
update:
$set:
resolved: true
```
###### Mark all documents with score less than 6 as urgent:
```yaml
requests:
- id: set_resolved
type: MongoDBUpdateMany
properties:
filter:
score:
$lt: 6
update:
$set:
status: urgent
```
### MongoDBUpdateOne
The `MongoDBUpdateOne` request updates a single document in the collection specified in the connectionId. It requires a filter, which is written in the query syntax, to select a document to update. It will update the first document that matches the filter. If the `upsert` option is set to true, it will insert a new document if no document is found to update.
If no document matches the filter, the request throws `No matching record to update.` — a silent no-op update usually indicates a bug. Set `disableNoMatchError: true` on the request to restore the pre-5.5.0 behavior of returning `matchedCount: 0`. Requests with the `upsert` option never throw this error. Running `lowdefy upgrade` adds `disableNoMatchError: true` to existing requests so upgraded apps keep their behavior.
> When the connection has a log collection, a findOneAndUpdate operation is performed instead of the standard updateOne operation so before and after document snapshots can be captured in the change log. The response shape is the same in both cases.
#### Properties
- `filter: object`: __Required__ - The filter used to select the document to update.
- `update: object | object[]`: __Required__ - The update operations to be applied to the document.
- `disableNoMatchError: boolean`: Default: `false` - Do not throw an error when no document matches the filter.
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#updateone) for more information. Supported settings are:
- `arrayFilters: object[]`: _Array_ - Array filters for the [`$[]`](https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/) array update operator.
- `authdb: string`: Specifies the authentication information to be used.
- `bsonRegExp: boolean`: Return the BSON regular expressions as BSONRegExp instances.
- `bypassDocumentValidation: boolean`: Default: `false` - Allow driver to bypass schema validation in MongoDB 3.2 or higher.
- `checkKeys: boolean`: Default: `false` - If true, will throw if bson documents start with $ or include a . in any key value.
- `collation: object`: Specify collation (MongoDB 3.4 or higher) settings for update operation.
- `comment: string | object`: A user-provided comment to attach to this command.
- `dbName: string`: The database name.
- `explain: object`: Specifies the verbosity mode for the explain output.
- `fullResponse: boolean`: Return the full server response for the command.
- `hint: string | object`: An optional hint for query optimization.
- `ignoreUndefined: boolean`: Default: `false` - Specify if the BSON serializer should ignore undefined fields.
- `let: object`: Map of parameter names and values that can be accessed using `$$var` (requires MongoDB 5.0).
- `maxTimeMS: number`: Number of milliseconds to wait before aborting the command.
- `noResponse: boolean`: Admin command option.
- `readConcern: object`: Specify a read concern and level for the collection. (only MongoDB 3.2 or higher supported).
- `readPreference: object`: The preferred read preference.
- `retryWrites: boolean`: Should retry failed writes.
- `serializeFunctions: boolean`: Default: `false` - Serialize the javascript functions.
- `upsert: boolean`: Default: `false` - Insert document if no match is found.
- `willRetryWrites: boolean`: Option whether to retry writes.
- `writeConcern: object`: An object that expresses the write concern.
#### Examples
###### Update a document:
```yaml
requests:
- id: update
type: MongoDBUpdateOne
connectionId: my_mongodb_collection_id
payload:
_id:
_state: _id
properties:
filter:
_id:
_payload: _id
update:
$set:
_state: true
```
Like a comment:
```yaml
requests:
- id: like_comment
type: MongoDBUpdateOne
connectionId: my_mongodb_collection_id
payload:
comment_id:
_state: comment._id
properties:
filter:
_id:
_payload: comment_id
update:
$inc:
likes: 1
$push:
liked_by:
_user.id:
$set:
last_liked:
_date: now
```
### MongoDBVersionedUpdateOne
The `MongoDBVersionedUpdateOne` request updates a single document while preserving the previous version. The matched document is re-inserted under a new `_id`, and the update is applied to the new copy — so the collection keeps a full version history of the document.
If no document matches the filter, the request throws `No matching record to update.`. Set `disableNoMatchError: true` on the request to suppress the error. Requests with the `upsert` update option never throw this error.
> The version insert and the update are separate operations, not a transaction. If the update fails, the inserted version copy remains in the collection.
> When the connection has a log collection, a findOneAndUpdate operation is performed instead of the standard updateOne operation so before and after document snapshots can be captured in the change log. The response shape is the same in both cases.
#### Properties
- `filter: object`: __Required__ - The filter used to select the document to version and update.
- `update: object | object[]`: __Required__ - The update operations to be applied to the new copy of the document.
- `disableNoMatchError: boolean`: Default: `false` - Do not throw an error when no document matches the filter.
- `options: object`: Optional settings for each underlying operation:
- `find: object`: Options for the find one operation. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#findone).
- `insert: object`: Options for the insert one operation that creates the version copy. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#insertone).
- `update: object`: Options for the update operation. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#updateone).
#### Examples
###### Update a document, keeping the previous version:
```yaml
requests:
- id: versioned_update
type: MongoDBVersionedUpdateOne
connectionId: my_mongodb_collection_id
payload:
doc_id:
_state: doc_id
properties:
filter:
doc_id:
_payload: doc_id
current: true
update:
$set:
status:
_state: status
```
## Websockets
Websocket types:
- MongoDBChangeStream
### MongoDBChangeStream
The `MongoDBChangeStream` [websocket](/websockets-introduction) opens a MongoDB [change stream](https://www.mongodb.com/docs/manual/changeStreams/) on the collection specified in the connection, and pushes every change event to subscribed pages in real time. The source starts when the first page subscribes and stops when the last one leaves — any number of subscribers share one change stream.
Properties are evaluated per subscription, so `_user` and `_payload` operators in the `pipeline` produce user-specific streams.
A change stream reads the collection, so a connection with `read: false` refuses subscriptions, as it refuses read requests.
> Change streams require MongoDB to run as a replica set — they are not available on standalone deployments. MongoDB Atlas clusters support them out of the box.
#### Properties
- `pipeline: object[]`: An array of [aggregation pipeline stages](https://www.mongodb.com/docs/manual/changeStreams/#modify-change-stream-output) applied to the change stream, e.g. `$match` on `operationType` or `fullDocument` fields.
- `fullDocument: string`: The change stream [fullDocument](https://www.mongodb.com/docs/manual/reference/method/db.collection.watch/) option. Defaults to `updateLookup`, which includes the current document on update events.
#### Examples
###### Refetch a table when the user's orders change:
```yaml
websockets:
- id: order_updates
type: MongoDBChangeStream
connectionId: my_mongodb_collection_id
properties:
pipeline:
- $match:
operationType:
$in:
- insert
- update
fullDocument.owner_id:
_user: id
pages:
- id: orders
type: PageHeaderMenu
requests:
- id: get_orders
type: MongoDBFind
connectionId: my_mongodb_collection_id
properties:
query:
owner_id:
_user: id
subscriptions:
- websocketId: order_updates
events:
onMessage:
- id: refetch
type: Request
params: get_orders
blocks:
- id: orders_table
type: AgGridAlpine
properties:
rowData:
_request: get_orders
```
The change event payload is available on `_event: messages` in `onMessage` and via the [`_websocket`](/websocket-subscriptions) operator — each message is the MongoDB change event, including `operationType`, `documentKey` and `fullDocument`.
## Errors
When MongoDB rejects an operation, the request fails with a `RequestError` that carries:
- `code` — the MongoDB error code, for example `11000` for a duplicate key.
- `message` — a plain sentence naming the collection and the request type, like `Duplicate key on collection "orders".`
- `hint` — a sentence saying what to do about it, for example to insert with `MongoDBUpdateOne` and `upsert: true`, or to grant the database user a role.
A time limit (codes `50` and `89`) or the aggregation memory limit (code `292`) is a `ServiceError` instead, with the same `code` and a `hint` such as adding an index covering the filter. Network, DNS and TLS failures are also `ServiceError`s, classified by the connection layer rather than by an error code. A `ServiceError` is an outage that can pass with time; a `RequestError` repeats until the request or the database changes.
The driver's own message is never sent to the browser — it can quote values from the document that triggered the error. The dev server terminal prints it under the located error line as `Caused by: MongoServerError: E11000 …`.
---
url: https://docs.lowdefy.com/md/connections/mssql.md
---
# Microsoft SQL Server
The [Knex](/Knex) connection can be used to connect to [Microsoft SQL Server](https://www.microsoft.com/en-us/sql-server/sql-server-2019).
## Connections
Connection types:
- Knex
### Knex
#### Properties
- `client: enum`: __Required__ - Should be `mssql` to connect to Microsoft SQL Server.
- `connection: object | string `: __Required__ - Connection object or string to pass to the [`tedious`](https://www.npmjs.com/package/tedious) database client (knex's `mssql` dialect uses tedious internally).
- `useNullAsDefault: boolean`: If true, undefined keys are replaced with NULL instead of DEFAULT.
#### Examples
###### Connection object:
```yaml
connections:
- id: mssql
type: Knex
properties:
client: mssql
connection:
host:
_secret: MSSQL_HOST
database:
_secret: MSSQL_DB
user:
_secret: MSSQL_USER
password:
_secret: MSSQL_PASSWORD
```
Environment variables:
```
LOWDEFY_SECRET_MSSQL_HOST = database.server.com
LOWDEFY_SECRET_MSSQL_DB = db
LOWDEFY_SECRET_MSSQL_USER = user
LOWDEFY_SECRET_MSSQL_PASSWORD = password
```
###### Secret connection string:
```yaml
connections:
- id: mssql
type: Knex
properties:
client: mssql
connection:
_secret: MSSQL_CONNECTION_STRING
```
Environment variables:
```
LOWDEFY_SECRET_MSSQL_CONNECTION_STRING = mssql://user:password@database.server.com:1433/db
```
## Requests
Request types:
- KnexBuilder
- KnexRaw
### KnexBuilder
#### Properties
- `query: object[]`: **Required** - SQL query builder array. An array of objects, with a single key which is the name of the knex builder function. The value should be an array of arguments to pass to the builder function.
- `tableName: string | object`: The name of the table to query from.
#### Examples
###### Build a query:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
query:
- select:
- '*'
- from:
- users
- where:
- name
- _payload: name
```
###### Using `tableName`:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
tableName: users
query:
- select:
- '*'
- where:
- name
- _payload: name
```
###### Aliases:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
properties:
tableName:
a: tableA
b: tableB
query:
- select:
- aField: 'a.field'
- bField: 'b.field'
- limit:
- 1
```
### KnexRaw
#### Properties
- `query: string`: **Required** - SQL query string.
- `parameters: string | number | array | object`: SQL query parameters.
#### Examples
###### Simple raw query:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query: SELECT * FROM "my_table";
```
###### Query with named parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = :name
parameters:
name:
_payload: selected_name
```
###### Query with positional parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = ?
parameters:
- _payload: selected_name
```
###### Reference a `.sql` file:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query:
_ref: my_query.sql
```
---
url: https://docs.lowdefy.com/md/connections/mysql.md
---
# MySQL
The [Knex](/Knex) connection can be used to connect to a [MySQL](https://www.mysql.com) database.
## Connections
Connection types:
- Knex
### Knex
#### Properties
- `client: enum`: __Required__ - Should be `mysql2` to connect to MySQL. MySQL uses the [`mysql2`](https://www.npmjs.com/package/mysql2) driver.
- `connection: object | string `: __Required__ - Connection object or string to pass to the database client.
- `version: string`: Set database version.
- `useNullAsDefault: boolean`: If true, undefined keys are replaced with NULL instead of DEFAULT.
#### Examples
###### Connection Object:
```yaml
connections:
- id: mysql
type: Knex
properties:
client: mysql2
connection:
host:
_secret: MYSQL_HOST
user:
_secret: MYSQL_USER
database:
_secret: MYSQL_DB
password:
_secret: MYSQL_PASSWORD
```
Environment variables:
```
LOWDEFY_SECRET_MYSQL_HOST = database.server.com
LOWDEFY_SECRET_MYSQL_DB = db
LOWDEFY_SECRET_MYSQL_USER = user
LOWDEFY_SECRET_MYSQL_PASSWORD = password
```
###### Connection string:
```yaml
connections:
- id: mysql
type: Knex
properties:
client: mysql2
connection:
_secret: MYSQL_CONNECTION_STRING
```
Environment variables:
```
LOWDEFY_SECRET_MYSQL_CONNECTION_STRING = mysql://user:password@database.server.com/db
```
## Requests
Request types:
- KnexBuilder
- KnexRaw
### KnexBuilder
#### Properties
- `query: object[]`: **Required** - SQL query builder array. An array of objects, with a single key which is the name of the knex builder function. The value should be an array of arguments to pass to the builder function.
- `tableName: string | object`: The name of the table to query from.
#### Examples
###### Build a query:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
query:
- select:
- '*'
- from:
- users
- where:
- name
- _payload: name
```
###### Using `tableName`:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
tableName: users
query:
- select:
- '*'
- where:
- name
- _payload: name
```
###### Aliases:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
properties:
tableName:
a: tableA
b: tableB
query:
- select:
- aField: 'a.field'
- bField: 'b.field'
- limit:
- 1
```
### KnexRaw
#### Properties
- `query: string`: **Required** - SQL query string.
- `parameters: string | number | array | object`: SQL query parameters.
#### Examples
###### Simple raw query:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query: SELECT * FROM "my_table";
```
###### Query with named parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = :name
parameters:
name:
_payload: selected_name
```
###### Query with positional parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = ?
parameters:
- _payload: selected_name
```
###### Reference a `.sql` file:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query:
_ref: my_query.sql
```
---
url: https://docs.lowdefy.com/md/connections/postgresql.md
---
# PostgreSQL
The [Knex](/Knex) connection can be used to connect to a [PostgreSQL](https://www.postgresql.org) database.
## Connections
Connection types:
- Knex
### Knex
#### Properties
- `client: enum`: __Required__ - The database client to use. To connect to PostgreSQL, use one of:
- `postgres`
- `pg` (alias of `postgres`)
- `postgresql` (alias of `postgres`)
- `connection: object | string`: __Required__ - Connection string or object to pass to the [`pg`](https://www.npmjs.com/package/pg) database client.
- `searchPath: string`: Set PostgreSQL search path.
- `version: string`: Set database version.
- `useNullAsDefault: boolean`: If true, undefined keys are replaced with NULL instead of DEFAULT.
#### Examples
###### Connection Object:
```yaml
connections:
- id: postgres
type: Knex
properties:
client: postgres
connection:
user:
_secret: PG_USER
host:
_secret: PG_HOST
database:
_secret: PG_DB
password:
_secret: PG_PASSWORD
```
Environment variables:
```
LOWDEFY_SECRET_PG_HOST = database.server.com
LOWDEFY_SECRET_PG_DB = db
LOWDEFY_SECRET_PG_USER = user
LOWDEFY_SECRET_PG_PASSWORD = password
```
###### Secret connection string, with version and searchPath:
```yaml
connections:
- id: postgres
type: Knex
properties:
client: postgres
connection:
_secret: PG_CONNECTION_STRING
version: '7.2'
searchPath:
- knex
- public
```
Environment variables:
```
LOWDEFY_SECRET_PG_CONNECTION_STRING = postgresql://user:password@database.server.com:5432/db
```
## Requests
Request types:
- KnexBuilder
- KnexRaw
### KnexBuilder
#### Properties
- `query: object[]`: **Required** - SQL query builder array. An array of objects, with a single key which is the name of the knex builder function. The value should be an array of arguments to pass to the builder function.
- `tableName: string | object`: The name of the table to query from.
#### Examples
###### Build a query:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
query:
- select:
- '*'
- from:
- users
- where:
- name
- _payload: name
```
###### Using `tableName`:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
tableName: users
query:
- select:
- '*'
- where:
- name
- _payload: name
```
###### Aliases:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
properties:
tableName:
a: tableA
b: tableB
query:
- select:
- aField: 'a.field'
- bField: 'b.field'
- limit:
- 1
```
### KnexRaw
#### Properties
- `query: string`: **Required** - SQL query string.
- `parameters: string | number | array | object`: SQL query parameters.
#### Examples
###### Simple raw query:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query: SELECT * FROM "my_table";
```
###### Query with named parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = :name
parameters:
name:
_payload: selected_name
```
###### Query with positional parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = ?
parameters:
- _payload: selected_name
```
###### Reference a `.sql` file:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query:
_ref: my_query.sql
```
---
url: https://docs.lowdefy.com/md/connections/redis.md
---
# Redis
[`Redis`](http://redis.io/) is an open-source, in-memory key-value data structure store. Redis offers a set of versatile in-memory data structures (strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams) that allow the creation of many custom applications. Key use cases for Redis include database, caching, session management and message broker.
Lowdefy integrates with Redis using the one of the recommended [Node.js clients (node-redis)](https://github.com/redis/node-redis).
## Connections
Connection types:
- Redis
### Redis
#### Properties
- `connection: object | string `: __Required__ - Connection object or string to pass to the [`redis client`](https://github.com/redis/node-redis) redis client.
The connection object accepts will be passed to the redis client verbatim, so check out the [configuration instructions](https://github.com/redis/node-redis/blob/master/docs/client-configuration.md).
#### Examples
###### Redis with connection object:
```yaml
connections:
- id: redis
type: Redis
properties:
connection:
username:
_secret: REDIS_USERNAME
password:
_secret: REDIS_PASSWORD
database:
_secret: REDIS_DATABASE
socket:
host:
_secret: REDIS_HOST
port:
_secret: REDIS_PORT
```
Environment variables:
```
LOWDEFY_SECRET_REDIS_USERNAME = user
LOWDEFY_SECRET_REDIS_PASSWORD = password
LOWDEFY_SECRET_REDIS_DATABASE = 4
LOWDEFY_SECRET_REDIS_HOST = redis.server.com
LOWDEFY_SECRET_REDIS_PORT = 5000
```
###### Redis with connection string:
```yaml
connections:
- id: redis
type: Redis
properties:
connection:
_secret: REDIS_CONNECTION_STRING
```
Environment variables:
```
LOWDEFY_SECRET_REDIS_CONNECTION_STRING = redis://user:password@redis:server.com:5000/4'
```
## Requests
Request types:
- Redis
### Redis
#### Properties
- `command: string`: **Required** - Redis command to be executed, accepts all of the [out-of-the-box Redis commands](https://redis.io/commands).
- `parameters: array`: An array of parameters to be passed to the redis command.
- `modifiers: object`: The redis modififers to be passed to the redis command.
#### Examples
###### Setting a key-value pair in redis:
```yaml
id: redisRequest
type: Redis
connectionId: redis
properties:
command: set
parameters:
- key
- value
```
###### Getting a value from redis:
```yaml
id: redisRequest
type: Redis
connectionId: redis
properties:
command: get
parameters:
- key
```
###### Setting a key-value pair only if key does not exist:
```yaml
id: redisRequest
type: Redis
connectionId: redis
properties:
command: set
parameters:
- key
- value
modififers:
nx: true
```
---
url: https://docs.lowdefy.com/md/connections/sendgridmail.md
---
# SendGrid Email
[SendGrid](https://sendgrid.com/) is a popular email API provider which allows you to easily setup a email service. The `SendGridMail` connection can be used to connect to an existing SendGrid API account.
The `SendGridMail` connector uses the [@sendgrid/mail](https://github.com/@sendgrid/mail) library.
In order to use the `SendGridMail` connector, you first need to create a [SendGrid](https://sendgrid.com/) account and setup an API key.
> Secrets like API keys should be stored using the [`_secret`](operators/secret.md) operator.
In order to send from your custom domain your will need to [authenticate your domain](https://app.sendgrid.com/settings/sender_auth) through SendGrid. See the [SendGrid Docs](https://sendgrid.com/docs) for help on getting started with SendGrid.
## Connections
Connection types:
- SendGridMail
## Requests
Request types:
- SendGridMailSend
### Types
- `email: string | object`: SendGrid accepts emails as either a `string` or an `object`.
- `string`: Can be in the following format; `someone@example.org` or `Some One `.
- `object`: With `name' and `email` properties, for example: `{"name": "Some One", "email": "someone@example.org"}`.
### SendGridMail
#### Properties
- `apiKey: string`: __Required__ - SendGrid API key.
- `from: email`: __Required__ - Email address to send email from.
- `replyTo: email`: Default email address replies should be sent to.
- `mailSettings: object`: SendGrid mail settings. See [SendGrid API-Reference](https://sendgrid.com/docs/api-reference/)
- `sandboxMode: object`: SendGrid mail sandbox mode settings.
- `enable: boolean`: Sandbox mode enabled when `true`.
- `templateId: string`: SendGrid email template ID to render email when sending.
- `filter: object`: Environment-aware delivery filter, applied to every send. Filter values are usually supplied by [`_secret`](operators/secret.md); a field that resolves to `null` is ignored, so one config serves every environment (a dev catch-all, a sandbox allowlist, nothing in production).
- `replaceAddress: string`: Redirect all mail to this single address. When set, it takes precedence — every message goes to this address only, with `cc` and `bcc` dropped.
- `allowlist: string[]`: A list of domains. Only recipients whose domain is in the list are sent to.
- `regex: string`: A regular expression. Only recipient addresses matching the pattern are sent to.
When the connection sets no `filter`, or every field of it resolves to `null`, the current environment's `email.filter` from [`config.environments`](/lowdefy-schema) applies instead. A connection's own `filter` wins when it sets at least one field, and `filter: false` turns filtering off entirely, the environment's too. With `email.enabled: false` on the current environment, mail requests send nothing and report each message as `{ disabled: true }`.
Addresses on the reserved `.invalid` domain, which never resolves (RFC 6761), are always dropped from `to`, `cc` and `bcc` before the filter runs, in every environment, with no filter and with `filter: false` too. Case, surrounding spaces and a trailing dot are ignored. SendGrid reads a string recipient as one address, so a comma-separated string is dropped only when every address in it is on `.invalid`. Only those addresses are dropped: when every `to` recipient is on `.invalid`, the remaining `cc` and `bcc` recipients each get their own copy, addressed to them, since SendGrid needs a `to` recipient. When no recipient is left, the message is not sent and reports `{ messageId: null, to: null, filtered: true }`. So test users with addresses such as `user@audit.invalid` never reach a `replaceAddress` catch-all. Use `.invalid` for test users that must never receive mail, and `example.com` or `.test` for journey users whose mail a journey reads.
### SendGridMailSend
#### Properties
##### object
A `mail description`:
- `to: email | email[]`: __Required__ - Email address or addresses to send to.
- `cc: email | email[]`: Email address to cc in communication.
- `bcc: email | email[]`: Email address to bcc in communication.
- `replyTo: email | email[]`: Email address to reply to.
- `subject: string`: Email subject.
- `text: string`: Email message in plain text format.
- `html: string`: Email message in html format.
- `dynamicTemplateData: object`: SendGrid template data to render into email template.
- `sendAt: integer`: A unix timestamp allowing you to specify when you want your email to be delivered. You can't schedule more than 72 hours in advance.
- `attachments: object[]`: List of email attachments to include with email. See [SendGrid API-Reference](https://d2w67tjf43xwdp.cloudfront.net/Classroom/Build/Add_Content/attachments.html]).
- `content: string`: __Required__ - Base 64 encoded attachment content.
- `filename: string`: __Required__ - Name of the attachment file.
- `type: string`: The mime type of the content you are attaching. For example, `text/plain` or `text/html`.
##### array
An array of `mail description` objects can also be provided.
### Examples
###### Send a reminder email
```yaml
connections:
- id: my_sendgrid
type: SendGridMail
properties:
apiKey:
_secret: SENDGRID_API_KEY
from: reminders@example.org
# ...
requests:
- id: send_reminder
type: SendGridMailSend
connectionId: my_sendgrid
properties:
to: Harry Potter
subject: Reminder for Mr. Potter to water the 🌱
text: |
Hi Harry
Please remember to water the magic plants today :)
Thank you
# ...
```
---
url: https://docs.lowdefy.com/md/connections/smtp.md
---
# SMTP Email
The `SMTP` connection sends email over any SMTP server — Amazon SES, Postmark, Mailgun, Resend, SendGrid's SMTP relay, or a self-hosted server. One connection type covers every provider.
The `SMTP` connector uses the [nodemailer](https://nodemailer.com/) library. Connection properties are passed through to nodemailer's transport, so any [transport option](https://nodemailer.com/smtp/) nodemailer accepts (pooling, TLS options, a `service` shortcut, a connection `url`) can be set alongside the documented properties.
> Secrets like passwords and API keys should be stored using the [`_secret`](operators/secret.md) operator.
## Connections
Connection types:
- SMTP
## Requests
Request types:
- SMTPMailSend
### Types
- `email: string | object`: An email address as either a `string` or an `object`.
- `string`: In the format `someone@example.org` or `Some One `.
- `object`: With `name` and `email` properties, for example `{ "name": "Some One", "email": "someone@example.org" }`.
- `emails: email | email[]`: A single email address or a list of email addresses.
### SMTP
#### Properties
- `host: string`: Hostname or IP address of the SMTP server to connect to.
- `port: integer`: Port to connect to. Defaults to `587` when `secure` is `false`, or `465` when `secure` is `true`.
- `secure: boolean`: If `true`, the connection uses TLS when connecting to the server.
- `auth: object`: Authentication credentials for the SMTP server.
- `user: string`: Username to authenticate with.
- `pass: string`: Password to authenticate with.
- `from: emails`: __Required__ - Default email address to send email from.
- `replyTo: emails`: Default email address replies should be sent to.
- `filter: object`: Environment-aware delivery filter, applied to every send. See [Delivery filter](#delivery-filter) below.
Additional nodemailer transport options (for example `service`, `url`, `pool`, `tls`) are passed through unchanged.
### SMTPMailSend
Sends one email, or an array of emails. When an array is given, each message is sent in turn.
#### Properties
##### object
A `mail description`:
- `to: emails`: __Required__ - Email address or addresses to send to.
- `cc: emails`: Email address to cc in communication.
- `bcc: emails`: Email address to bcc in communication.
- `replyTo: emails`: Email address to reply to. Overrides the connection `replyTo`.
- `subject: string`: Email subject.
- `text: string`: Email message in plain text format.
- `html: string`: Email message in html format.
- `attachments: object[]`: List of email attachments to include with the email.
- `filename: string`: Name of the attachment file.
- `content: string`: String content of the attachment.
- `path: string`: File path or URL to stream the attachment from.
- `contentType: string`: The mime type of the content you are attaching. For example, `text/plain` or `text/html`.
- `encoding: string`: Encoding used to decode string `content` into a buffer. For example, `base64` or `hex`.
- `cid: string`: Content id to reference the attachment as an embedded image in html.
##### array
An array of `mail description` objects can also be provided.
### Delivery filter
The connection's `filter` is applied to every message before it is sent — from `SMTPMailSend` requests, notification pipelines, and any other send over the connection. It has one enforcement point, so no send can bypass it. Because filter values are usually supplied by [`_secret`](operators/secret.md), any field that resolves to `null` or `undefined` is ignored — an unset filter is disabled. This lets one connection config serve every environment: development sets a catch-all, a sandbox sets a domain allowlist or regex, production sets nothing.
- `replaceAddress: string`: Redirect all mail to this single address. When set, it takes precedence — every message is delivered to this address only, with `cc` and `bcc` dropped. Use it to catch all outbound mail in development.
- `allowlist: string[]`: A list of domains. Only recipients whose domain is in the list are sent to; others are dropped. When every `to` recipient is filtered out, the message is not sent.
- `regex: string`: A regular expression. Only recipient addresses matching the pattern are sent to.
Addresses on the reserved `.invalid` domain, which never resolves (RFC 6761), are always dropped from `to`, `cc` and `bcc` before the filter runs. This happens in every environment, with no filter and with `filter: false`, and for auth emails too. Case, surrounding spaces and a trailing dot are ignored, and each address in a comma-separated string is checked on its own. Only those addresses are dropped: when every `to` recipient is on `.invalid`, the remaining `cc` and `bcc` recipients still get the mail. When no recipient is left, the message is not sent and reports `{ messageId: null, to: null, filtered: true }`. So test users with addresses such as `user@audit.invalid` never reach a `replaceAddress` catch-all. Use `.invalid` for test users that must never receive mail, and `example.com` or `.test` for journey users whose mail a journey reads.
When the connection sets no `filter`, or every field of it resolves to `null`, the current environment's `email.filter` from [`config.environments`](/lowdefy-schema) applies instead, so the per-environment rule lives in one place for every mail connection. A connection's own `filter` wins when it sets at least one field, and `filter: false` turns filtering off entirely — the environment's too — for mail that must reach its real recipient in every environment (an invite, say). Auth emails (magic links, email codes, verification, password reset, invitations) send through the `auth.email` connection with only that connection's own `filter`: the environment's `email.filter` and `email.enabled` do not apply to them, so sign-in keeps working in every environment. To catch auth emails outside production, set a `filter` on the auth connection itself. With `email.enabled: false` on the current environment, mail requests send nothing and report each message as `{ disabled: true }`.
```yaml
config:
environments:
prod:
url: https://app.example.com
staging:
url: https://staging.example.com
email:
filter:
replaceAddress: team+staging@example.com
```
`allowlist` and `regex` combine — a recipient must satisfy both to receive mail.
### Examples
###### Send a reminder email
```yaml
connections:
- id: my_smtp
type: SMTP
properties:
host: smtp.example.com
port: 465
secure: true
auth:
user: my-smtp-user
pass:
_secret: SMTP_PASS
from: Reminders
# ...
requests:
- id: send_reminder
type: SMTPMailSend
connectionId: my_smtp
properties:
to: Harry Potter
subject: Reminder for Mr. Potter to water the 🌱
text: |
Hi Harry
Please remember to water the magic plants today :)
Thank you
# ...
```
###### Catch all mail in a development environment
```yaml
connections:
- id: my_smtp
type: SMTP
properties:
host: smtp.example.com
auth:
user: my-smtp-user
pass:
_secret: SMTP_PASS
from: App
filter:
# In dev, DEV_CATCH_ALL is set and all mail is redirected to it.
# In production the secret is unset, so the filter is disabled.
replaceAddress:
_secret: DEV_CATCH_ALL
```
###### Send over SendGrid's SMTP relay
```yaml
connections:
- id: my_smtp
type: SMTP
properties:
host: smtp.sendgrid.net
port: 465
secure: true
auth:
user: apikey
pass:
_secret: SENDGRID_API_KEY
from: App
```
---
url: https://docs.lowdefy.com/md/connections/sqlite.md
---
# SQLite
The [Knex](/Knex) connection can be used to connect to a [SQLite](https://www.sqlite.org) database.
## Connections
Connection types:
- Knex
### Knex
#### Properties
- `client: enum`: __Required__ - Should be `better-sqlite3` or `sqlite` (alias of `better-sqlite3`) to connect to SQLite. SQLite uses the [`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3) driver.
- `connection: object`:
- `filename: string`: __Required__ - The path to the SQLite file (relative to the project root).
- `useNullAsDefault: boolean`: If true, undefined keys are replaced with NULL instead of DEFAULT.
#### Examples
##### Specify filename:
```yaml
connections:
- id: sqlite
type: Knex
properties:
client: better-sqlite3
connection:
filename: ./mydb.sqlite
```
###### Different connections in deployment and production environments:
```yaml
connections:
- id: knex
type: Knex
properties:
client:
_secret: KNEX_CLIENT
connection:
_json.parse:
_secret: KNEX_CONNECTION
```
Environment variables in development:
```
LOWDEFY_SECRET_KNEX_CLIENT = better-sqlite3
LOWDEFY_SECRET_KNEX_CONNECTION = {"filename": "./mydb.sqlite"}
```
Environment variables in production:
```
LOWDEFY_SECRET_KNEX_CLIENT = postgres
LOWDEFY_SECRET_KNEX_CONNECTION = {"user": "dbuser", "host": "database.server.com", "database": "mydb", "password": "secretpassword"}
```
## Requests
Request types:
- KnexBuilder
- KnexRaw
### KnexBuilder
#### Properties
- `query: object[]`: **Required** - SQL query builder array. An array of objects, with a single key which is the name of the knex builder function. The value should be an array of arguments to pass to the builder function.
- `tableName: string | object`: The name of the table to query from.
#### Examples
###### Build a query:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
query:
- select:
- '*'
- from:
- users
- where:
- name
- _payload: name
```
###### Using `tableName`:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
payload:
name:
_state: name
properties:
tableName: users
query:
- select:
- '*'
- where:
- name
- _payload: name
```
###### Aliases:
```yaml
id: knexBuilder
type: KnexBuilder
connectionId: knex
properties:
tableName:
a: tableA
b: tableB
query:
- select:
- aField: 'a.field'
- bField: 'b.field'
- limit:
- 1
```
### KnexRaw
#### Properties
- `query: string`: **Required** - SQL query string.
- `parameters: string | number | array | object`: SQL query parameters.
#### Examples
###### Simple raw query:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query: SELECT * FROM "my_table";
```
###### Query with named parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = :name
parameters:
name:
_payload: selected_name
```
###### Query with positional parameters:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
payload:
selected_name:
_state: selected_name
properties:
query: select * from users where name = ?
parameters:
- _payload: selected_name
```
###### Reference a `.sql` file:
```yaml
id: knexRaw
type: KnexRaw
connectionId: knex
properties:
query:
_ref: my_query.sql
```
---
url: https://docs.lowdefy.com/md/connections/stripe.md
---
# Stripe
## Connections
Connection types:
- Stripe
### Stripe
[Stripe](https://stripe.com/) is a popular payment provider which allows you to accept payments, send payouts, and manage your business online.
The `Stripe` connector uses the official [Node.js client from Stripe](https://github.com/stripe/stripe-node).
In order to use the `Stripe` connection, you first need to create a [Stripe](https://stripe.com/) account and setup an API key.
> Secrets like API keys should be stored using the [`_secret`](operators/secret.md) operator.
#### Properties
- `secretKey: string`: __Required__ - Stripe [secret key](https://stripe.com/docs/keys).
- `apiVersion: string`: Stripe API version to use. Defaults to the account-wide version.
- `timeout: number`: Timeout for requests to the Stripe API.
- `maxNetworkRetries: number`: Maximum number of times failed requests are repeated before throwing an error.
- `telemetry: boolean`: Whether to send telemetry data to Stripe (this is forwarded to the Stripe client library. Lowdefy does not receive any telemetry data from your Stripe connection.)
#### Examples
###### Simple connection:
```yaml
connections:
- id: stripe
type: Stripe
properties:
secretKey:
_secret: STRIPE_SECRET_KEY
```
Environment variables:
```
LOWDEFY_SECRET_STRIPE_SECRET_KEY = sk_test_KyvNyie...
```
###### Using an older API version:
```yaml
connections:
- id: stripe
type: Stripe
properties:
secretKey:
_secret: STRIPE_SECRET_KEY
apiVersion: 2017-12-14
```
Environment variables:
```
LOWDEFY_SECRET_STRIPE_SECRET_KEY = sk_test_KyvNyie...
```
## Requests
Request types:
- StripeRequest
### StripeRequest
The `StripeRequest` request allows calls to all modules supported by the [Stripe API client](https://stripe.com/docs/api?lang=node) by nesting the resource and method calls:
```yaml
resource:
method:
- parameter1
- parameter2
```
#### Properties
- `{{ apiResource }}: object`: A Stripe API resource, eg. `customers`.
- `{{ method }}: array | null`: A resource method, eg. `create`. The arguments array will be passed on to the client method.
The Stripe client exposes all resources as objects, with the API methods being available as function properties on those resource objects.
In Lowdefy, you may access these properties by nesting them.
### Examples
###### List the 30 most recent customers
```yaml
requests:
- id: list_customers
type: StripeRequest
connectionId: stripe
properties:
customers:
list:
limit: 30
```
###### Create a payment intent
```yaml
requests:
- id: create_payment_intent
type: StripeRequest
connectionId: stripe
properties:
paymentIntents:
create:
- amount: 2000
currency: eur
payment_method_types: [ card ]
```
###### Retrieve a checkout session by ID
```yaml
requests:
- id: retrieve_checkout_session
type: StripeRequest
connectionId: stripe
properties:
checkout:
sessions:
retrieve:
- cs_test_onpT2icY2lrSU0IgDGXEhhcOHcWeJS5BpLcQGMx0uI9TZHLMBdzvWpvx
```
---
url: https://docs.lowdefy.com/md/connections/treg.md
---
# treg
[treg](https://treg.to) is an open-source catalog of external API endpoints (SEO and SERP data, people and company enrichment, social data, scraping, generation and more) behind one token. treg holds the provider credentials and bills each call from the team's prepaid balance, or runs it on the team's own provider key for free. Its routed endpoints, such as `treg.people.email.find`, try provider after provider for one job and answer with the first hit.
The `TregConnection` connection calls treg from server routines. It is a good provider backend for [enrichment tables](/Table): one connection gives every enrichment column access to the whole catalog, with an exact cost per call.
> Store the token with the [`_secret`](/_secret) operator. `TregCall` spends money, so call it from API endpoints, and bound it with `maxCost` and `idempotencyKey`.
## Connections
Connection types:
- TregConnection
## Requests
Request types:
- TregCall
- TregCatalogSearch
- TregCatalogGet
- TregBalance
### TregConnection
#### Properties
- `token: string`: __Required__ - The treg token, sent as `X-Treg-Token`. Use a per-team token (`treg org agent-new `, or a dashboard API key), which carries its team.
- `org: string`: The team slug, sent as `X-Treg-Org`. Only needed with a personal identity token (from `treg login`).
- `baseUrl: string`: Default: `https://treg.to` - The treg URL, for a self-hosted treg. An `https` URL, or `http` on `localhost`.
- `timeout: integer`: Default: `30000` - The time in milliseconds each HTTP call to treg may take.
- `maxCost: number`: The default spend ceiling per call in USD, sent as `X-Treg-Route-Max-Cost`. treg refuses a call whose reserve would exceed it and charges nothing. treg itself caps routed calls at $1 and direct calls not at all.
- `meta: object`: Default tags for every call, sent as `X-Treg-Meta`, for treg's per-tag usage reports and budgets. Up to 5 pairs; keys are lowercase letters, digits and `_`; values are letters, digits and `. _ - :`. Request `meta` is merged over it.
- `allowCustomTools: boolean`: Default: `false` - Allow `TregCall` to call the team's own registered tools with `tool` and `path`. Without it a request can only reach catalog and routed endpoints.
### TregCall
Calls one treg endpoint by its id, `POST` (or `GET` without a body) to `/call/`.
`endpoint` must be a catalog or routed endpoint id, such as `treg.people.email.find`: lowercase letters, digits, `.`, `_` and `-`. The raw upstream-URL form (`/call/https://…`) is never accepted, because it would let config send any URL through the team's stored credentials. The team's own registered tools are called with `tool` and `path` instead, and only when the connection sets `allowCustomTools: true`.
#### Properties
- `endpoint: string`: The catalog or routed endpoint id to call. Find ids with `TregCatalogSearch`.
- `tool: string`: The name of one of the team's own tools, with `path`. Needs `allowCustomTools` on the connection.
- `path: string`: The path on the tool's API, such as `/v1/charges`. A path only: printable ASCII (also once percent-decoded) with no scheme, host, query, backslash, `.` or `..` segment, whitespace or control characters. A path the URL parser would change (it strips tabs and newlines and resolves `..`) is refused before anything is sent.
- `method: enum`: `GET`, `POST`, `PUT`, `PATCH` or `DELETE`. Defaults to `POST` when `body` is set, otherwise `GET`.
- `query: object`: Query parameters. An array value sends the parameter once per item.
- `body: any`: The JSON request body. A routed endpoint takes its inputs here.
- `idempotencyKey: string`: Sent as `Idempotency-Key`. A repeat of a call with the same key gets treg's stored answer and is not charged again (`replayed: true`, cost 0). treg keeps keys for 24 hours, frees the key of a failed call, and refuses a key reused for a different request with a 422. Use a new key for genuinely new work.
- `maxCost: number`: The spend ceiling for this call in USD, overriding the connection's `maxCost`. On a routed endpoint it bounds the whole waterfall.
- `maxAge: integer`: Only accept a cached answer younger than this many seconds (`X-Treg-Max-Age`).
- `noCache: boolean`: Force a live call instead of a cached answer (`Cache-Control: no-cache`).
- `waterfall: boolean`: Routed endpoints: `false` stops at the first provider that misses. treg falls through to the next provider by default.
- `strictFilters: boolean`: Routed endpoints: `true` refuses with a 422 (nothing charged) instead of answering from a provider that could not apply a filter.
- `meta: object`: Tags for this call, merged over the connection's `meta`.
- `await: object`: Wait for an async task. Without it, a task that is still running returns `pending: true`.
- `timeoutMs: integer`: Default: `60000` - How long to poll, from 100 to 900000.
- `intervalMs: integer`: The wait between polls. Defaults to the interval treg's descriptor names (at least 100), or 2000.
#### Response
```yaml
output: # routed: the job's normalised answer; catalog: the provider body (without _treg)
email: ada@example.com
verified: false
raw: # routed: the serving provider's body; catalog: the provider body as it came
data: { … }
cost: # what treg charged, from X-Treg-Cost-Micro. 0 on the team's own key and on a replay.
micro: 4000
usd: 0.004
callId: call_8f2… # X-Treg-Call-Id: store it with the cost; treg support looks calls up by it
servedBy: hunter.people.email.find
tried: [ … ] # routed: every provider tried, with its outcome and charge
outcome: hit # routed: hit, weak, miss or pending; null for catalog endpoints
cached: false # answered from treg's cache (X-Treg-Cache: hit)
replayed: false # an idempotent replay of an earlier call
pending: false # an async task that is still running (only without await)
task: null # the async task: { id, status, pollEndpoint, reserved }
httpStatus: 200
```
The cost is always what treg reports it charged, never the catalog estimate. An async task is charged only when it succeeds: while it is pending `cost` is 0 and `task.reserved` is the hold, and after `await` it is the reserve treg settles.
#### Async tasks
Generation endpoints, and routed endpoints whose provider is still working after treg's own 60 second wait, answer with a task and an `X-Treg-Async` poll descriptor. With `await`, `TregCall` polls the descriptor's catalog endpoint (`GET /call/