lzb.constructor.panels
Filters the collapsible panels the block builder puts in the Inspector under the general settings. Add a panel here when an extension keeps its own data on the block and needs somewhere in the builder to edit it.
The default array holds four panels in this order: style-variations, supports, supports-ghost-kit and condition. All four start collapsed.
Attributes
| Name | Type | Description |
|---|---|---|
panels | Array | panel definitions, rendered in array order |
data | Object | blockData, updateBlockData |
Each panel is an object with four keys:
| Name | Type | Description |
|---|---|---|
name | String | React key of the panel, and the handle other extensions match on |
title | String | heading shown on the panel |
component | Function | React component type, rendered with data and updateData props |
initialOpen | Boolean | whether the panel is expanded on first render |
component is the component itself, not an element. The builder writes <PanelComponent data={blockData} updateData={updateBlockData} /> inside a PanelBody, so a panel that sets component to <MyPanel /> hands React an element where it expects a type and nothing renders.
data.updateBlockData shallow merges the object you give it into the block data, so a panel writes one field with updateData({ my_field: value }).
Usage
The Relationships panel finds the condition panel and splices itself in after it, which keeps the ordering stable when other extensions add panels too.
const { TextControl } = wp.components;
function TrackingPanel({ data, updateData }) {
return (
<TextControl
label="Tracking ID"
value={data.my_tracking_id || ""}
onChange={(value) => updateData({ my_tracking_id: value })}
/>
);
}
wp.hooks.addFilter(
"lzb.constructor.panels",
"my.custom.namespace",
function (panels) {
const conditionIndex = panels.findIndex(
(panel) => panel.name === "condition",
);
const insertIndex =
conditionIndex === -1 ? panels.length : conditionIndex + 1;
panels.splice(insertIndex, 0, {
name: "my-tracking",
title: "Tracking",
component: TrackingPanel,
initialOpen: false,
});
return panels;
},
);The builder calls panels.map() on the result, so returning anything but an array throws panels.map is not a function and leaves the block builder Inspector blank. A handler that decides to do nothing must return the incoming panels.