Repeater
React Bricks allows for infinite nesting of bricks within bricks using the <Repeater>
component.
Each Repeater can contain either a single repeatable brick type or multiple types.
Usage example
Let’s consider the following “Button” brick that we want to repeat inside a “TextImage” brick:
import { types, Link, Text } from 'react-bricks/frontend'import clsx from 'clsx'
export interface ButtonProps { path: string buttonText: types.TextValue}
const Button: types.Brick<ButtonProps> = ({ path, buttonText }) => ( <div> <Link href={path} className="inline-block text-center font-semibold leading-6 rounded-full px-8 py-3 border text-white bg-indigo-500 hover:bg-indigo-500/90 transition-colors border-indigo-500" > <Text propName="buttonText" value={buttonText} placeholder="Type a buttonText..." renderBlock={({ children }) => <span>{children}</span>} /> </Link> </div>)
Button.schema = { name: 'my-button', label: 'Button', hideFromAddMenu: true, getDefaultProps: () => ({ buttonText: 'Learn more', }), sideEditProps: [ { name: 'path', label: 'Path', type: types.SideEditPropType.Text }, ],}
export default Button
In our TextImage brick, we need to:
- Add a prop in our interface for the repeated buttons
- Add a
<Repeater>
component in the rendered JSX where items should appear - Add the
repeaterProps
in the brick’sschema
to specify the type of brick to be repeated
1. Add a prop in the brick interface:
interface TextImageProps { title: types.TextValue description: types.TextValue image: types.IImageSource buttons: types.RepeaterItems<ButtonProps>}
2. Add the Repeater
component:
// ...<Repeater propName="buttons" items={buttons} renderWrapper={(items) => ( <div className="flex gap-4 flex-wrap mt-6">{items}</div> )}/>// ...
3. Add repeaterItems
in the schema
TextImage.schema = { name: 'text-image', label: 'Text Image', ... repeaterItems: [ { name: 'buttons', itemType: 'my-button', itemLabel: 'Button', max: 2, }, ], ...}
Note that the name buttons
is the same for both the Repeater’s propName
and the item name in the repeaterItems
.
In this example, our Repeater allows only one type of brick to be repeated (my-button
). By setting max: 2
, we limit the number of buttons that can be added in the repeater.
Repeater Properties
interface RepeaterProps { propName: string items?: types.RepeaterItems<T> itemProps?: types.Props renderWrapper?: (items: React.ReactElement) => React.ReactElement renderItemWrapper?: ( item: React.ReactElement, index?: number, itemsCount?: number ) => React.ReactElement}
Repeater Properties definition
Property | Definition |
---|---|
propName | Name of the prop containing the repeated items (should match the one in the repeaterItems schema property) |
items | The value of the prop for this repeater, containing the repeated items. Required for Server Components, but always recommended for RSC compatibility |
itemProps? | Optional object with props passed to all the items (e.g., a global configuration shared by all the items). |
renderWrapper? | Optional function taking items as an argument. It should return JSX that wraps the items. Rendered only if there is at least one repeated item. |
renderItemWrapper? | Optional wrapper around each item. Takes item , index and itemsCount as arguments and should return JSX |
The schema’s repeaterItems
Property
While there’s a dedicated section in the docs about the bricks’ schema, we’ll include the interface for repeaterItems
here due to its close relation to the Repeater component.
repeaterItems?: IRepeaterItem[]
Where IRepeaterItem
is defined as:
interface IRepeaterItem { name: string label?: string itemType?: string itemLabel?: string defaultOpen?: boolean min?: number max?: number positionLabel?: string // DEPRECATED => use "label" getDefaultProps?: () => Props items?: { type: string label?: string min?: number max?: number getDefaultProps?: () => Props }[]}
When max
is reached, no more blocks can be added to the repeater.
Setting a min
ensures that React Bricks always maintains at least that number of blocks (adding items with default values).
RepeaterItem Properties definition
Property | Definition |
---|---|
name | Name of the prop containing the repeated items (e.g., “buttons”) |
itemType | Corresponds to the unique name of the repeated Brick type (e.g., “my-button”) |
label? | Label for the group of items in this repeater (title of nested items) |
itemLabel? | Optional label used for the Add / Remove buttons. If not provided, the repeated brick’s label is used as a fallback |
min | Minimum number of repeated items allowed |
max | Maximum number of repeated items allowed |
getDefaultProps | Function that returns the default props for the repeated brick inside of this brick. For example, for a Button brick repeated inside a Form brick, you could specify that the default type should be “submit” instead of “link”. |
items | Allowed item types, when multiple. In this case the main itemType and min are not considered. Each item has its own type , label , min , max and getDefaultProps . |
Multiple item types
itemType
is used for a single type of brick that can be repeated in a Repeater (e.g. a Thumbnail in a Gallery).items
is used for multiple types of brick in a Reapear (e.g., in a Form you may add “TextInput” blocks or “Select” blocks).- With multiple item types, each with its own
min
andmax
, the root item’smin
is ignored, while the overallmax
is still enforced.
Hiding a Repeated Brick from the Brick Selection
Sometimes a brick is designed to be used only within another brick, and you don’t want editors to add it directly to a page as a standalone element. For example, you might have a GalleryImage
brick that should only appear inside a Gallery
brick.
To prevent such a brick from showing up in the list of available bricks when adding a new block, set hideFromAddMenu: true
in the brick’s Schema.
Usage with Server components
When working with Server Components, you need to import from 'react-bricks/rsc'
:
import { types, Repeater, Text } from 'react-bricks/rsc'
see more in the Server Components documentation.