Kanzo UI
Forms

Field Array

Repeatable rows — N controls, a remove per row, and one add below.

Usage

import { FieldArray } from "@kanzo-tech/ui";
<FieldArray
  count={values.length}
  rowKey={(index) => `party#${index}`}
  onAdd={() => …}
  onRemove={(index) => …}
>
  {(index) => <Input value={values[index]} onChange={…} />}
</FieldArray>

Deliberately stateless and unaware of cardinality: it renders exactly count rows and reports intent. Whoever owns the data decides what "add" means and whether another row is allowed — which is what lets the same component sit on a form library, a plain array or a graph.

rowKey is required, and must never be the bare index. A row that is only a UI placeholder has to already carry the key it will have once committed; if the key changes on commit, React remounts the input and the user loses focus and caret mid-typing.

Limits

canAdd and canRemove hide the controls rather than disabling them — a maximum that is already reached does not need a dead button.

1/5 on the party — “Add” hides at the maximum, and the last remaining row keeps its remove control hidden.

Block rows

align="start" for rows whose content is a block — a textarea, or a nested form — so the remove control sits at the top rather than floating in the middle.

API Reference

PropTypeDefault
countnumber
rowKey(index: number) => string
children(index: number) => ReactNode
onAdd() => void
onRemove(index: number) => void
canAddbooleantrue
canRemovebooleantrue
addLabelReactNode"Add"
removeLabelstring"Remove"
align"center" | "start""center"
classNamestring

FieldArrayProps is exported, so a wrapper can take the same props without restating them.

On this page