Categories
Material UI

How To Use Material UI to Bring Material Design to React

Material UI is one of the most popular Material Design libraries for React. It has the basic Material Design UI elements, such as inputs, cards, grids, tables, navigation, toolbar, dropdowns, fonts, etc. Here’s the full list.

It is available as a Node package. To install it, run npm i @material-ui/core. Then, you can import them into your component files when you need them.

In this piece, I will make an app with React and Material UI that uses the Dog API.

To create a new React app, use the create-react-app code generator, made by the developers of React. Here are the README and the full documentation.

To create the app, run npx create-react-app and follow the instructions, you will get a new app. Then, you are ready to install React Router. To install it, run npm i react-router-dom.

After that, install @material-ui/core and Axios by running npm i @material-ui/core axios. Material UI provides the Material Design look to our app and Axios is an HTTP client which works at client-side apps.

In index.js, we have:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { breedsReducer, imagesReducer } from './reducers';
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import { combineReducers } from 'redux'
const dogApp = combineReducers({
  breeds: breedsReducer,
  images: imagesReducer
})

const store = createStore(dogApp);
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>
, document.getElementById('root')
);
serviceWorker.unregister();

The file above is where the reducers are mapped to the states. With the combineReducers function called, the store is created, which is then passed into the app, where the mapStateToProps will make the state available to the component as props.

The mapDispatchToProps allows you to set state in your component via a function in the props, as you will see below.

We add reducers to store state in a centrally available location. The states of our app are set here.

We make a file called reducer.js:

import { SET_BREEDS, SET_IMAGES } from './actions';

function breedsReducer(state = {}, action) {
    switch (action.type) {
        case SET_BREEDS:
            state = JSON.parse(JSON.stringify(action.payload));
            return state;
        default:
            return state
    }
}

function imagesReducer(state = [], action) {
    switch (action.type) {
        case SET_IMAGES:
            state = JSON.parse(JSON.stringify(action.payload));
            return state;
        default:
            return state
    }
}

export { breedsReducer, imagesReducer };ima

In actions.js, we add these constants for our Redux actions:

const SET_BREEDS = 'SET_BREEDS';
const SET_IMAGES = 'SET_IMAGES';
export { SET_BREEDS, SET_IMAGES };

In actionCreators.js, we add:

import { SET_BREEDS, SET_IMAGES } from './actions';

const setBreeds = (breeds) => {
    return {
        type: SET_BREEDS,
        payload: breeds
    }
};

const setImages = (images) => {
    return {
        type: SET_IMAGES,
        payload: images
    }
};

export { setBreeds, setImages };

In app.js, we change the default code to:

import React, { useState, useEffect } from "react";
import './App.css';
import { setBreeds } from './actionCreators';
import { connect } from 'react-redux';
import { Router, Route, Link } from "react-router-dom";
import HomePage from './HomePage';
import BreedsPage from './BreedsPage';
import SubBreedsPage from './SubBreedsPage';
import AppBar from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/AppBar';
import Toolbar from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/Toolbar';
import Typography from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/Typography';
import Button from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/Button';
import IconButton from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/IconButton';
import Drawer from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/Drawer';
import List from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/List';
import ListItem from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/ListItem';
import ListItemText from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/ListItemText';
import { makeStyles } from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/styles';
import { createBrowserHistory as createHistory } from 'history'
const history = createHistory();
const axios = require('axios');

const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1,
  },
  menuButton: {
    marginRight: theme.spacing(2),
  },
  title: {
    flexGrow: 1,
  },
}));

function App({ setBreeds }) {
  const classes = useStyles();
  const [initialized, setInitialized] = useState(false);
  const [state, setState] = useState({
    openDrawer: false
  });

  const titles = {
    '/': 'Dog App',
    '/breeds': 'Get Images By Breed - Dog App',
    '/subbreeds': 'Get Images By Breed or Sub-Breed - Dog App'
  }

  history.listen((location, action) => {
    document.title = titles[location.pathname];
    setState({ openDrawer: false });
  });

  const toggleDrawer = (open) => event => {
    if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
      return;
    }
    setState({ openDrawer: open });
  };

  const links = {
    'Home': '/',
    'Breeds': '/breeds',
    'Sub-Breeds': '/subbreeds',
  }

  const getBreeds = () => {
    setInitialized(true);
    axios.get('[https://dog.ceo/api/breeds/list/all'](https://dog.ceo/api/breeds/list/all%27))
      .then((response) => {
        setBreeds(response.data.message);
      })
      .catch((error) => {
        console.log(error);
      })
      .finally(() => {

      });
  }

  useEffect(() => {
    if (!initialized) {
      getBreeds();
    }
  });

  return (
    <div className="App">
      <Router history={history}>
        <Drawer anchor="left" open={state.openDrawer} onClose={toggleDrawer(false)}>
          <List>
            <ListItem button>
              <h2><b>Dog App</b></h2>
            </ListItem>
            {Object.keys(links).map((text) => (
              <ListItem button key={text}>
                <Link to={links[text]}>
                  <ListItemText primary={text} />
                </Link>
              </ListItem>
            ))}
          </List>
        </Drawer>
        <AppBar position="static">
          <Toolbar>
            <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="Menu" onClick={toggleDrawer(true)}>
              <i className="material-icons">menu</i>
            </IconButton>
            <Typography variant="h6" className={classes.title}>
              Dog App
            </Typography>
          </Toolbar>
        </AppBar>

      <Route path="/" exact component={HomePage} />
        <Route path="/breeds/" component={BreedsPage} />
        <Route path="/subbreeds/" component={SubBreedsPage} />
      </Router>
    </div>
  );
}

  const mapStateToProps = (state) => ({
    breeds: state.breeds
  })

  const mapDispatchToProps = (dispatch) => ({
    setBreeds: breeds => dispatch(setBreeds(breeds))
  })

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

Notice that, in the code above, we imported all the widgets that we need into the component file and then we include it in the return statement.

For styling, we import the makeStyles function and put an object in it. We style it by providing CSS-like attributes and values.

The top-level keys are the classes. They will be created when the imported useStyles() is called. Then, we can use it by referencing classes.className.

For example, classes.menuButton would be used for applying the menuButton class to the button above.

The code above has Hooks.

const [initialized, setInitialized] = useState(false);
const [state, setState] = useState({
  openDrawer: false
});

These functions are equivalent to setState functions in class-based components.

The first element in the array (initialized) is equivalent to this.state.initialized and setInitialized is equivalent to a function that calls this.setState({initialized: initializedValue}); in a class-based component.

Hooks only works with function-based components. This has the benefit of writing fewer lines of code to achieve the same effect of setting state.

Also note that we have this in the above component:

useEffect(() => {
  if (!initialized) {
    getBreeds();
  }
});

As we don’t have componentDidMount like in class-based components, we have to check if the component is loaded with our own flag.

The getBreeds function sets the initialized flag to true once it’s run successfully, so that the getBreeds function will not run repeatedly forever. useEffect is a function that is run during every render, so be careful not to put necessary code in there.

Note the connect function at the end of the file above. This where the state connects to the component. setBreeds is a function which returns a plain object with the action type and the payload.

This allows the reducer to set the state, according to the type field, which in this case would be SET_BREEDS or SET_IMAGES. The state will be set, returned, and the new state will be available via props.breeds for breeds.

The <Route path=”/breeds/” component={BreedsPage} /> is where the route is defined. It must be inside <Router history={history}></Router>.

This is the routing part of our application. With this, we can go to the page when we type in http://localhost: 3000/breeds.

This block sets the title and hides the app drawer on the left when the route changes:

history.listen((location, action) => {
   document.title = titles[location.pathname];
   setState({ openDrawer: false });
});

We now create the pages for our apps which will use React Router for routing. First, we create a page for displaying breeds, we call it BreedPage.js.

The code will look like this:

import React from 'react';
import './BreedsPage.css';
import { setImages } from './actionCreators';
import { connect } from 'react-redux';
import InputLabel from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/InputLabel';
import MenuItem from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/MenuItem';
import FormControl from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/FormControl';
import Select from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/Select';
import { makeStyles } from '[@material](http://twitter.com/material "Twitter profile for @material")-ui/core/styles';
import ImagesBox from './ImagesBox';
const axios = require('axios');

const useStyles = makeStyles(theme => ({
    formControl: {
        margin: theme.spacing(1),
        width: '90vw',
    },

}));

function BreedsPage({ breeds, setImages }) {
    const classes = useStyles();
    const [state, setState] = React.useState({
        breed: '',
    });
    const [initialized, setInitialized] = React.useState(false);

    const handleChange = name => event => {
        setState({
            ...state,
            [name]: event.target.value,
        });

    if (name == 'breed') {
            getImagesByBreed(event.target.value);
        }
    };

    const getImagesByBreed = (breed) => {
        axios.get(`[https://dog.ceo/api/breed/${breed}/images`](https://dog.ceo/api/breed/$%7Bbreed%7D/images`))
            .then((response) => {
                setImages(response.data.message);
            })
            .catch((error) => {
                console.log(error);
            })
            .finally(() => {

});
    }

    React.useEffect(() => {
        if (!initialized) {
            setInitialized(true);
            setImages([]);
        }
    });

    return (
        <div className="App">
            <h1>Get Images By Breed</h1>
            <form>
                <FormControl className={classes.formControl}>
                    <InputLabel>Breed</InputLabel>
                    <Select
                        value={state.breed}
                        onChange={handleChange('breed')}
                    >
                        {Object.keys(breeds || {}).map(b =>
                            <MenuItem value={b} key={b}>
                                {b}
                            </MenuItem>
                        )}
                    </Select>
                </FormControl>
                <ImagesBox></ImagesBox>
            </form>
        </div>
    );

}

const mapStateToProps = state => {
    return {
        breeds: state.breeds,
        images: state.images
    }
}

const mapDispatchToProps = dispatch => ({
    setImages: images => dispatch(setImages(images))
})

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(BreedsPage);

In the end, you get the screen below when you go to [http://localhost:](http://localhost/)3000/breeds:

Categories
Reactstrap

Reactstrap — Tooltips

Reactstrap is a version Bootstrap made for React.

It’s a set of React components that have Boostrap styles.

In this article, we’ll look at how to add tooltips with Reactstrap.

Tooltips

We can add tooltips with Reactstrap.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Tooltip } from "reactstrap";
export default function App() {
  const [tooltipOpen, setTooltipOpen] = React.useState(false);

  const toggle = () => setTooltipOpen(!tooltipOpen);

  return (
    <div>
      <p>
        <span
          style={{ textDecoration: "underline", color: "blue" }}
          href="#"
          id="Tooltip"
        >
          tooltip
        </span>
      </p>
      <Tooltip
        placement="right"
        isOpen={tooltipOpen}
        target="Tooltip"
        toggle={toggle}
      >
        Hello world
      </Tooltip>
    </div>
  );
}

to add a tooltip trigger span element.

The id of the span should match the value of the target prop of the Tooltip .

The Tooltip component also takes the placement , isOpen and toggle props.

isOpen has the open state of the tooltip.

toggle has the function to toggle the tooltip.

Tooltip Disable Autohide

We can disable autohide with the autohide prop set to false .

So we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Tooltip } from "reactstrap";
export default function App() {
  const [tooltipOpen, setTooltipOpen] = React.useState(false);

const toggle = () => setTooltipOpen(!tooltipOpen);

return (
    <div>
      <p>
        <span
          style={{ textDecoration: "underline", color: "blue" }}
          href="#"
          id="Tooltip"
        >
          tooltip
        </span>
      </p>
      <Tooltip
        placement="right"
        isOpen={tooltipOpen}
        target="Tooltip"
        toggle={toggle}
        autohide={false}
      >
        Hello world
      </Tooltip>
    </div>
  );
}

Tooltips Placement

We can change the placement of the tooltip with the placement prop.

So we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Tooltip } from "reactstrap";
export default function App() {
  const [tooltipOpen, setTooltipOpen] = React.useState(false);

  const toggle = () => setTooltipOpen(!tooltipOpen);

  return (
    <div>
      <p>
        <span
          style={{ textDecoration: "underline", color: "blue" }}
          href="#"
          id="Tooltip"
        >
          tooltip
        </span>
      </p>
      <Tooltip
        placement="bottom"
        isOpen={tooltipOpen}
        target="Tooltip"
        toggle={toggle}
      >
        Hello world
      </Tooltip>
    </div>
  );
}

We can set the placement prop to left , right , bottom or top .

Uncontrolled Tooltip

We can add the UncontrolledTooltip to add a tooltip if we don’t need to control the tooltip state programmatically.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { UncontrolledTooltip } from "reactstrap";

export default function App() {
  return (
    <div>
      <p>
        <span
          style={{ textDecoration: "underline", color: "blue" }}
          href="#"
          id="Tooltip"
        >
          tooltip
        </span>
      </p>
      <UncontrolledTooltip placement="right" target="Tooltip">
        Hello world
      </UncontrolledTooltip>
    </div>
  );
}

to add the UncontrolledTooltip component.

The id of the trigger element should match the target of the UncontrolledTooltip .

Repositioning Tooltips

A tooltip can be repositioned on the fly with the scgheduleUpdate function.

For instance, if we toggle between short and long text in our tooltip as follows:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { UncontrolledTooltip } from "reactstrap";

const shortText = "Hi";
const longText =
  "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus fermentum lacus";

const TooltipContent = ({ scheduleUpdate }) => {
  const [text, setText] = React.useState(shortText);

  React.useEffect(() => {
    const intervalId = setInterval(() => {
      setText(text === shortText ? longText : shortText);
      scheduleUpdate();
    }, 2000);

    return () => clearInterval(intervalId);
  });

  return <>{text}</>;
};

export default function App() {
  return (
    <div>
      <p>
        <span
          style={{ textDecoration: "underline", color: "blue" }}
          href="#"
          id="Tooltip"
        >
          tooltip
        </span>
      </p>
      <UncontrolledTooltip placement="top" target="Tooltip" trigger="click">
        {({ scheduleUpdate }) => (
          <TooltipContent scheduleUpdate={scheduleUpdate} />
        )}
      </UncontrolledTooltip>
    </div>
  );
}

Then if we run scheduleUpdate as we did in the setInterval callback, we’ll see the tooltip automatically reposition itself as the text changes.

Conclusion

We can add a tooltip either as a controlled or uncontrolled components.

They can be repositioned on the fly.

Categories
Reactstrap

Reactstrap — Tabs and Toasts

Reactstrap is a version Bootstrap made for React.

It’s a set of React components that have Boostrap styles.

In this article, we’ll look at how to add tabs and toasts with Reactstrap.

Tabs

We can add tabs with the Nav component with the tabs prop.

The content of each tab can be added with the TabContent and TabPane components.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import {
  TabContent,
  TabPane,
  Nav,
  NavItem,
  NavLink,
  Card,
  Button,
  CardTitle,
  CardText,
  Row,
  Col
} from "reactstrap";

export default function App() {
  const [activeTab, setActiveTab] = React.useState("1");

  const toggle = tab => {
    if (activeTab !== tab) setActiveTab(tab);
  };

  return (
    <div>
      <Nav tabs>
        <NavItem>
          <NavLink
            className={activeTab === "1" ? "active" : ""}
            onClick={() => {
              toggle("1");
            }}
          >
            Tab1
          </NavLink>
        </NavItem>
        <NavItem>
          <NavLink
            className={activeTab === "2" ? "active" : ""}
            onClick={() => {
              toggle("2");
            }}
          >
            More Tabs
          </NavLink>
        </NavItem>
      </Nav>
      <TabContent activeTab={activeTab}>
        <TabPane tabId="1">
          <Row>
            <Col sm="12">
              <h4>Tab 1 Contents</h4>
            </Col>
          </Row>
        </TabPane>
        <TabPane tabId="2">
          <Row>
            <Col sm="12">
              <h4>Tab 2 Contents</h4>
            </Col>
          </Row>
        </TabPane>
      </TabContent>
    </div>
  );
}

to create our nav with the tab content.

We have a toggle component to set the active tab with the setActiveTab function when we click on a tab.

The activeTab is used to set the className of the link to active for the active tab.

The active class will set the styles for an active tab.

Toasts

Toasts are components that show notifications to the user.

To add them, we use the Toast , ToastBody , and ToastHeader component.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Toast, ToastBody, ToastHeader } from "reactstrap";
export default function App() {
  return (
    <div>
      <Toast>
        <ToastHeader>Title</ToastHeader>
        <ToastBody>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus
          fermentum lacus.
        </ToastBody>
      </Toast>
    </div>
  );
}

to add a toast with a header and body.

Toast is the wrapper.

ToastHeader has the toast header.

ToastBody has the toast body.

The background can change depending on the style of its parent element.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Toast, ToastBody, ToastHeader } from "reactstrap";
export default function App() {
  return (
    <div className="p-3 bg-primary my-2 rounded">
      <Toast>
        <ToastHeader>Title</ToastHeader>
        <ToastBody>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus
          fermentum lacus.
        </ToastBody>
      </Toast>
    </div>
  );
}

to set the div’s background to blue.

And the toast will have a light blue background.

We can replace bg-primary with all the other background class variants to change the background.

Header Icons

We can add an icon to the header of a toast.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Toast, ToastBody, ToastHeader } from "reactstrap";
export default function App() {
  return (
    <div>
      <Toast>
        <ToastHeader icon="dark">Title</ToastHeader>
        <ToastBody>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus
          fermentum lacus.
        </ToastBody>
      </Toast>
    </div>
  );
}

to add the icon prop to the ToastHeader .

We can also add a component instead of a string:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Toast, ToastBody, ToastHeader, Spinner } from "reactstrap";
export default function App() {
  return (
    <div>
      <Toast>
        <ToastHeader icon={<Spinner size="sm" />}>Title</ToastHeader>
        <ToastBody>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus
          fermentum lacus.
        </ToastBody>
      </Toast>
    </div>
  );
}

We added a spinner to the header.

Conclusion

We can add tabs with a nav.

And we can add toasts to display popup notifications.

Categories
Reactstrap

Reactstrap — Tables

Reactstrap is a version Bootstrap made for React.

It’s a set of React components that have Boostrap styles.

In this article, we’ll look at how to add tables with Reactstrap.

Tables

Reactstrap comes with its own table component.

For instance, we can use it by writing:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "reactstrap";

export default function App() {
  return (
    <div>
      <Table>
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>james</td>
            <td>smith</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>mary</td>
            <td>wong</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>larry</td>
            <td>jones</td>
          </tr>
        </tbody>
      </Table>
    </div>
  );
}

We just add the Table component and use the usual table elements inside it to create our table.

By default, it’ll have a bottom border.

Dark Table

We can make the background dark with the dark prop.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "reactstrap";

export default function App() {
  return (
    <div>
      <Table dark>
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>james</td>
            <td>smith</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>mary</td>
            <td>wong</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>larry</td>
            <td>jones</td>
          </tr>
        </tbody>
      </Table>
    </div>
  );
}

Striped Rows

We can make the rows striped with the striped prop:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "reactstrap";

export default function App() {
  return (
    <div>
      <Table striped>
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>james</td>
            <td>smith</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>mary</td>
            <td>wong</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>larry</td>
            <td>jones</td>
          </tr>
        </tbody>
      </Table>
    </div>
  );
}

Bordered Table

We can add borders to the cells with the bordered prop:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "reactstrap";

export default function App() {
  return (
    <div>
      <Table bordered>
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>james</td>
            <td>smith</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>mary</td>
            <td>wong</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>larry</td>
            <td>jones</td>
          </tr>
        </tbody>
      </Table>
    </div>
  );
}

Borderless Table

We can make the cells borderless with the borderless prop:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "reactstrap";

export default function App() {
  return (
    <div>
      <Table borderless>
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>james</td>
            <td>smith</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>mary</td>
            <td>wong</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>larry</td>
            <td>jones</td>
          </tr>
        </tbody>
      </Table>
    </div>
  );
}

Hoverable Rows

The rows can be made hoverable with the hover prop:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "reactstrap";

export default function App() {
  return (
    <div>
      <Table hover>
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>james</td>
            <td>smith</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>mary</td>
            <td>wong</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>larry</td>
            <td>jones</td>
          </tr>
        </tbody>
      </Table>
    </div>
  );
}

Small Table

To make the rows smaller, we can set the size prop to sm :

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "reactstrap";

export default function App() {
  return (
    <div>
      <Table size="sm">
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>james</td>
            <td>smith</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>mary</td>
            <td>wong</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>larry</td>
            <td>jones</td>
          </tr>
        </tbody>
      </Table>
    </div>
  );
}

Responsive Table

We can make a table responsive with the responsive prop:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table } from "reactstrap";

export default function App() {
  return (
    <div>
      <Table responsive>
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">1</th>
            <td>james</td>
            <td>smith</td>
          </tr>
          <tr>
            <th scope="row">2</th>
            <td>mary</td>
            <td>wong</td>
          </tr>
          <tr>
            <th scope="row">3</th>
            <td>larry</td>
            <td>jones</td>
          </tr>
        </tbody>
      </Table>
    </div>
  );
}

Now it’ll display properly on any screen.

Conclusion

Reactstrap provides us with a simple Table component to display tables.

Categories
Reactstrap

Reactstrap — Progress Bars

Reactstrap is a version Bootstrap made for React.

It’s a set of React components that have Boostrap styles.

In this article, we’ll look at how to add a progress bar with Reactstrap.

Progress

We can add a progress bar with the Progress component.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Progress } from "reactstrap";

export default function App() {
  return (
    <div className="text-center">
      <Progress value={2 * 20} />
      <Progress color="success" value="25" />
      <Progress color="info" value={50} />
      <Progress color="warning" value={75} />
      <Progress color="danger" value="100" />
    </div>
  );
}

to display various progress bars.

The value prop lets us change the amount of the bar that’s filled.

color has the color and they’re the variants that are shown.

Multiple Segments

We can create a progress bar that has multiple segments.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Progress } from "reactstrap";

export default function App() {
  return (
    <div className="text-center">
      <Progress multi>
        <Progress bar value="15">
          foo
        </Progress>
        <Progress bar color="success" value="30">
          bar
        </Progress>
        <Progress bar color="info" value="25">
          baz
        </Progress>
        <Progress bar color="warning" value="20">
          qux
        </Progress>
        <Progress bar color="danger" value="5">
          !!
        </Progress>
      </Progress>
    </div>
  );
}

We have a Progress components that wraps around other Progress components.

The multi prop lets us add a progress bar with multiple segments.

The inner bars has the bar component with the color to specify their color.

The value is the value out of 100.

Striped

We can make a progress bar striped with the striped prop.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Progress } from "reactstrap";

export default function App() {
  return (
    <div className="text-center">
      <Progress striped color="info" value={50} />
    </div>
  );
}

to add a striped progress bar.

This also works with progress bars with multiple segments:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Progress } from "reactstrap";

export default function App() {
  return (
    <div className="text-center">
      <Progress multi>
        <Progress striped bar value="10" />
        <Progress striped bar color="success" value="20" />
        <Progress striped bar color="warning" value="30" />
        <Progress striped bar color="danger" value="20" />
      </Progress>
    </div>
  );
}

We’ve to add the striped prop to each bar.

Animated

We can make the progress bar animated by using the animated prop.

For instance, we can write:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Progress } from "reactstrap";

export default function App() {
  return (
    <div className="text-center">
      <Progress animated color="info" value={50} />
    </div>
  );
}

to make it animated.

We can do the same thing with multi-segment progress bars:

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import { Progress } from "reactstrap";

export default function App() {
  return (
    <div className="text-center">
      <Progress multi>
        <Progress animated bar value="10" />
        <Progress animated bar color="success" value="20" />
        <Progress animated bar color="warning" value="30" />
        <Progress animated bar color="danger" value="20" />
      </Progress>
    </div>
  );
}

the animated prop is applied to each segment.

Conclusion

We can add a progress bar with multiple segments and different colors.

They can also be striped or animated.