---
title: "lzb.constructor.control.settings-rows"
description: "JS filter `lzb.constructor.control.settings-rows` of the Lazy Blocks WordPress plugin."
url: "https://www.lazyblocks.com/docs/js-filters/lzb-constructor-control-settings-rows/"
source: "js-filters/lzb-constructor-control-settings-rows.mdx"
---
# lzb.constructor.control.settings-rows

Filters the rows of the control settings sidebar, the panel that opens in the block builder when a control is selected. Add a row when a control needs a setting the plugin does not ship, or rebuild the object to put your row next to a related one.

## Attributes

| Name              | Type       | Description                                                 |
| ----------------- | ---------- | ----------------------------------------------------------- |
| `rows`            | **Object** | row components keyed by setting name, rendered in key order |
| `props`           | **Object** | `updateData`, `data`, `id`                                  |
| `controlTypeData` | **Object** | registration data of the selected control type              |

`rows` holds 14 keys by default, in this order: `label`, `name`, `type`, `control_specific_rows`, `default`, `help`, `placement`, `group`, `width`, `required`, `hide_if_not_selected`, `translate`, `save_in_meta`, `pro_notice`. Every value is a React component type, not an element, and each one is rendered with `controlTypeData` plus everything in `props`.

`props.data` holds the settings of the selected control, `props.id` its uid, and `props.updateData` writes changes back to it.

`controlTypeData` comes from the control type registry and carries `name`, `icon`, `type`, `label`, `category`, `restrictions` and `attributes`.

Before rendering a row the builder reads `controlTypeData.restrictions[key + '_settings']` and skips the row when that value is false. A key you add has no matching restriction, so your row shows for every control type. Guard on `props.data.type` when it only makes sense for one of them.

## Usage

Key order is render order, so rebuilding the object is how a row lands at a chosen position. Conditional Logic appends its key to the end, and the Rich Text component inserts its notice directly after `name` this way.

```js title="JS"
const { TextControl } = wp.components;

function CharactersLimitRow({ data, updateData }) {
  return (
    <TextControl
      label="Characters limit"
      type="number"
      value={data.my_characters_limit || ""}
      onChange={(value) => updateData({ my_characters_limit: value })}
    />
  );
}

wp.hooks.addFilter(
  "lzb.constructor.control.settings-rows",
  "my.custom.namespace",
  function (rows, props) {
    if (props.data.type !== "text") {
      return rows;
    }

    const result = {};

    Object.keys(rows).forEach((key) => {
      result[key] = rows[key];

      if (key === "default") {
        result.my_characters_limit = CharactersLimitRow;
      }
    });

    return result;
  },
);
```

The filter runs only while a control is selected, and the result goes straight into `Object.keys()`. Returning `null` throws `Cannot convert undefined or null to object` and the settings sidebar stops rendering, so return the incoming `rows` when a handler has nothing to change.

## Documentation Index
> Fetch the complete documentation index at: https://www.lazyblocks.com/llms.txt
> Fetch every page in a single file at: https://www.lazyblocks.com/llms-full.txt
