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 a transfer list with Material UI.
Transfer List
A transfer list lets us move one or more items between lists.
To use it, we can write:
import React from "react";
import Grid from "@material-ui/core/Grid";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import Checkbox from "@material-ui/core/Checkbox";
import Button from "@material-ui/core/Button";
import Paper from "@material-ui/core/Paper";
function not(a, b) {
return a.filter(value => b.indexOf(value) === -1);
}
function intersection(a, b) {
return a.filter(value => b.indexOf(value) !== -1);
}
export default function App() {
const [checked, setChecked] = React.useState([]);
const [left, setLeft] = React.useState([0, 1, 2, 3]);
const [right, setRight] = React.useState([4, 5, 6, 7]);
const leftChecked = intersection(checked, left);
const rightChecked = intersection(checked, right);
const handleToggle = value => () => {
const currentIndex = checked.indexOf(value);
const newChecked = [...checked];
if (currentIndex === -1) {
newChecked.push(value);
} else {
newChecked.splice(currentIndex, 1);
}
setChecked(newChecked);
};
const handleAllRight = () => {
setRight(right.concat(left));
setLeft([]);
};
const handleCheckedRight = () => {
setRight(right.concat(leftChecked));
setLeft(not(left, leftChecked));
setChecked(not(checked, leftChecked));
};
const handleCheckedLeft = () => {
setLeft(left.concat(rightChecked));
setRight(not(right, rightChecked));
setChecked(not(checked, rightChecked));
};
const handleAllLeft = () => {
setLeft(left.concat(right));
setRight([]);
};
const customList = items => (
<Paper>
<List dense component="div" role="list">
{items.map(value => {
const labelId = `transfer-list-item-${value}-label`;
return (
<ListItem
key={value}
role="listitem"
button
onClick={handleToggle(value)}
>
<ListItemIcon>
<Checkbox
checked={checked.indexOf(value) !== -1}
tabIndex={-1}
disableRipple
inputProps={{ "aria-labelledby": labelId }}
/>
</ListItemIcon>
<ListItemText id={labelId} primary={`item ${value + 1}`} />
</ListItem>
);
})}
<ListItem />
</List>
</Paper>
);
return (
<Grid container spacing={2} justify="center" alignItems="center">
<Grid item>{customList(left)}</Grid>
<Grid item>
<Grid container direction="column" alignItems="center">
<Button
variant="outlined"
size="small"
onClick={handleAllRight}
disabled={left.length === 0}
aria-label="move all right"
>
≫
</Button>
<Button
variant="outlined"
size="small"
onClick={handleCheckedRight}
disabled={leftChecked.length === 0}
aria-label="move selected right"
>
>
</Button>
<Button
variant="outlined"
size="small"
onClick={handleCheckedLeft}
disabled={rightChecked.length === 0}
aria-label="move selected left"
>
<
</Button>
<Button
variant="outlined"
size="small"
onClick={handleAllLeft}
disabled={right.length === 0}
aria-label="move all left"
>
≪
</Button>
</Grid>
</Grid>
<Grid item>{customList(right)}</Grid>
</Grid>
);
}
We have a grid 2 lists side by side.
We added the list with the List
component.
The left list is created with the customList
component, which has a List
with some items inside it.
Each item has its own checkbox so that’s we can check them off and move them.
The moving is done by a few functions.
The handleAllRight
function moves everything to the right.
handleCheckedRight
moves everything that’s checked to the right.
handleCheckedLeft
moves the items that are check to the left list.
handleAllLeft
moves all items to the left list.
The move is done by a few helper functions.
setLeft
and setRight
sets the items for the left and right respectively.
We concatenate the existing items with the ones that’s checked in each function.
setChecked
is used to set the checked value of each item.
It only unchecks that values that are moved.
The example is simplified from the one at https://material-ui.com/components/transfer-list/
Conclusion
We can make a transfer list by following the Material UI example.
We make 2 lists with their own items.
The items are on each list are determined by the state.
Then we can move them by concatenating to the new list and removing them from the old list.