UI steps

UI steps

UI steps pause execution of the flow and displays UI to the user. UI steps are used to collect user input or to display information to the user.

Use ctx.ui.page() to create a UI step

const values = await ctx.ui.page("userInfo", {
  stage: "stage1",
  title: "User Info",
  content: [
    ctx.ui.inputs.text("name", { label: "Your name" }),
    ctx.ui.inputs.number("age", { label: "Your age" }),
  ],
});

A page is built up from UI elements. These element are available via the ctx.ui object.

Input elements

Display elements

Select elements

Interactive elements

Layout elements

Response data

Pages with inputs will return data. The response data will be an object with the keys being the names of the inputs and the values being the values of the inputs.

const values = await ctx.ui.page("userInfo", {
  content: [
    ctx.ui.inputs.text("name", { label: "Your name" }),
    ctx.ui.inputs.number("age", { label: "Your age" }),
  ],
});
 
console.log(values);
// { name: "John Doe", age: 30 }

If you have custom actions defined, the repsonse will be the action key and a data property with the response data.

const values = await ctx.ui.page("userInfo", {
  actions: [
    { label: "Continue", value: "continue", mode: "primary" },
    { label: "Cancel", value: "cancel" },
  ],
  content: [
    ctx.ui.inputs.text("name", { label: "Your name" }),
    ctx.ui.inputs.number("age", { label: "Your age" }),
  ],
});
 
console.log(values);
// { action: "continue", data: { name: "John Doe", age: 30 } }

Conditional visibility

Use visibility to show an element only when a rule over the page's inputs is true:

const values = await ctx.ui.page("delivery", {
  content: [
    ctx.ui.inputs.boolean("isExpress", { label: "Express delivery" }),
    ctx.ui.inputs.text("courierNotes", { label: "Courier notes" }),
  ],
  visibility: {
    courierNotes: "inputs.isExpress == true",
  },
});
 
console.log(values);
// { isExpress: false }

Hidden inputs aren't validated and are left out of the response data, so targeted inputs are typed T | undefined. See Conditional visibility for the rule syntax, iterators and display elements.

Page configuration


title
string

Title displayed at the top of the page.


description
string

Short description or subtitle for the page.


content
UIElements[]

An array of elements that make up the body of the page.

stage
string

(Optional) The flow stage this page belongs to. Used for organizing multi-stage flows. For more information on stages, see Showing progress.


validate
(data) => Promise<true | string>

Optional async validation function applied to the entire form's data. Returns a string error message.


actions
({ label: string; value: string; mode?: "primary" | "secondary" | "destructive" } | string)[]

Defines what actions are shown at the bottom of the page.


visibility
Record<string, string>

Rules that control when elements on the page are shown. Each key is an input or iterator name, or a display element's key. Each value is a rule over the page's inputs, such as "inputs.isExpress == true". See Conditional visibility.

Usage

await ctx.ui.page({
  stage: "setup",
  title: "Configure Workspace",
  description: "Set up your project preferences.",
  content: [
    ctx.ui.input.text("projectName", { label: "Project Name" }),
    ctx.ui.input.boolean("notifications", {
      label: "Enable Notifications",
      defaultValue: true,
    }),
  ],
  actions: [
    { label: "Continue", value: "continue", mode: "primary" },
    { label: "Cancel", value: "cancel" },
  ],
  validate: async (data) => {
    if (!data.projectName) return "Project name is required";
    return true;
  },
});