Balance Logo
Reckon Design System
Open playroom

Array Field

The ArrayField is a form input for capturing multiple instances of multiple fields, saving valuable screen space.
pnpm add @balance-web/array-field
Import usage
import {
} from '@balance-web/array-field';
  • Code
  • API


This package exposes a number of primitives that can be used to compose a ArrayField.


This is the root primitive of an ArrayField.

Basic usage

All primitives exposed from this package must be used inside ArrayField

<ArrayField>{/* ArrayField primitives */}</ArrayField>

This component has 2 variants:

ordered: Shows the index of an item.

unordered: Does not show the index of an item.


Label for the item user is trying to add.

description (optional)

Description or supporting info required regarding the item the user is trying to add.

It accepts a ReactElement or a string similar to the Field component description.


This primitive renders the list of items user has added.

It's responsible for the following behavious:

  • Collapse all expanded items when a new item is added.
  • Scroll to the newly added item.
  • Focus the first interactive element in a newly added item.
  • Focus the first interactive element when an item is expanded.
Basic usage

This component only accepts an array of ArrayField.Item as children. It will throw an error otherwise.

<ArrayField.Item />
<ArrayField.Item />


  • DONOT conditionally render ArrayField.Items based on if your list has elements or not. Do that inside. ArrayField.Items is the list container and must always be renderred for the behaviours outlined above to work correctly.
  • ArrayField.Items only accepts ArrayField.Item as children. Again, this constraint is for the behaviours outlined above to work correctly.


This primitive renders a single item.

Basic usage

This primitive should only be used inside ArrayField.Items.

A ArrayField item renders a set of relevant fields, based on the item the user is trying to add, as a <fieldset>.

It provides expand/collapse, ability to remove item and some other accessibility features.

label="Emergency contact"
onRemove={() => {
/* remove item from someForm */
<Field label="First name">
<TextInput {...someForm.firstName.props} />
<Field label="Last name">
<TextInput {...someForm.lastName.props} />
<Field label="Mobile">
<TextInput {} />

Index of the item in the list. The index is displayed as a landmark for each item in order to help the user keep track of the list. In most cases this would be a numerical value but any unique sequential id can be used.

This index should not refer to the database ordering of the item.


The ArrayField renders children inside a <Fieldset> under the hood which requires a legend. This legend is mainly for accessibility reasons, it's not displayed to the user.


Handler for the button used to remove the item from the list.


Snapshot information of the item displayed to the user in collapsed state. This should usually be a field or a calculation based on some fields within the item.

collapsedSummary (optional)

Optionally render a ReactNode in collapsed state to display additional information.

<Text size="small" color="muted">
Some supporting information
{/* fields */}

An array of errors related to the item. These errors are only displayed in collapsed state.

In expanded state, the errors should be displayed through the Field component as per usual.

  • The getValidationMessages function from the useForms package can be used to collate all the errors in a form. This is demo'd in the recipes section below.
  • Remember to de-duplicate errors!
<ArrayField.Item errors={['error_1', 'error_2']}>
{/* fields */}


A wrapper component around Button with reduced api surface to make sure the "add button" is rendered consistently.

Basic usage
label="Add thing"
onClick={() => {
/** add thing */

Label for the button. It's passed on directly to the label prop of Button.


Click handler for the button. It's passed on directly to the onClick prop of Button.


Full example of how to compose an ArrayField.

Edit in Playroom
Copyright © 2024 Reckon. Designed and developed in partnership with Thinkmill.
Bitbucket logoJira software logoConfluence logo