Categories
Material UI

Material UI — Radio Button Errors, Dropdowns and Sliders

Material UI is a Material Design library made for React.

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

In this article, we’ll look at how to add radio buttons, dropdowns, and sliders with Material UI.

Show Error

To show errors with radio buttons, we can pass in an error prop to it.

For instance, we can write:

import React from "react";
import Radio from "@material-ui/core/Radio";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import FormLabel from "@material-ui/core/FormLabel";
import FormControl from "@material-ui/core/FormControl";
import FormHelperText from "@material-ui/core/FormHelperText";
import Button from "@material-ui/core/Button";
import RadioGroup from "@material-ui/core/RadioGroup";

export default function App() {
  const [value, setValue] = React.useState("");
  const [error, setError] = React.useState(false);
  const [helperText, setHelperText] = React.useState("");

  const handleRadioChange = event => {
    setValue(event.target.value);
    setHelperText(" ");
    setError(false);
  };

  const handleSubmit = event => {
    event.preventDefault();

    if (value === "2") {
      setHelperText("right");
      setError(false);
    } else if (value === "3") {
      setHelperText("wrong");
      setError(true);
    } else {
      setHelperText("Please select an option.");
      setError(true);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <FormControl component="fieldset" error={error}>
        <FormLabel component="legend">What's 1 + 1?</FormLabel>
        <RadioGroup name="quiz" value={value} onChange={handleRadioChange}>
          <FormControlLabel value="2" control={<Radio />} label="2" />
          <FormControlLabel value="3" control={<Radio />} label="3" />
        </RadioGroup>
        <FormHelperText>{helperText}</FormHelperText>
        <Button type="submit" variant="outlined" color="primary">
          Check Answer
        </Button>
      </FormControl>
    </form>
  );
}

We have the value state to set the value that the user selects as the value.

In App , we return a form with the FormComtrol compknent to wrap around the radio buttons.

RadioGroup have the radio button groups.

FormControlLabel gave the label with the radio button inside.

When we click the button, the handeSubmit function is run.

In the function, we call preventDefault to stop the default submission behavior.

Then we check if the user picked a valid choice.

We set the helper text and the error state so that we can pass that to the error prop.

The helper text is displayed between the radio buttons and the check answer button.

Select

We can add the Select component to add a select dropdown.

For instance, we can write:

import React from "react";
import InputLabel from "@material-ui/core/InputLabel";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";

export default function App() {
  const [fruit, setFruit] = React.useState("");

  const handleChange = event => {
    setFruit(event.target.value);
  };

  return (
    <form>
      <FormControl>
        <InputLabel id="fruit-label">fruit</InputLabel>
        <Select
          labelId="fruit-label"
          id="fruit"
          value={fruit}
          onChange={handleChange}
        >
          <MenuItem value="apple">Apple</MenuItem>
          <MenuItem value="orange">Orange</MenuItem>
          <MenuItem value="grape">Grape</MenuItem>
        </Select>
      </FormControl>
    </form>
  );
}

to add a dropdown along with a label.

InputLabel lets us add a label for the dropdown.

Select lets us add a dropdown.

labelId of Select should match with the id of the InputLabel .

Native Select

To make the select dropdown display as a native dropdown, we can use the native prop on the Select .

For example, we can write:

import React from "react";
import InputLabel from "@material-ui/core/InputLabel";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";

export default function App() {
  const [fruit, setFruit] = React.useState("");

  const handleChange = event => {
    setFruit(event.target.value);
  };

  return (
    <form>
      <FormControl>
        <Select
          native
          id="fruit"
          value={fruit}
          onChange={handleChange}
        >
          <option value="">Select one</option>
          <option value="apple">Apple</option>
          <option value="orange">Orange</option>
          <option value="grape">Grape</option>
        </Select>
      </FormControl>
    </form>
  );
}

We add the native prop to the Select .

And we replaced the MenuItem with the option element.

We also removed the label, so that it won’t overlap with the dropdown.

Slider

We can add a slider to add a numeric input that’s set by dragging a slider.

To add one, we can use the Slider component.

For instance, we can write:

import React from "react";
import Slider from "@material-ui/core/Slider";

export default function App() {
  const [value, setValue] = React.useState(10);

  const handleChange = event => {
    setValue(event.target.value);
  };

  return (
    <form>
      <Slider
        value={value}
        onChange={handleChange}
      />
    </form>
  );
}

to add a numerical slider.

We have the value state which we set as the value prop.

Also, we have the onChange prop set to our handleChange function.

We call setValue with the slider’s selected value to update the value state.

Now our slider’s handle can be dragged to change its selected value.

Conclusion

We can add a slider by using the Slider component.

Also, we can show errors with radio buttons.

Dropdowns can be added with the Select component.

Categories
Material UI

Material UI — More Text Field Customization

Material UI is a Material Design library made for React.

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

In this article, we’ll look at how to customize text fields with Material UI.

Inputs

We can add input boxes without all the other parts.

For example, we can write:

import React from "react";
import Input from "@material-ui/core/Input";

export default function App() {
  return (
    <>
      <div>
        <Input
          placeholder="Placeholder"
          inputProps={{ "aria-label": "description" }}
        />
      </div>
    </>
  );
}

to add an Input component without all the other components.

Color

To change the color of a TextField , we can set the color prop.

For example, we can write:

import React from "react";
import TextField from "@material-ui/core/TextField";

export default function App() {
  return (
    <>
      <div>
        <TextField
          id="filled-primary"
          label="Filled primary"
          variant="filled"
          color="primary"
        />
      </div>
    </>
  );
}

We set the color prop to primary to set the color.

Customized Text Field

We can customize a text field by passing our own style to it.

TextField has an InputProps prop which takes an object with some propeerties.

For instance, we can write;

import React from "react";
import TextField from "@material-ui/core/TextField";
import { fade, makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
  root: {
    border: "1px solid brown",
    overflow: "hidden",
    borderRadius: 3,
    backgroundColor: "orange",
    transition: theme.transitions.create(["border-color", "box-shadow"]),
    "&:hover": {
      backgroundColor: "#fff"
    },
    "&$focused": {
      backgroundColor: "#fff",
      boxShadow: `${fade(theme.palette.primary.main, 0.25)} 0 0 0 2px`,
      borderColor: theme.palette.primary.main
    }
  },
  focused: {}
}));

function StyledTextField(props) {
  const classes = useStyles();

  return (
    <TextField InputProps={{ classes, disableUnderline: true }} {...props} />
  );
}

export default function App() {
  return (
    <>
      <div>
        <StyledTextField
          id="filled-primary"
          label="Filled primary"
          variant="filled"
          color="primary"
        />
      </div>
    </>
  );
}

The StyledTextField gets all the props and pass them in.

And we make our styles with the makeStyle function.

We styled the root with all the styles we want.

The root would be the text field since we pass in the classes from the returned useStyles hook to the text field.

We set the border , backgroundColor , shadow and more.

transition lets us add transition effects.

Integration with 3rd Party Input Libraries

We can add things like input masks to our inputs with 3rd party libraries.

For instance, we can use the react-text-mask library to add an input mask to our Input component.

We can write:

import React from "react";
import Input from "@material-ui/core/Input";
import MaskedInput from "react-text-mask";

function TextMask(props) {
  const { inputRef, ...other } = props;

  return (
    <MaskedInput
      {...other}
      ref={ref => {
        inputRef(ref ? ref.inputElement : null);
      }}
      mask={[
        /d/,
        /d/,
        /d/,
        "-",
        /d/,
        /d/,
        /d/,
        "-",
        /d/,
        /d/,
        /d/,
        /d/
      ]}
      placeholderChar={"u2000"}
      showMask
    />
  );
}

export default function App() {
  const [values, setValues] = React.useState("");
  const handleChange = event => {
    setValues(event.target.value);
  };

  return (
    <>
      <div>
        <Input
          value={values.textmask}
          onChange={handleChange}
          name="textmask"
          id="formatted-text-mask-input"
          inputComponent={TextMask}
        />
      </div>
    </>
  );
}

We add a TextMask component that uses the MaskedInput with the mask that we want to add.

The mask will restrict the format to what we want.

showMask shows the mask

The mask has the format.

placeholderChar has a placeholder character.

We also set ref to the inputRef that’s passed in from the props.

The in our App component, we pass the TextMask into our Input ‘s inputComponent prop.

And we’ll see the input mask displayed.

Other libraries that it works with include the react-number-format library to restrict number inputs to a fixed format.

Accessibility

Input should be linked to the label and helper text so that text fields are accessible.

For example, we write:

import React from "react";
import FormControl from "@material-ui/core/FormControl";
import InputLabel from "@material-ui/core/InputLabel";
import Input from "@material-ui/core/Input";
import FormHelperText from "@material-ui/core/FormHelperText";

export default function App() {
  return (
    <>
      <div>
        <FormControl>
          <InputLabel htmlFor="name-input">name</InputLabel>
          <Input id="name-input" aria-describedby="name-helper-text" />
          <FormHelperText id="name-helper-text">
            enter your name.
          </FormHelperText>
        </FormControl>
      </div>
    </>
  );
}

to make it accessible.

We have the html-for prop which matches the id of the input.

id of the FormHelperText matches the aria-describedby of the Input .

This way, they can be linked to each other.

Conclusion

Material UI text fields can be customized with 3rd party libraries.

Also, we can make them accessible with additional props in the components.

Categories
Material UI

Material UI — Bottom Nav and Breadcrumbs

Material UI is a Material Design library made for React.

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

In this article, we’ll look at how to add bottom navigation and breadcrumbs with Material UI.

Bottom Navigation

We can add bottom navigation to let us add links to move around our app.

To add it, we can use the BottomNavigation component.

For example, we can write:

import React from "react";
import BottomNavigation from "@material-ui/core/BottomNavigation";
import BottomNavigationAction from "@material-ui/core/BottomNavigationAction";
import RestoreIcon from "@material-ui/icons/Restore";
import FavoriteIcon from "@material-ui/icons/Favorite";
import LocationOnIcon from "@material-ui/icons/LocationOn";

export default function App() {
  const [value, setValue] = React.useState(0);

  return (
    <BottomNavigation
      value={value}
      onChange={(event, newValue) => {
        setValue(newValue);
      }}
      showLabels
    >
      <BottomNavigationAction label="latest" icon={<RestoreIcon />} />
      <BottomNavigationAction label="favorites" icon={<FavoriteIcon />} />
      <BottomNavigationAction label="location" icon={<LocationOnIcon />} />
    </BottomNavigation>
  );
}

to add a navigation bar to the bottom of the page.

We add the BottomNavigation component with the showLabels prop to show the labels.

BottomNavigationAction has the items that users can click on

label has the text below the icon.

icon has the icons.

When we click on the BottomNavigationAction then the value state will be set with the onChange callback which calls the setValue function with the index.

The value prop of BottomNavigationAction lets us set the value that’s set when we click the action.

For example, we can write:

import React from "react";
import BottomNavigation from "@material-ui/core/BottomNavigation";
import BottomNavigationAction from "@material-ui/core/BottomNavigationAction";
import RestoreIcon from "@material-ui/icons/Restore";
import FavoriteIcon from "@material-ui/icons/Favorite";
import LocationOnIcon from "@material-ui/icons/LocationOn";

export default function App() {
  const [value, setValue] = React.useState("favorites");

  return (
    <BottomNavigation
      value={value}
      onChange={(event, newValue) => {
        setValue(newValue);
      }}
      showLabels
    >
      <BottomNavigationAction
        label="latest"
        value="latest"
        icon={<RestoreIcon />}
      />
      <BottomNavigationAction
        label="favorites"
        value="favorites"
        icon={<FavoriteIcon />}
      />
      <BottomNavigationAction
        label="location"
        value="location"
        icon={<LocationOnIcon />}
      />
    </BottomNavigation>
  );
}

We set the value prop for each item so that we can use a name that we want for the state instead of an index number.

Breadcrumbs

We can add breadcrumbs to let us click links on navigation hierarchies.

To add one, we can use the Breadcrumbs components with Link s inside.

For example, we can write:

import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import Link from "@material-ui/core/Link";

export default function App() {
  const handleClick = event => {
    event.preventDefault();
    console.info("clicked.");
  };
  return (
    <Breadcrumbs aria-label="breadcrumb">
      <Link color="inherit" href="/" onClick={handleClick}>
        home
      </Link>
      <Link color="inherit" href="/profile/" onClick={handleClick}>
        profile
      </Link>
      <Link color="inherit" href="/profile/user" onClick={handleClick}>
        user
      </Link>
    </Breadcrumbs>
  );
}

We have the Breadcrumbs component surrounding the Link components.

color is inherited from the parent.

href has the URL for the link.

onClick lets us listen for item clicks.

Active Last Breadcrumb

We can make the last item active with the textPrimary value for the color prop.

For example, we can write:

import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import Link from "@material-ui/core/Link";

export default function App() {
  const handleClick = event => {
    event.preventDefault();
    console.info("clicked.");
  };
  return (
    <Breadcrumbs aria-label="breadcrumb">
      <Link color="inherit" href="/" onClick={handleClick}>
        home
      </Link>
      <Link color="inherit" href="/profile/" onClick={handleClick}>
        profile
      </Link>
      <Link color="textPrimary" href="/profile/user" onClick={handleClick}>
        user
      </Link>
    </Breadcrumbs>
  );
}

We added the color prop with the textPrimary string to make it highlight.

Custom Separator

To change the default separator, we can use the separator prop.

For example, we can write:

import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import Link from "@material-ui/core/Link";

export default function App() {
  const handleClick = event => {
    event.preventDefault();
    console.info("clicked.");
  };
  return (
    <Breadcrumbs separator="-">
      <Link color="inherit" href="/" onClick={handleClick}>
        home
      </Link>
      <Link color="inherit" href="/profile/" onClick={handleClick}>
        profile
      </Link>
      <Link color="textPrimary" href="/profile/user" onClick={handleClick}>
        user
      </Link>
    </Breadcrumbs>
  );
}

to change the default separator to the - character.

Collapsed Breadcrumbs

If we have lots of breadcrumbs, we can set the maxItems prop to set the max number of breadcrumb items to show.

For example, we can write:

import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import Link from "@material-ui/core/Link";

export default function App() {
  const handleClick = event => {
    event.preventDefault();
    console.info("clicked.");
  };
  return (
    <Breadcrumbs maxItems={2}>
      <Link color="inherit" href="/" onClick={handleClick}>
        home
      </Link>
      <Link color="inherit" href="/profile/" onClick={handleClick}>
        profile
      </Link>
      <Link color="textPrimary" href="/profile/user" onClick={handleClick}>
        user
      </Link>
    </Breadcrumbs>
  );
}

to limit the items to display to 2 with the maxItems prop.

Conclusion

We can add a bottom navigation bar to our app with the BottomNavigation component.

Breadcrumbs lets us add a breadcrumb to the navigation items in a hierarchy.

Categories
Material UI

Material UI — Date and Time Pickers and Radio Buttons

Material UI is a Material Design library made for React.

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

In this article, we’ll look at how to add date and time pickers and radio buttons with Material UI.

Date / Time Pickers

We can add a native date picker with the type set to date .

For example, we can write:

import React from "react";
import TextField from "@material-ui/core/TextField";

export default function App() {
  return (
    <div>
      <form noValidate>
        <TextField
          id="date"
          label="Birthday"
          type="date"
          defaultValue="2020-05-26"
          InputLabelProps={{
            shrink: true
          }}
        />
      </form>
    </div>
  );
}

to add a date picker.

We used the TextField component to add the text field.

defaultValue is used to set the default value of the picker.

Date and Time Pickers

If we want to add a picker for both the date and time, we can set the type

For example, we can write:

import React from "react";
import TextField from "@material-ui/core/TextField";

export default function App() {
  return (
    <div>
      <form noValidate>
        <TextField
          id="date"
          label="Birthday"
          type="datetime-local"
          defaultValue="2021-05-26T10:30"
          InputLabelProps={{
            shrink: true
          }}
        />
      </form>
    </div>
  );
}

We set the type to datetime-local to show a native date and time picker.

Time Pickers

To add a time picker only, we can set the type of the TextField to time .

For example, we can write:

import React from "react";
import TextField from "@material-ui/core/TextField";

export default function App() {
  return (
    <div>
      <form noValidate>
        <TextField
          id="time"
          label="Clock"
          type="time"
          defaultValue="07:30"
          InputLabelProps={{
            shrink: true
          }}
        />
      </form>
    </div>
  );
}

to display a native time picker.

Radio Buttons

Radio buttons let the user select one option from a set.

We can put one more radio buttons into a RadioGroup .

For example, we can write:

import React from "react";
import RadioGroup from "@material-ui/core/RadioGroup";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Radio from "@material-ui/core/Radio";

export default function App() {
  const [value, setValue] = React.useState("apple");

  const handleChange = event => {
    setValue(event.target.value);
  };

  return (
    <div>
      <form noValidate>
        <RadioGroup name="fruit" value={value} onChange={handleChange}>
          <FormControlLabel value="apple" control={<Radio />} label="apple" />
          <FormControlLabel value="orange" control={<Radio />} label="orange" />
          <FormControlLabel value="banana" control={<Radio />} label="banana" />
          <FormControlLabel
            value="grape"
            disabled
            control={<Radio />}
            label="grape"
          />
        </RadioGroup>
      </form>
    </div>
  );
}

We added the RadioGroup component to add a group of radio buttons.

Then we add the FormControlLabel to add the label for the radio button.

The value is the value for the radio button.

And we put the radio button inside each FormControlLabel .

The label sets the label of each radio button.

We can add a disable radio button with the disabled prop.

To set the value that the user selects as the state value, we have the handleChange function passed to the onChange prop.

Then we can set the value of the value prop as the value of the value state when we select an option.

Standalone Radio Buttons

The Radio component can be used as a standalone component.

For example, we can write:

import React from "react";
import Radio from "@material-ui/core/Radio";

export default function App() {
  const [value, setValue] = React.useState("apple");

  const handleChange = event => {
    setValue(event.target.value);
  };

  return (
    <div>
      <form noValidate>
        <Radio
          checked={value === "apple"}
          onChange={handleChange}
          value="apple"
          name="fruit"
        />
        <Radio
          checked={value === "orange"}
          onChange={handleChange}
          value="orange"
          name="fruit"
        />
      </form>
    </div>
  );
}

We have a Radio components to show the radio buttons without the labels.

The checked state is set by comparing the selectedvalue against the value of the radio button.

onChange is the same as the previous example.

Label Placement

The placement of the label can be changed with the labelPlacement prop.

For example, we can write:

import React from "react";
import Radio from "@material-ui/core/Radio";
import FormControlLabel from "@material-ui/core/FormControlLabel";

export default function App() {
  return (
    <div>
      <form noValidate>
        <FormControlLabel
          value="bottom"
          control={<Radio color="primary" />}
          label="Bottom"
          labelPlacement="bottom"
        />
      </form>
    </div>
  );
}

We set the labelPlacement prop to bottom to place the label below the radio button.

Other possible values include top , start , and end .

Conclusion

We can add date and time pickers with the TextField component.

To add radio buttons, we can use FormControlLabel and Radio components.

Radio buttons can be added without labels.

Categories
Material UI

Material UI — Floating Action Buttons

Material UI is a Material Design library made for React.

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

In this article, we’ll look at how to add floating buttons with Material UI.

Floating Action Button

We can add floating action buttons with the Fab component.

For instance, we can write:

import React from "react";
import Fab from "@material-ui/core/Fab";
import AddIcon from "@material-ui/icons/Add";

export default function App() {
  return (
    <Fab color="primary" aria-label="add">
      <AddIcon />
    </Fab>
  );
}

to add a floating action button to our app with the Fab component.

We have an icon inside it.

Size

To change the size, we set the size prop.

For instance, we can write:

import React from "react";
import Fab from "@material-ui/core/Fab";
import AddIcon from "@material-ui/icons/Add";

export default function App() {
  return (
    <Fab size="small">
      <AddIcon />
    </Fab>
  );
}

to change the button size to small.

Animation

We can animate the display of floating action buttons when we switch tabs.

To add the animation, we write:

import React from "react";
import Fab from "@material-ui/core/Fab";
import SwipeableViews from "react-swipeable-views";
import AppBar from "@material-ui/core/AppBar";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import AddIcon from "@material-ui/icons/Add";
import EditIcon from "@material-ui/icons/Edit";
import UpIcon from "@material-ui/icons/KeyboardArrowUp";
import Zoom from "@material-ui/core/Zoom";

function TabPanel(props) {
  const { children, value, index, ...other } = props;

return (
    <Typography
      component="div"
      role="tabpanel"
      hidden={value !== index}
      id={`action-tabpanel-${index}`}
      aria-labelledby={`action-tab-${index}`}
      {...other}
    >
      {value === index && <Box p={3}>{children}</Box>}
    </Typography>
  );
}

export default function App() {
  const [value, setValue] = React.useState(0);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };

  const handleChangeIndex = index => {
    setValue(index);
  };

  const fabs = [
    {
      color: "primary",
      icon: <AddIcon />,
      label: "Add"
    },
    {
      color: "secondary",
      icon: <EditIcon />,
      label: "Edit"
    },
    {
      color: "inherit",
      icon: <UpIcon />,
      label: "Expand"
    }
  ];

return (
    <div>
      <AppBar position="static" color="default">
        <Tabs
          value={value}
          onChange={handleChange}
          indicatorColor="primary"
          textColor="primary"
          variant="fullWidth"
          aria-label="action tabs example"
        >
          <Tab label="Item One" />
          <Tab label="Item Two" />
          <Tab label="Item Three" />
        </Tabs>
      </AppBar>
      <SwipeableViews axis="x" index={value} onChangeIndex={handleChangeIndex}>
        <TabPanel value={value} index={0}>
          Item One
        </TabPanel>
        <TabPanel value={value} index={1}>
          Item Two
        </TabPanel>
        <TabPanel value={value} index={2}>
          Item Three
        </TabPanel>
      </SwipeableViews>
      {fabs.map((fab, index) => (
        <Zoom
          key={fab.color}
          in={value === index}
          timeout={100}
          style={{
            transitionDelay: `0ms`
          }}
          unmountOnExit
        >
          <Fab
            aria-label={fab.label}
            className={fab.className}
            color={fab.color}
          >
            {fab.icon}
          </Fab>
        </Zoom>
      ))}
    </div>
  );
}

We add an AppBar to display a bar on the top with the Tab s below it.

Then to display the tab content, we have the TabPanel components to display them.

We created the TabPanel component ourselves to show and hide the items based on the index of the tab that’s selected.

Then we display the floating action buttons below that.

The p prop on the Box lets us add some padding.

We set the font with the Typography component.

component is set to div.

hidden lets us choose what content to hide, which is the tabs with the index that isn’t selected.

We put it inside the Zoom component so that we get a zoom transition when we display the buttons.

The duration of the transition will be the timeout value.

It’s measured in milliseconds.

unmountOnExit will clear the button when we switch tabs.

The index is updated when we click the tab heading, which will trigger the handleChange function to run.

If we swipe tabs, then the handleChangeIndex function runs and does the same thing as handleChange .

Conclusion

We can add floating action buttons with various styles and sizes.

Also, we can transition between different buttons within a tab.