Skip to content
Backlit
Esc
navigateopen⌘Jpreview
On this page

Action target

Submit a small action directly or through a dialog.

Use submitTo when an action needs only a button, a confirmation, or a small fixed set of fields.

API

submitTo(action, args?, presentation?)
  .withInitialData(values)
  .setDialog(dialog)
  .setFields(fields)

Pass the action definition directly. submitTo does not accept a thunk. args must contain one defined value for each action parameter.

presentation can be a value or a callback. It supports text, icon, tooltip, skip, disabled, intent, and primary.

  • skip: true removes the complete action.
  • disabled: true sends only a disabled control. Backlit does not resolve args, dialog data, or form data for it.

Missing args on an active action are an authoring error.

Direct action

Do not set a dialog or fields. The renderer sends an empty payload when the person selects the action. It does not mount an HTML form or create RHF state.

submitTo(archiveOrder, [order.id], { text: 'Archive' })

Confirmation dialog

Use setDialog to ask for confirmation. A fieldless confirmation also sends an empty payload and does not create RHF state.

submitTo(cancelOrder, [order.id], { text: 'Cancel order' }).setDialog({
  title: 'Cancel this order?',
  description: 'This action cannot be undone.',
  submitLabel: 'Cancel order',
})

Dialog with fields

Call setFields after setDialog. The field list is stable. Each field can use its normal configuration and can read the current row. Initial values use the same input remapping as a regular form.

submitTo(changeStatus, [order.id], { text: 'Change status' })
  .withInitialData({ status: order.status })
  .setDialog({
    title: 'Change order status',
    submitLabel: 'Save status',
  })
  .setFields(orders.pick('status'))

The dialog mounts the regular form renderer only while it is open. This keeps all RHF behavior in one place.

submitTo does not accept panels, sections, conditions, zones, or a dynamic field list. For a full form, create a view with form() and open that view with visitTo in modal or drawer mode.

Intent and priority

Use intent: 'destructive' when the action removes data that cannot be restored. Other actions use neutral. Intent describes the effect of an action. Use primary: true to mark the main action. These values are presentation; authorize and validate the operation on the server.

Complete controls

import {
  callout,
  defineResource,
  fields,
  linkTo,
  panel,
  submitTo,
  table,
  visitTo,
} from '@backlit/sdk'
import { z } from 'zod'
const orders = defineResource('orders', [
  fields.text('id'),
  fields.text('title'),
])
const detail = orders.view('detail', ['id'], (ctx) =>
  callout(`Order ${ctx.paramValues.id}`)
)
const archive = orders.action(
  'archive',
  ['id'],
  z.object({}),
  (ctx) => ctx.refresh()
)
const rename = orders.action(
  'rename',
  ['id'],
  z.object({ title: z.string().min(1) }),
  (ctx) => ctx.notify(ctx.data.title)
)
orders.view('list', () =>
  panel([
    table([{ id: '42', title: 'Notebook' }])
      .setFields(orders.pick('title'))
      .onRowClick(linkTo(detail, (row) => [row.id]))
      .setRowActions([
        visitTo(detail, (row) => [row.id], {
          text: 'Open',
          mode: 'drawer',
        }),
        submitTo(
          archive,
          (row: { id: string }) => [row.id],
          {
            text: 'Archive',
            intent: 'destructive',
          }
        ).setDialog({
          title: 'Archive this order?',
          submitLabel: 'Archive',
        }),
        submitTo(
          rename,
          (row: { id: string }) => [row.id],
          {
            text: 'Rename',
          }
        )
          .setDialog({ title: 'Rename order' })
          .setFields(orders.pick('title')),
      ]),
  ]).setActions([
    visitTo(detail, ['42'], {
      text: 'Open order',
      mode: 'modal',
    }),
    submitTo(rename, ['42'], {
      text: 'Rename order',
      primary: true,
    })
      .withInitialData({ title: 'Notebook' })
      .setDialog({ title: 'Rename order' })
      .setFields(orders.pick('title')),
  ])
)
export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "list",
    "slots": {
      "content": [
        {
          "kind": "panel",
          "actions": [
            {
              "kind": "visit",
              "resource": "orders",
              "view": "detail",
              "mode": "modal",
              "args": [
                "42"
              ],
              "text": "Open order"
            },
            {
              "kind": "action",
              "form": {
                "kind": "form",
                "target": {
                  "resource": "orders",
                  "action": "rename",
                  "args": [
                    "42"
                  ]
                },
                "slots": {
                  "content": [
                    {
                      "kind": "form-fields",
                      "fields": [
                        {
                          "kind": "text",
                          "name": "title",
                          "label": ""
                        }
                      ]
                    }
                  ]
                },
                "initial": {
                  "title": "Notebook"
                }
              },
              "text": "Rename order",
              "primary": true,
              "dialog": {
                "title": "Rename order"
              }
            }
          ],
          "slots": {
            "content": [
              {
                "kind": "table",
                "fields": [
                  {
                    "kind": "text",
                    "name": "title",
                    "label": ""
                  }
                ],
                "targets": [
                  {
                    "kind": "link",
                    "resource": "orders",
                    "view": "detail"
                  },
                  {
                    "kind": "visit",
                    "resource": "orders",
                    "view": "detail",
                    "mode": "drawer"
                  },
                  {
                    "kind": "action",
                    "form": {
                      "kind": "form",
                      "target": {
                        "resource": "orders",
                        "action": "archive"
                      },
                      "slots": {
                        "content": []
                      }
                    }
                  },
                  {
                    "kind": "action",
                    "form": {
                      "kind": "form",
                      "target": {
                        "resource": "orders",
                        "action": "rename"
                      },
                      "slots": {
                        "content": [
                          {
                            "kind": "form-fields",
                            "fields": [
                              {
                                "kind": "text",
                                "name": "title",
                                "label": ""
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                ],
                "data": [
                  {
                    "title": "Notebook",
                    "$click": {
                      "target": 0,
                      "args": [
                        "42"
                      ]
                    },
                    "$actions": [
                      {
                        "target": 1,
                        "args": [
                          "42"
                        ],
                        "text": "Open"
                      },
                      {
                        "target": 2,
                        "text": "Archive",
                        "intent": "destructive",
                        "dialog": {
                          "title": "Archive this order?"
                        },
                        "form": {
                          "target": {
                            "args": [
                              "42"
                            ]
                          },
                          "submit": {
                            "label": "Archive"
                          }
                        }
                      },
                      {
                        "target": 3,
                        "text": "Rename",
                        "dialog": {
                          "title": "Rename order"
                        },
                        "form": {
                          "target": {
                            "args": [
                              "42"
                            ]
                          },
                          "initial": {
                            "title": "Notebook"
                          }
                        }
                      }
                    ]
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  }
}

Was this page helpful?