Skip to content

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:

Button.tsx
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:

  1. Add a prop in our interface for the repeated buttons
  2. Add a <Repeater> component in the rendered JSX where items should appear
  3. Add the repeaterProps in the brick’s schema to specify the type of brick to be repeated

1. Add a prop in the brick interface:

TextImage.tsx
interface TextImageProps {
title: types.TextValue
description: types.TextValue
image: types.IImageSource
buttons: types.RepeaterItems<ButtonProps>
}

2. Add the Repeater component:

TextImage.tsx
// ...
<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.tsx
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

PropertyDefinition
propNameName of the prop containing the repeated items (should match the one in the repeaterItems schema property)
itemsThe 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

PropertyDefinition
nameName of the prop containing the repeated items (e.g., “buttons”)
itemTypeCorresponds 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
minMinimum number of repeated items allowed
maxMaximum number of repeated items allowed
getDefaultPropsFunction 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”.
itemsAllowed 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 and max, the root item’s min is ignored, while the overall max 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.