<- Back to Forms Components

EditableList edits a list as visible rows. Use it when every item should stay directly editable instead of being compressed into chips.

The current contract supports lists of strings. Each row is either a text input or a select input, depending on item_schema.

Contract

Property Type Notes
value list[str] Current row values. Supports literal, store binding, and data-model binding.
item_label str Label shown above the list.
add_label str Add button label. Defaults to Add.
remove_label str Remove button label. Defaults to Remove.
submit_label str Save button label. Defaults to Save.
placeholder str Placeholder for text rows.
item_schema dict Required. Describes each row input.
action / params str or action object / dict Optional action emitted by the save button.
track_loading str or list[str] Action names used to show save loading state.

Collected value: list[str].

Item Schema

item_schema.type Row input Notes
text Text input Row value is the entered string.
select Select input options is required. Each option must define string label and string value.

item_schema is required. There is no default row type.

Example

field = sdk.ui.EditableList(
    "components_test_editable_list_store",
    item_label="EditableList store",
    value=bound.store(
        "/components_test/list_inputs/editable_list/store",
        scope="page",
        default=["chat"],
    ),
    add_label="Add capability",
    remove_label="Remove",
    submit_label="Save",
    item_schema={"type": "select", "options": capability_options},
)
field.set_show_if({
    "left": bound.store("/components_test/list_inputs/editable_list/show", scope="page", default=True),
    "op": "==",
    "right": True,
})
field.set_hide_if({
    "left": bound.store("/components_test/list_inputs/editable_list/hide", scope="page", default=False),
    "op": "==",
    "right": True,
})
field.set_required_permissions(["components.content.view"])

Data Model Binding

sdk.ui.EditableList(
    "components_test_editable_list_data",
    item_label="EditableList data",
    value=bound.data("/components_test/list_inputs/editable_list/data", default=["reasoning"]),
    add_label="Add capability",
    remove_label="Remove",
    submit_label="Save",
    item_schema={"type": "select", "options": capability_options},
)

Direct Property Update

Declare value.set before sending direct property updates to value.

field = sdk.ui.EditableList(
    "components_test_editable_list_live",
    item_label="EditableList property update",
    value=["chat"],
    add_label="Add capability",
    remove_label="Remove",
    submit_label="Save",
    item_schema={"type": "select", "options": capability_options},
)
field.allow("value.set")

Form Field

Inside Form.model, use type: editable_list. The field accepts the same item_schema contract as the standalone component.

- name: capabilities
  label: Capabilities
  type: editable_list
  value: ["chat"]
  add_label: Add capability
  remove_label: Remove
  submit_label: Save
  item_schema:
    type: select
    options:
      - label: Chat
        value: chat