Create Flow Builder Custom Property Editors That Access Automatic Outputs

Custom property editors can access automatic outputs, which makes it easy to use upstream variable values as options for input fields later in a flow. Previously, custom property editors could access only values that admins manually assigned to flow variables.

Where: This change applies to Lightning web components in Lightning Experience.

Why: You no longer introspect and describe every element in a flow to include upstream variables in picklists and other input fields.

How: In your custom property editor, expose a public property called automaticOutputVariables. When the custom property editor is initialized or when the admin changes a value in the custom property editor, Flow Builder passes the automatically stored values to automaticOutputVariables.

Write custom logic so that when an admin sets a value for a field such as a combo box or picklist, the automatically stored values appear as input options.

// myCustomPropertyEditor.js 
import { LightningElement, api } from 'lwc'; 
export default class MyCustomPropertyEditor extends LightningElement { 
    @api automaticOutputVariables;
    
    //Insert custom logic.
}

For example, this custom property editor gets a list of merge fields from automaticOutputVariables and displays them as input options for the Phone field. In this case, the merge fields are standard phone components for Home and Mobile.

Custom property editor that highights automatically stored values as options in a combo box

The data structure passed into the custom property editor via automaticOutputVariables describes the automatically stored values. In our example, the flow has two standard phone components with the API names Home and Mobile, so Flow Builder passes this data into the custom property editor.

    "Home":[
        {
            "apiName":"label",
            "dataType":"string",
            "description":"The label that appears above the phone field.",
            "hasDefaultValue":true,
            "isRequired":true,
            "label":"Label",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1,
            "defaultValue":"Home"
        },

        {
            "apiName":"pattern",
            "dataType":"string",
            "description":"To require the value to follow a specific pattern, use the Inputs tab to set this attribute's value to a regular expression.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Pattern",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        },
        {
            "apiName":"placeholder",
            "dataType":"string",
            "description":"Text that appears in the field when it's empty. Use placeholder text to give users a hint about what to enter in the field.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Placeholder text",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        },
        {
            "apiName":"readonly",
            "dataType":"boolean",
            "description":"Prevents the user from modifying the value, but not from copying it.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Read Only",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        },
        {
            "apiName":"required",
            "dataType":"boolean",
            "description":"Requires the user to enter a value.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Required",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        },
        {
            "apiName":"value",
            "dataType":"string",
            "description":"The value of the phone field. To pre-populate the field, use the Inputs tab to set this attribute's value. To use the value elsewhere in your flow, use the Outputs tab to pass this attribute's value to a variable.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Value",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        }
    ]
    "Mobile":[
        {
            "apiName":"label",
            "dataType":"string",
            "description":"The label that appears above the phone field.",
            "hasDefaultValue":true,
            "isRequired":true,
            "label":"Label",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1,
            "defaultValue":"Mobile"
        },
        {
            "apiName":"pattern",
            "dataType":"string",
            "description":"To require the value to follow a specific pattern, use the Inputs tab to set this attribute's value to a regular expression.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Pattern",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        },
        {
            "apiName":"placeholder",
            "dataType":"string",
            "description":"Text that appears in the field when it's empty. Use placeholder text to give users a hint about what to enter in the field.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Placeholder text",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        },
        {
            "apiName":"readonly",
            "dataType":"boolean",
            "description":"Prevents the user from modifying the value, but not from copying it.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Read Only",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        },
        {
            "apiName":"required",
            "dataType":"boolean",
            "description":"Requires the user to enter a value.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Required",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        },
        {
            "apiName":"value",
            "dataType":"string",
            "description":"The value of the phone field. To pre-populate the field, use the Inputs tab to set this attribute's value. To use the value elsewhere in your flow, use the Outputs tab to pass this attribute's value to a variable.",
            "hasDefaultValue":false,
            "isRequired":false,
            "label":"Value",
            "isInput":true,
            "isOutput":true,
            "maxOccurs":1
        }
    ]
}