---
tags: architecture,content,rebuild
---

library display is a currently bit off as it is using a to be deprecated version of the TextInput

> **FormGroup** lets you create form groups consisting of input details and accepts error information for accessibly displaying errors. It takes children which is where you should setup your input

`import { FormGroup } from '@bulb/design/components/FormGroup';`

## Basic FormGroup

The `id` and `label` props are required strings.

```react
<FormGroup id="name" label="Your name" status="unknown">
  {renderProps => <TextInput id={renderProps.id} />}
</FormGroup>
```

## Render Props

The FormGroup provides a render props to help adding accessibility props and avoid id and other property misspellings.

For all form group states it passes the id and status props.

For the error state it also provides a fieldProps props which contains accessibility props to be added to the field.

```code
<FormGroup id={'example-formgroup'} label="example input" status="unknown">
  {renderProps => {
    if (renderProps.status === 'invalid') {
      return <TextInput id={renderProps.id} {...renderProps.fieldProps} />;
    }
    return <TextInput id={renderProps.id} />;
  }}
</FormGroup>
```

## Add a description

For more difficult form group, you can include a description. This forms part of the label, so is accessible to screen readers.

```react
<FormGroup
  id="name"
  label="Account number"
  description="This is found at the top of your bill."
  placeholder="e.g. 6736453"
  status="unknown"
>
  {renderProps => <TextInput id={renderProps.id} />}
</FormGroup>
```

## Change spacing

For a form group which you want to visually distinguish you can use the `spacing` prop.

This defaults to moon and takes a step from the space scale, it applies spacing vertically and horizontally.

```react
<FormGroup
  id="name"
  label="Account number"
  description="This is found at the top of your bill."
  status="unknown"
  spacing="earth"
>
  {renderProps => <TextInput id={renderProps.id} />}
</FormGroup>
```

## Change label size

For a form group which you want to visually distinguish you can use the `labelTypeStep` prop.

This defaults to mouse and takes a step from the type scale

```react
<FormGroup
  id="name"
  label="Account number"
  description="This is found at the top of your bill."
  status="unknown"
  labelTypeStep="dolphin"
>
  {renderProps => <TextInput id={renderProps.id} />}
</FormGroup>
```

## Errors

To indicate an error with the form group you set the status prop to `invalid` and pass a message via the `errorMessage` prop.

If a message is passed, it is displayed under the children, which should have their input set to the `aria-invalid="true"` state and `aria-describedby="{id}-error"`. The error message is accessibly associated with the input field using `aria-describedby`.

```react
<FormGroup
  id="name"
  label="Account number"
  description="This is found at the top of your bill."
  errorMessage="Your account number should have 7 digits."
  status="invalid"
>
  {renderProps => {
    if (renderProps.status === 'invalid') {
      return (
        <TextInput
          id={renderProps.id}
          {...renderProps.fieldProps}
          status={renderProps.status === 'invalid' ? 'invalid' : undefined}
        />
      );
    }
    return <TextInput id={renderProps.id} />;
  }}
</FormGroup>
```

## Validated

To indicate an form group has been validated you set the status prop to `valid`

```react
<FormGroup
  id="name"
  label="Account number"
  description="This is found at the top of your bill."
  status="valid"
>
  {renderProps => <TextInput id={renderProps.id} />}
</FormGroup>
```

## Hidden `<label>`

You can hide the label visually without it becoming hidden to assistive technologies using the `hideLabelInaccessibly` prop.

**IMPORTANT:** This technique makes the label _only_ accessible to assistive technologies. It is strongly recommended against because sighted users all benefit from a persistent label. The `placeholder` is not a worthy substitute in most cases.

```react
<FormGroup
  id="password"
  label="Enter your postcode"
  hideLabelInaccessibly={true}
  status="unknown"
>
  {renderProps => <TextInput id={renderProps.id} />}
</FormGroup>
```

## LabelIsDecorative

If a label applies to a list of input items -- like radio buttons -- then the main label should be considered decorative. This is because the group id will not point to a valid input id, in which case we're rendering invalid html. When `labelIsDecorative` is applied, the `label` element is instead rendered as a `div`.

```react
<FormGroup
  id="password"
  label="Enter your postcode"
  labelIsDecorative={true}
  status="unknown"
>
  {() =>
    props.possibleValues.map(input => (
      <div>
        <label htmlFor={input.id}>{input.label}</label>
        <input
          type="radio"
          name={input.id}
          id={input.id}
          value={input.value}
        />
      </div>
    ))
  }
</FormGroup>
```
