Skip to content
FormsGenerated from the public API

FieldArray

Grouping, repeating and numbering fields across a long form.

@luc/ui/forms

Examples

A section, and repeating rows

`FormSection` groups fields under a heading and a description; the fields inside keep their own `Field` wiring.

Identity

What this run is called.

Add, remove and reorder rows

The array lives in the consumer's form engine; the component owns the controls, the row labels and the keyboard path — and reordering is button-driven on purpose, so no drag gesture is required.

Filters

Each row is one filter; the order is the evaluation order.

A section with an action, in two columns

`actions` puts a control in the heading row — a switch for the whole block — and `columns` lays the fields out in a grid that collapses to one column on a narrow screen.

Universe

Which instruments are in scope.

A fixed-length group

Omitting `onAdd` and `onRemove` makes the group fixed-length: the same layout without controls that would have nothing to do.

Split

Usage

import { FormSection, FieldArray } from "@luc/ui/forms";
<FormSection title="Identity" description="What this run is called.">
  <Input defaultValue="Momentum v3" aria-label="Run name" />
</FormSection>

Package setup — peer requirements, the stylesheet and the provider — is on installation.

API

Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.

Exported symbols
ExportKindSignature
FieldArray9 documented props({ legend, description, count, onAdd, onRemove, onMove, addLabel, minRows, children, className, ...props }: FieldArrayProps) => import("@types/react").JSX.Element
FormSection4 documented props({ title, description, actions, columns, children, className, ...props }: FormSectionProps) => import("@types/react").JSX.Element

FieldArray props

Type: FieldArrayProps

Values the compiler reads from the declaration.

FieldArray props
PropTypeDefaultNotes
addLabel?string | undefined—
childrenReactNode—Rows are rendered by the caller with its own engine's bindings.
countnumber—Current row count. The array itself lives in the consumer's form engine.
description?ReactNode—
legendReactNode—Row label, e.g. `(index) => `Attendee ${index + 1}``.
minRows?number | undefined—
onAdd?(() => void) | undefined—
onMove?((from: number, to: number) => void) | undefined—Reordering is deliberately button-driven — no drag-and-drop in V0.4.
onRemove?((index: number) => void) | undefined—Omit to make the group fixed-length.

FormSection props

Type: FormSectionProps

Values the compiler reads from the declaration.

FormSection props
PropTypeDefaultNotes
actions?ReactNode—Trailing content in the heading row — a toggle, a link, a count.
columns?1 | 2 | 3 | undefined—Column count for the fields inside, from the `sm` breakpoint up.
description?ReactNode—
titleReactNode—

Guidelines

Do

  • Group a long form with `FormSection`: a heading, a description and, from `sm` up, a column count.
  • Reach for `FieldArray` when rows repeat, and keep the array in your form engine — the component owns the controls, not the data.
  • Omit `onAdd` and `onRemove` for a fixed-length group: the same layout without buttons that would have nothing to do.

Don't

  • Number the sections by hand (`1.`, `2.`) — the order is the structure, and a heading keeps it readable when rows move.
  • Store the array inside `FieldArray`; a re-render would lose it, and a form engine already owns it.
  • Add reordering where the order has no meaning.

Accessibility

A section is a real `<section>` with a heading, so a screen-reader user can jump between blocks. Every row control is a real button with a name that says what it does to which row, the row count is announced, and `minRows` stops the group from being emptied when the last row must stay.

Family

Forms

Inputs, their validation surfaces and the form lifecycle around them.

24 documented entries in this family. Open the family index

Luc UI v1.0FieldArraydark theme