Cheat Sheet for React Bootstrap. Layout and Forms
Published: 2024-07-03 11:54:08

## Table of contents

1. [Breakpoints](#breakpoints)
2. [Grid system](#grid-system)
3. [Container](#container)
4. [Row](#row)
5. [Col](#col)
6. [Stacks](#stacks)
8. [Forms](#forms)
 9. [Form props](#form-props)
 10. [Form.Label props](#form.label-props)
 11. [fieldset props](#fieldset-props)
 12. [Form.Control props](#form.control-props)
 13. [Form.Text props](#form.text-props)
 14. [Form.Select](#form.select)
 15. [Form.Check](#form.check)
 16. [Floating labels](#floating-labels)
 17. [Form Layout](#form-layout)
 18. [Validation](#validation)

## Breakpoints

- **xs**(X-Small) <576px
- **sm**(Small)	≥576px
- **md**(Medium) ≥768px
- **lg**(Large)	≥992px
- **xl**(Extra large) ≥1200px
- **xxl**(Extra extra large) ≥1400px

## Grid system

### Container

- element with Bootstrap's `container` class:

```html
<Container style={{border: '1px solid black'}}>
  <Row>
    <Col>1 of 1</Col>
  </Row>
</Container>
```

#### Container props

- **fluid={true/'sm'/'md'/'lg'/'xl'/'xxl'}** - Container fills all available horizontal space until the specified breakpoint;

### Row

#### Row props

- **xs={number/'auto'}** - number indicates how many columns can fit in one row on extra small devices;
- **{breakpoint}={number/'auto'}**;



### Col
`Row` is a flexbox with 12 template columns, so we can set how many template columns each `Col` occupies.

#### Col props

- **{breakpoint}={number/'auto'}** - number indicates how many template columns Col can occupy in one row;
- **{breakpoint}={span: number, offset: number, order: {"first"/"last"/number}}** - `span` indicates number of template columns to occupy, `offset` indicates how  many template columns to omit before starting Col.

## Stacks

Full-width flexbox with column direction by default:

```html
<Stack direction="horizontal" gap={3}>
  <div className="p-2">First item</div>
  <div className="p-2 ms-auto">Second item</div>
  <div className="p-2">Third item</div>
</Stack>
```

### Stack props

- **gap={1-5}** - space between items;
- **direction="horizontal"** - makes horizontal stacked flexbox;

## Forms

```html
<Form>
<fieldset>
<Form.Group className="mb-3" controlId="formBasicEmail">
  <Form.Label>Email address</Form.Label>
  <Form.Control 
    type="email" 
    placeholder="Enter email" 
  />
  <Form.Text muted>
    We'll never share your email with anyone else.
  </Form.Text>
</Form.Group>
<Form.Group>
  <Form.Label htmlFor="inputPassword">Password</Form.Label>
  <Form.Control
    type="password"
    id="inputPassword"
    aria-describedby="passwordHelpBlock"
  />
  <Form.Text id="passwordHelpBlock" muted>
    Your password must be 8-20 characters long, contain letters and numbers,
    and must not contain spaces, special characters, or emoji.
  </Form.Text>
</Form.Group>
</fieldset>
<Button variant="primary" type="submit">
  Submit
</Button>
</Form>
```

- **Form.Group** - wrapper around label and input.
- **Form.Control** - renders `<input>` or `<textarea>`.
- **Form.Text** - form text below inputs, it can be help text, some restrictions for inputs.

> help text should be associated with the control using `aria-describedby`

### Form props

- **validated** - mark form as having been validated.

### Form.Label props

- **htmlFor={controlId}** - if label is not in `Form.Group` we should specify.
- **visuallyHidden** - hides the label visually while still allowing it to be accessible.

### fieldset props

- **disabled** - disabling all controls which were wrapped inside.

### Form.Control props

- **as={'input'|'textarea'|element}** - by default it's `input`;
- **size={'sm'|'lg'}** - input size variants;
- **htmlSize={number}** - number of characters that are visible. It's size attribute of the HTML `input`;
- **plaintext** - renders input as plain text. Usually used along side `readonly`;
- **readonly**;
- **disabled**;
- **value**;
- **onChange**;
- **type={string}**;
- **isValid**;
- **isInValid**.

### Form.Text props

- **muted** - add `text-muted` class.

### Form.Select

```html
<Form.Select aria-label="Default select example">
  <option>Open this select menu</option>
  <option value="1">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</Form.Select>
```

#### Form.Select props

- **size={'sm'|'lg'}**;
- **htmlSize={number}**;
- **disabled**;
- **value**;
- **onChange**;
- **isValid**;
- **isInValid**.

### Form.Check

```html
<Form.Check
  type='radio'
  id='radio'
  label='radio'
/>
```

We can implement toggle switch:

```html
<Form.Switch
  id="custom-switch"
  label="Check this switch"
/>
```

#### Form.Check with children

```html
<Form.Check type='radio' id='radio'>
  <Form.Check.Input type='radio' isValid />  <Form.Check.Label>radio</Form.Check.Label>
  <Form.Control.Feedback type="valid">
    You did it!
  </Form.Control.Feedback>
</Form.Check>
```

#### Form.Check props

- **inline** - groups controls horizontally;
- **reverse** - put checkboxes etc. on the opposite side;
- **disabled**;
- **title={str}**;
- **type={'radio'|'checkbox'|'switch'}**;
- **isValid**;
- **isInValid**;
- **feedback** - a message to display when the input is in a validation state;
- **feedbackType={'valid'|'invalid'}**.

#### Form.Check.Input props

- **type={'radio'|'checkbox'}**;
- **isValid**;
- **isInValid**;

### Floating labels

Labels floating over input fields.

```html
<FloatingLabel controlId="formBasicPassword" label="Password">
  <Form.Control type="password" placeholder="Password" />
</FloatingLabel>
```

>`placeholder` in `<Form.Control>` is required since react-bootstrap uses `:placeholder-shown` pseudo-element.

#### FloattingLabel props

- **controlId={string}** - sets id and htmlFor;
- **label={string|node}** -  form control label.

### Form Layout

#### Label and Control placed horizontally

```html
<Row>
<Form.Label column="lg" lg={2}>
  Large Text
</Form.Label>
<Col>
  <Form.Control size="lg" type="text" placeholder="Large text" />
</Col>
</Row>
<br />
<Row>
<Form.Label column lg={2}>
  Normal Text
</Form.Label>
<Col>
  <Form.Control type="text" placeholder="Normal text" />
</Col>
</Row>
```

### Validation

To "turn on" react-bootstrap validation style it's better to "turn off" built-in browser validator by adding `noValidate` in `Form`:

```javascript
const [validated, setValidated] = useState(false);

const handleSubmit = (e) => {
  e.preventDefault();
  const form = e.currentTarget;
  if (form.checkValidity() === true) {
    // submit logic
  } else {
    setValidated(true);
  }
}

return(
<Form 
  onSubmit={handleSubmit} 
  noValidated 
  validated={validated}
>
  // ...
</Form>
}
```