Cheat Sheet for React Bootstrap. Installation and components
Tags: react, bootstrap
Published: 2024-07-03 11:53:51

Bootstrap Javascript is not recommended to use with React. React-Bootstrap creates each component as a true React component so there won't be any conflict with React library.

## Table of contents
- [Installation and usage](#installation-and-usage)
- [**as** Prop API](#**as**-prop-api)
- [Theming](#theming)
- [Components](#components)
  - [Accordion](#accordion)
  - [Alerts](#alerts)
  - [Badges](#badges)
  - [Breadcrumbs](#breadcrumbs)
  - [Buttons](#buttons)
  - [Button group](#button-group)
  - [Cards](#cards)
  - [Carousels](#carousels)
  - [Dropdowns](#dropdowns)
  - [Images](#images)
  - [List groups](#list-groups)
  - [Modals](#modals)
  - [Navs](#navs)
  - [Navbars](#navbars)
  - [Offcanvas](#offcanvas)
  - [Progress bars](#progress-bars)
  - [Spinners](#spinners)
  - [Tables](#tables)
  - [Tabs](#tabs)
  - [Toasts](#toasts)

## Installation and usage

```bash
npm i react-bootstrap
```

If we don't want to customize Bootstrap CSS we can just include it using cdn, otherwise we should install vanilla bootstrap via package manager:

```bash
npm i bootstrap
```

Then we should import library in root module:

```javascript
import 'bootstrap/dist/css/bootstrap.min.css';
```

Importing Bootstrap CSS should be before importing css/scss files and React components if they use css/scss files.

To use react-bootstrap components we should import each individually where we need it:

```javascript
import Button from 'react-bootstrap/Button';

// or
import { Button } from 'react-bootstrap';
```

## **as** Prop API

If we want to keep styling of the certain React-Bootstrap component but change the final rendered component (different HTML tag, different custom component) we can use `as` prop:

```javascript
import { Button, Badge } from 'react-bootstrap';

const Component = () => {
  return (
    <>
    <Button as="a">Link</Button>
    <Badge as={Button}>Button</Badge>
    </>
  )
}
```

## Theming

We can set bootstrap theme using `data-bs-theme` attribute. Globally we should add it to `<html>` element. For example, if we want 'dark' color mode we add `data-bs-theme="dark"`.

## Components

### Accordion

Vertically collapsing element:

```html
<Accordion defaultActiveKey="0">
  <Accordion.Item eventKey="0">
    <Accordion.Header>Accordion Item #1</Accordion.Header>
    <Accordion.Body>
      Lorem ipsum
    </Accordion.Body>
  </Accordion.Item>
  <Accordion.Item eventKey="1">
    <Accordion.Header>Accordion Item #2</Accordion.Header>
    <Accordion.Body>
      Lorem ipsum
    </Accordion.Body>
  </Accordion.Item>
</Accordion>
```

#### Accordion props

- **defaultActiveKey={value}** - which `Accordion.Item` is open by default. The value corresponds to `eventKey`. If there is no `defaultActiveKey` no item is open by default;
- **flush** - removes the dafault background-color, borders.
- **alwaysOpen** - not close the item when another item is opened. If we want multiple items to be open by default:
```html
<Accordion 
  defaultActiveKey={["0","1"]} 
  alwaysOpen
>
```
- **onSelect={(selectedEventKey, event) => {}}** - fires when the active item changes.

### Alerts

Styled feedback message:

```html
<Alert variant='warning'>
  <Alert.Heading>
    Hey, just a warning
  </Alert.Heading>
  This is a 'warning' alert with <Alert.Link href="#">
    an example link
  </Alert.Link>.
</Alert>
```

#### Alert props

- **variant={value}** - style, where value may equal:
  - 'primary',
  - 'secondary',
  - 'success',
  - 'danger',
  - 'warning',
  - 'info',
  - 'light',
  - 'dark';
- **dismissible** - adds button that dismisses the alert;
- **show={Boolean}** - visual state of the Alert;
- **onClose={func}** - callback invoked when alert is closed

### Badges

Count and labeling component, that matches the size of the immediate parent:

```html
<Button variant="primary">
  Profile <Badge bg="secondary">9</Badge>
  <span className="visually-hidden">unread messages</span>
</Button>
```

#### Badge props

- **bg-{keyword}** - similar to apply bootstrap `.text-bg-{keyword}` class, where keyword is the same as variant in Alert component;
- **pill** - borders are more rounded. 

### Breadcrumbs

Current page's location within a navigational hierarchy:

```html
<Breadcrumb>
  <Breadcrumb.Item href="#">Home</Breadcrumb.Item>
  <Breadcrumb.Item href="https://getbootstrap.com/docs/4.0/components/breadcrumb/">
    Library
  </Breadcrumb.Item>
  <Breadcrumb.Item active>Data</Breadcrumb.Item>
</Breadcrumb>
```

#### Breadcrumb.Item props

- **href={value}**;
- **active** - it overrides 'href'; `span` element renders instead of `a` element .

### Buttons

#### Button props

- **variant={value}** - style, where value may equal:
  - 'primary',
  - 'secondary',
  - 'success',
  - 'danger',
  - 'warning',
  - 'info',
  - 'light',
  - 'dark',
  - 'link',
  - 'outline-primary' - no background color,
  - 'outline-secondary',
  - 'outline-success',
  - 'outline-danger',
  - 'outline-warning',
  - 'outline-info',
  - 'outline-light',
  - 'outline-dark';
- **size={value}** - scale, where value may equal:
  - 'lg',
  - 'sm';
- **disabled**;
- **href={value}** - renders <a> element styled as button;
- **type={'button'/'reset'/'submit'/null}**

#### ToggleButton

It is used to style `checkbox`:

```html
<ToggleButton
  id="toggle-check"
  type="checkbox"
  variant='outline-primary'
  checked={checked}
  value="1"
  onChange={(e) => {
    setChecked(e.currentTarget.checked);
  }} 
>
  Controlled checked
</ToggleButton>
```

and `radio`:

```html
     <ToggleButton
      id="radio-1"
      type="radio"
      variant="outline-secondary"
      name="radioOptions"
      value="1"
      checked={radioValue==='1'}
      onChange={(e) => setRadioValue(e.currentTarget.value)}
    >
      radio option 1
     </ToggleButton>
     <ToggleButton
      id="radio-2"
      type="radio"
      variant="outline-secondary"
      name="radioOptions"
      value="2"
      checked={radioValue==='2'}
      onChange={(e) => setRadioValue(e.currentTarget.value)}
    >
      radio option 2
     </ToggleButton>
```

### Button group

- **`<ButtonGroup>`** - wrapper around group of `<Button>`, `<DropdownButton>` elements;
- **`<ButtonToolbar>`** - wrapper around sets of `<ButtonGroup>`, `<InputGroup>` elements.

#### ButtonGroup props

- **size={'sm'/'lg'}** - applying this size to all inner Buttons;
- **vertical** - making group of buttons vertically stacked ;

### Cards

Flexible and extensible container:

```html
<Card className="text-center">
  <Card.Img variant="top" src="#" />
  <Card.Header as="h3">Featured</Card.Header>
  <Card.Body>
    <Card.Title>Card Title</Card.Title>
    <Card.Subtitle>Card Subtitle</Card.Subtitle>
    <Card.Text>Card Text</Card.Text>
    <Card.Link href="#">Card Link</Card.Link>
    <Card.Link href="#">Another Link</Card.Link>
    <Button variant="primary">Go somewhere</Button>
  </Card.Body>
  <Card.Footer>Footer</Card.Footer>
</Card>
```

`<Card.Body>` adds padding.

#### Card props

- **bg={'primary'/'secondary'/etc.}** - card background;
- **text={'muted'/'primary'/etc.}** - card text color;
- **border={'primary'/'secondary'/etc.}** - card border color.

#### Card.Img props

- **variant={top/bottom}** - styling image for top of the card or the bottom.

#### Image Overlays

Image is turned into a card background:

```html
<Card style={{ width: '18rem' }} className="text-center">
  <Card.Img src="https://cdn.pixabay.com/photo/2024/05/05/05/55/goose-8740266_1280.jpg" />
  <Card.ImgOverlay>
  <Card.Header as="h3">Featured</Card.Header>
  <Card.Body>
  </Card.Body>
  </Card.ImgOverlay>
</Card>
```

#### Navigation

```html
<Card.Header>
  <Nav variant="tabs" defaultActiveKey="#first">
    <Nav.Item>
      <Nav.Link href="#first">Active</Nav.Link>
    </Nav.Item>
    <Nav.Item>
      <Nav.Link href="#link">Link</Nav.Link>
    </Nav.Item>
  </Nav>
</Card.Header>
```

#### Card Groups

Row-directioned flexbox:

```html
<CardGroup>
  <Card>
  </Card>
  <Card>
  </Card>
</CardGroup>
```

### Carousels

Slideshow component for cycling through elements- images or slides of text:

```html
{/* uncontrolled */}
<Carousel style={{width: '17rem'}}>
  <Carousel.Item>
    <Card>
      <Card.Img src="https://cdn.pixabay.com/photo/2024/04/25/06/50/banana-8719086_960_720.jpg" />
    </Card>
    <Carousel.Caption>
      <h3>First slide label</h3>
      <p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p>
    </Carousel.Caption>
  </Carousel.Item>
  <Carousel.Item>
  <Card>
      <Card.Img src="https://cdn.pixabay.com/photo/2024/04/25/06/50/banana-8719086_960_720.jpg" />
    </Card>
    <Carousel.Caption>
      <h3>Second slide label</h3>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </Carousel.Caption>
  </Carousel.Item>
</Carousel>
```

#### Carousel props

- **fade** - fade transition instead of a slide;
- **slide={false}** - remove slide animation;
- **controls={false}** - remove previous and next arrows;
- **indicators={false}** - remove slide position indicators;
- **activeIndex={number}** - current visible slide;
- **onSelect={(newIndex, event) => {}}** - fires when the active item changes;
- **interval={number/null}** - delay between automatically cycling an item.

#### Carousel.Item props

- **interval={value}** - how many milliseconds we stay on this slide;

### Dropdowns
Toggler for displaying lists of links:

```html
<Dropdown>
  <Dropdown.Toggle id="dropdown-basic">
    Dropdown Button
  </Dropdown.Toggle>
  <Dropdown.Menu>
    <Dropdown.Header>Dropdown header</Dropdown.Header>
    <Dropdown.Item href="#/action-1">Action</Dropdown.Item>
    <Dropdown.Item href="#/action-2">Another action</Dropdown.Item>
    <Dropdown.Divider />
    <Dropdown.Item href="#/action-3">Something else</Dropdown.Item>
  </Dropdown.Menu>
</Dropdown>
```

**DropdownButton** can replace some elements:

```html
<DropdownButton id="dropdown-basic-button" title="Dropdown button">
  <Dropdown.Item href="#/action-1">Action</Dropdown.Item>
  <Dropdown.Item href="#/action-2">Another action</Dropdown.Item>
  <Dropdown.Item href="#/action-3">Something else</Dropdown.Item>
</DropdownButton>
```

#### Dropdown.Item
By default this element renders into links. However, we can use `as="button"` to change it.

We can also create non-iteractive items with `<Dropdown.ItemText>`.

#### Dropdown props

- **drop={value}** - direction and location of the Menu relative to Toggle, where value may equal to:
  - 'up' 
  - 'up-centered' 
  - 'start' 
  - 'end' 
  - 'down' 
  - 'down-centered';
- **show** - make menu visible;
- **onToggle={func}** - controls show;
- **autoClose={value}** - how to close he dropdown, where value may equal to:
  - true 
  - 'outside' 
  - 'inside' 
  - false.

#### Dropdown.Toggle props

- **split** - make Toggle split on button and toggler:

```html
<Dropdown as={ButtonGroup}>
<Button variant="success">Split Button</Button>
  <Dropdown.Toggle id="dropdown-basic" split />
</Dropdown>
```

#### Dropdown.Menu props

- **variant={value}**

### Images

Responsive images element:

```html
<Container className="w-25" >
<Image src="https://cdn.pixabay.com/photo/2024/03/30/04/56/tea-8664063_960_720.jpg" roundedCircle fluid />
</Container>
```

#### Image props

- **fluid** - it scales image to the parent element;
- shape of the image can be changed by:
  - **rounded**;
  - **roundedCircle**;
  - **thumbnail**.

### List groups

Flexible component for displaying series of content:

```html
<ListGroup numbered >
  <ListGroup.Item>Cras justo odio</ListGroup.Item>
  <ListGroup.Item>Dapibus ac facilisis in</ListGroup.Item>
</ListGroup>
```

#### ListGroup props

- **variant="flush"** - removes outer borders and rounded corners;
- **horizontal={true/'sm'/'md'/'lg'/'xl'/'xxl'}** - makes list horizonal starting at the breakpoint. It can't be combined with 'flush';
- **numbered** - make list with numbers;

#### ListGroup.Item props

- **variant={'primary'/'secondary'/etc.}**;
- **action** - additional hover:

```html
<ListGroup.Item action href='#'>...
<ListGroup.Item action onClick={()=>{}}>...
```

- **active** - style for active item;
- **disabled** - if item with `action` state becomes disabled;
- **href="#"**;
- **onClick={()=>{}}**.


### Modals

- These elements are over everything else in the document;
- Only one modal window at a time;

```javascript
  const [show, setShow] = useState(false);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  return (
    <>
      <Button variant="primary" onClick={handleShow}>
        Launch demo modal
      </Button>
      <Modal show={show} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Modal heading</Modal.Title>
        </Modal.Header>
        <Modal.Body>Woohoo, you are reading this text in a modal!</Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleClose}>
            Close
          </Button>
          <Button variant="primary" onClick={handleClose}>
            Save Changes
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  )
```

#### Modal props

- **size={'sm'/'lg'/'xl'}**;
- **fullscreen={true/'sm-down'/'md-down'/'xl-down'/'xxl-down'}** - fullscreen modal when screen width is below breakpoint;
- **centered** - vertically centered dialog;
- **backdrop='static'/true/false** - if `static` or `false` modal will not close when clicking outside. If `false` there is no outside background;
- **keyboard=false** - not close modal when escape key is pressed;
- **scrollable** - allows scrolling `<Modal.Body>` instead of the entire Modal when overflowing;
- **animation=false** - remove animation when open and close modal;
- **show** - show modal;
- **onShow={()=>{}}** - fires when modal is opening;
- **onHide={()=>{}}** - fires when modal is closing.

#### Modal.Header props

- **closeButton** - show close button.

### Navs

**Nav** - flexbox:

```html
<Nav>
  <Nav.Item>
    <Nav.Link href="/home">Active</Nav.Link>
  </Nav.Item>
  <Nav.Item>
    <Nav.Link eventKey="link-1">Link</Nav.Link>
  </Nav.Item>
  <Nav.Item>
    <Nav.Link eventKey="link-2">Link</Nav.Link>
  </Nav.Item>
  <Nav.Item>
    <Nav.Link eventKey="disabled" disabled>
      Disabled
    </Nav.Link>
  </Nav.Item>
</Nav>
```
#### Nav props

- **variant={'tabs'/'pills'/'underline'}** - style items;
- **activeKey={eventKey/href}** - which item is active;
- **defaultActiveKey={eventKey/href}**;
- **fill** - items proportionately fill width;
- **justify** - items evenly fill width;

#### Nav.Link props

- **active**;
- **disabled**;
- **href={#}**;
- **eventKey={string/number}**;

#### NavDropdown

```html
<Nav>
  <NavDropdown title="Dropdown" id="nav-dropdown">
    <NavDropdown.Item eventKey="4.1">Action</NavDropdown.Item>
    <NavDropdown.Item eventKey="4.2">Another action</NavDropdown.Item>
    <NavDropdown.Item eventKey="4.3">Something else here</NavDropdown.Item>
    <NavDropdown.Divider />
    <NavDropdown.Item eventKey="4.4">Separated link</NavDropdown.Item>
  </NavDropdown>
</Nav>
```

##### Props

- **title={string}** - text content of the button;
- **disabled**;
- **active**.



### Navbars

- `expand` prop collapses navbar at lower breakpoint;
- navbar is fluid by default;

```html
<Navbar expand="lg">
  <Container>
    <Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
    <Navbar.Toggle aria-controls="basic-navbar-nav" />
    <Navbar.Collapse id="basic-navbar-nav">
      <Navbar.Text href="#link">Not Link</Navbar.Text>
      <Nav className="me-auto">
        <Nav.Link href="#home">Home</Nav.Link>  
        <NavDropdown title="Dropdown" id="basic-nav-dropdown">
          <NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
          <NavDropdown.Item href="#action/3.2">
            Another action
          </NavDropdown.Item>
          <NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
          <NavDropdown.Divider />
          <NavDropdown.Item href="#action/3.4">
            Separated link
          </NavDropdown.Item>
        </NavDropdown>
      </Nav>
    </Navbar.Collapse>
  </Container>
</Navbar>
```

> Toggler will appear only at `lg` breakpoint

#### Navbar props

- **expand={breakpoint}** - below breakpoint Navbar will collapse;
- **bg={'primary'/'secondary'}** - Bootstrap's `.bg-*` class;
- **fixed={'top'/'bottom'}**;
- **sticky={'top'/'bottom'}**;
- **collapseOnSelect**.

### Offcanvas

Hidden sidebars:

```html
<Button variant="primary" onClick={handleShow}>
  Launch
</Button>

<Offcanvas show={show} onHide={handleClose}>
  <Offcanvas.Header closeButton>
    <Offcanvas.Title>Offcanvas</Offcanvas.Title>
  </Offcanvas.Header>
  <Offcanvas.Body>
    Some text as placeholder. In real life you can have the elements you
    have chosen. Like, text, images, lists, etc.
  </Offcanvas.Body>
</Offcanvas>
```

#### Offcanvas props

- **backdrop='static'/true/false** - if `static` or `false` modal will not close when clicking outside. If `false` there is no outside background;
- **keyboard=false** - not close modal when escape key is pressed;
- **scroll** - allow body scrolling while offcanvas is open;
- **placement={'start'/'end'/'top'/'bottom'}** - from which side of the viewport offcanvas appears;
- **responsive={'sm'/'md'/'lg'/'xl'/'xxl'}** - from the breakpoint show content of the offcanvas.

### Progress bars

```html
<ProgressBar 
  now={current} 
  label={`${current}%`} 
  variant='info' 
  striped 
  animated
/>
```

#### ProgressBar props

- **min={number}**;
- **now={number}**;
- **max={number}**;
- **label={string}**;
- **visuallyHidden** - hides label visually;
- **striped** - striped effect;
- **animated** - if `striped` stripes are animated;
- **variant={'success'/'danger'/'warning'/'info'}** - background class;

### Spinners

Usually it's used to show the loading state:

```html
<Spinner animation="border" role="status">
  <span className="visually-hidden">Loading...</span>
</Spinner>
```

#### Spinner props

- **variant={'primary'/'secondary'/etc.}**;
- **animation={'border'/'grow'}**;
- **size='sm'** - small spinner;

### Tables

#### Table props

- **striped/striped="columns"** - zebra-striping to rows or columns;
- **bordered** - adds borders to all sides of the table;
- **hover** - hover state on table rows;
- **variant={'primary'/'secondary'/etc.}**;
- **responsive={true/breakpoint}** - adds horizotal scroll.

### Tabs

```html
<Tabs
defaultActiveKey="profile"
id="uncontrolled-tab-example"
className="mb-3"
>
<Tab eventKey="home" title="Home">
  Tab content for Home
</Tab>
<Tab eventKey="profile" title="Profile">
  Tab content for Profile
</Tab>
<Tab eventKey="contact" title="Contact">
  Tab content for Contact
</Tab>
</Tabs>
```

#### Tabs props

- **variant={'tabs'/'pills'/'underline'}**;
- **fill**;
- **justify**;
- **activeKey={string}**;
- **defaultActiveKey={string}**;
- **onSelect={(eventKey, event)=>{}}**.

#### Tab.Container

It's used for more complex layouts.

```html
<Tab.Container id="left-tabs-example" defaultActiveKey="first">
<Row>
  <Col sm={3}>
    <Nav variant="pills" className="flex-column">
      <Nav.Item>
        <Nav.Link eventKey="first">Tab 1</Nav.Link>
      </Nav.Item>
      <Nav.Item>
        <Nav.Link eventKey="second">Tab 2</Nav.Link>
      </Nav.Item>
    </Nav>
  </Col>
  <Col sm={9}>
    <Tab.Content>
      <Tab.Pane eventKey="first">First tab content</Tab.Pane>
      <Tab.Pane eventKey="second">Second tab content</Tab.Pane>
    </Tab.Content>
  </Col>
</Row>
</Tab.Container>
```

### Toasts

Push notifications:

```html
<Button onClick={handleShow}>Show Toast</Button>
<Toast show={show} onClose={handleClose}>
  <Toast.Header>
    <strong className="me-auto">Bootstrap</strong>
    <small>11 mins ago</small>
  </Toast.Header>
  <Toast.Body>Hello, world! This is a toast message.</Toast.Body>
</Toast>
```

If there are multiple toasts:

```html
<ToastContainer position="bottom-end" className="p-3" style={{ zIndex: 1 }}>
  <Toast>
    <Toast.Header>
      <strong className="me-auto">Bootstrap</strong>
      <small className="text-muted">just now</small>
    </Toast.Header>
    <Toast.Body>See? Just like this.</Toast.Body>
  </Toast>
  <Toast>
    <Toast.Header>
      <strong className="me-auto">Bootstrap</strong>
      <small className="text-muted">2 seconds ago</small>
    </Toast.Header>
    <Toast.Body>Heads up, toasts will stack automatically</Toast.Body>
  </Toast>
</ToastContainer>
```

#### Toast props

- **autohide**;
- **delay={number}** - delay hiding for `number` milliseconds;
- **bg={'primary'/'secondary'/etc.}**;

#### ToastContainer props

- **position={value}** - where the toasts will be placed within container, where value may equal to:
  - 'top-start'
  - 'top-center'
  - 'top-end'
  - 'middle-start'
  - 'middle-center'
  - 'middle-end'
  - 'bottom-start'
  - 'bottom-center'
  - 'bottom-end'