FormRow

How a form is laid out: a two-column grid, and an inline-edit row.

Overview

FormGrid lays Fields out in two columns; FormRow puts several controls and a save button on one line.

Inline edit

Do

Press Save to apply the change.

import { Button, FormRow, FormRowField, Input } from "@hackcove/ui";

<FormRow hint="Press Save to apply the change." action={<Button>Save</Button>}>
  <FormRowField label="Description" htmlFor="do-row-desc" span={3}>
    <Input id="do-row-desc" defaultValue="Kitchen renovation" />
  </FormRowField>
  <FormRowField label="Amount" htmlFor="do-row-amount">
    <Input id="do-row-amount" defaultValue="12,400.00" align="end" />
  </FormRowField>
</FormRow>
A row of controls with proportional widths, an action after them, and one hint under the whole row.
Don't

Shown on the invoice.

import { Button, Field, FormRow, Input } from "@hackcove/ui";

<FormRow action={<Button>Save</Button>}>
  <Field label="Description" htmlFor="dont-row-desc" hint="Shown on the invoice.">
    <Input id="dont-row-desc" defaultValue="Kitchen renovation" />
  </Field>
  <Field label="Amount" htmlFor="dont-row-amount">
    <Input id="dont-row-amount" defaultValue="12,400.00" align="end" />
  </Field>
</FormRow>
A Field with its own hint inside a FormRow makes its column taller, so the controls drift out of line and the save button with them.

Two columns

Do
import { Field, FormGrid, Input, Textarea } from "@hackcove/ui";

<FormGrid>
  <Field label="First name" htmlFor="do-grid-first">
    <Input id="do-grid-first" />
  </Field>
  <Field label="Last name" htmlFor="do-grid-last">
    <Input id="do-grid-last" />
  </Field>
  <Field label="Notes" htmlFor="do-grid-notes" span="full">
    <Textarea id="do-grid-notes" />
  </Field>
</FormGrid>
A FormGrid is two columns from md; a long control takes span="full" so it runs across both.
Don't
import { Field, FormGrid, Input, Textarea } from "@hackcove/ui";

<FormGrid>
  <Field label="First name" htmlFor="dont-grid-first">
    <Input id="dont-grid-first" />
  </Field>
  <Field label="Last name" htmlFor="dont-grid-last">
    <Input id="dont-grid-last" />
  </Field>
  <Field label="Notes" htmlFor="dont-grid-notes">
    <Textarea id="dont-grid-notes" />
  </Field>
</FormGrid>
Without span="full" a Textarea takes half the width and leaves a hole beside it.

Usage

  • A form of several fields is a FormGrid of Fields: two columns from md, one below. A long control, such as a Textarea, takes span="full".
  • A line of controls to edit one record in place is a FormRow of FormRowFields, with the save Button as action.
  • FormRowField span 1 to 4 is its share of the row's width.
  • The hint or error goes on the FormRow, once, under the whole line. A FormRowField has no hint or error, and a Field does not belong inside a FormRow.
  • A FormRow inside a FormGrid runs across both columns.

Accessibility

  • FormRowField renders a <label> tied to its control by htmlFor, as Field does.
  • The row's error is a <p role="alert">.
  • Under md the fields and the action stack in reading order.

API

FormRow

An inline-edit row: several controls side by side with proportional widths (FormRowField span 1 to 4), an optional action after them (a save button), and one hint or error line under the whole row. Every control sits on the bottom edge, so the action lines up with them whatever the labels do. Under md the fields and the action stack. The row owns the note, so the fields beside each other keep their height: a FormRowField has no hint or error of its own.


action

A button or two after the last field. It keeps its own width.

Type
ReactNode

error

Replaces the hint when set, as Field's does.

Type
ReactNode

hint
Type
ReactNode

FormRowField

A compact label over one control, for a FormRow. span is its share of the row (1 default).


htmlFor required

The id of the control inside; the label's htmlFor.

Type
string

label required
Type
ReactNode

span
Type
1 | 2 | 3 | 4
Default
1

FormGrid

Two columns of Fields from md, one below it. A Field takes one column; span="full" runs it across both, and a FormRow is always full width.