Julia Shlykova
Posted on July 3, 2024
Bootstrap Javascript is not recommended to use with React. Thus, React-Bootstrap comes to light. It creates each component as a true React component so there won't be any conflict with React library.
Table of contents
Installation and usage
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:
npm i bootstrap
Then we should import library in root module:
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:
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:
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:
<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 toeventKey
. If there is nodefaultActiveKey
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:
<Accordion
defaultActiveKey={["0","1"]}
alwaysOpen
>
- onSelect={(selectedEventKey, event) => {}} - fires when the active item changes.
Alerts
Styled feedback message:
<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:
<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:
<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 ofa
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 element styled as button;
- type={'button'/'reset'/'submit'/null}
ToggleButton
It is used to style checkbox
:
<ToggleButton
id="toggle-check"
type="checkbox"
variant='outline-primary'
checked={checked}
value="1"
onChange={(e) => {
setChecked(e.currentTarget.checked);
}}
>
Controlled checked
</ToggleButton>
and radio
:
<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:
<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:
<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
<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:
<CardGroup>
<Card>
</Card>
<Card>
</Card>
</CardGroup>
Carousels
Slideshow component for cycling through elements- images or slides of text:
{/* 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:
<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:
<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:
<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:
<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:
<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:
<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;
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
orfalse
modal will not close when clicking outside. Iffalse
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:
<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
<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;
<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:
<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
orfalse
modal will not close when clicking outside. Iffalse
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
<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:
<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
<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.
<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:
<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:
<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'
Posted on July 3, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 18, 2024