Balance Logo
Balance
Reckon Design System
Open playroom

Array Field

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

Primitives

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

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>
variant

This component has 2 variants:

ordered: Shows the index of an item.

unordered: Does not show the index of an item.

label

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.

ArrayField.Items

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.Items>
<ArrayField.Item />
<ArrayField.Item />
</ArrayField.Items>

Constraints:

  • 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.

ArrayField.Item

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.

<ArrayField.Item
index={1}
label="Emergency contact"
onRemove={() => {
/* remove item from someForm */
}}
collapsedTitle={someForm.firstName.value}
>
<FieldStack>
<Field label="First name">
<TextInput {...someForm.firstName.props} />
</Field>
<Field label="Last name">
<TextInput {...someForm.lastName.props} />
</Field>
<Field label="Mobile">
<TextInput {...someForm.mobile.props} />
</Field>
</FieldStack>
</ArrayField.Item>
index

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.

legend

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.

onRemove

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

collapsedTitle

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.

<ArrayField.Item
collapsedSummary={
<Text size="small" color="muted">
Some supporting information
</Text>
}
>
{/* fields */}
</ArrayField.Item>
errors

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 */}
</ArrayField.Item>

ArrayField.AddButton

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

Basic usage
<ArrayField.AddButton
label="Add thing"
onClick={() => {
/** add thing */
}}
/>
label

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

onClick

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

Receipes

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