-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
/
RouterBreadcrumbs.tsx
126 lines (114 loc) · 3.73 KB
/
RouterBreadcrumbs.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* eslint-disable no-nested-ternary */
import * as React from 'react';
import { makeStyles, Theme, createStyles } from '@material-ui/core/styles';
import List from '@material-ui/core/List';
import Link, { LinkProps } from '@material-ui/core/Link';
import ListItem from '@material-ui/core/ListItem';
import Collapse from '@material-ui/core/Collapse';
import ListItemText from '@material-ui/core/ListItemText';
import Typography from '@material-ui/core/Typography';
import ExpandLess from '@material-ui/icons/ExpandLess';
import ExpandMore from '@material-ui/icons/ExpandMore';
import Breadcrumbs from '@material-ui/core/Breadcrumbs';
import { Route, MemoryRouter } from 'react-router';
import { Link as RouterLink } from 'react-router-dom';
import { Omit } from '@material-ui/types';
interface ListItemLinkProps extends LinkProps {
to: string;
open?: boolean;
}
const breadcrumbNameMap: { [key: string]: string } = {
'/inbox': 'Inbox',
'/inbox/important': 'Important',
'/trash': 'Trash',
'/spam': 'Spam',
'/drafts': 'Drafts',
};
function ListItemLink(props: Omit<ListItemLinkProps, 'ref'>) {
const { to, open, ...other } = props;
const primary = breadcrumbNameMap[to];
return (
<li>
<ListItem button component={RouterLink} to={to} {...other}>
<ListItemText primary={primary} />
{open != null ? open ? <ExpandLess /> : <ExpandMore /> : null}
</ListItem>
</li>
);
}
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex',
flexDirection: 'column',
width: 360,
},
lists: {
backgroundColor: theme.palette.background.paper,
marginTop: theme.spacing(1),
},
nested: {
paddingLeft: theme.spacing(4),
},
}),
);
interface LinkRouterProps extends LinkProps {
to: string;
replace?: boolean;
}
const LinkRouter = (props: LinkRouterProps) => (
<Link {...props} component={RouterLink as any} />
);
export default function RouterBreadcrumbs() {
const classes = useStyles();
const [open, setOpen] = React.useState(true);
const handleClick = () => {
setOpen((prevOpen) => !prevOpen);
};
return (
<MemoryRouter initialEntries={['/inbox']} initialIndex={0}>
<div className={classes.root}>
<Route>
{({ location }) => {
const pathnames = location.pathname.split('/').filter((x) => x);
return (
<Breadcrumbs aria-label="breadcrumb">
<LinkRouter color="inherit" to="/">
Home
</LinkRouter>
{pathnames.map((value, index) => {
const last = index === pathnames.length - 1;
const to = `/${pathnames.slice(0, index + 1).join('/')}`;
return last ? (
<Typography color="textPrimary" key={to}>
{breadcrumbNameMap[to]}
</Typography>
) : (
<LinkRouter color="inherit" to={to} key={to}>
{breadcrumbNameMap[to]}
</LinkRouter>
);
})}
</Breadcrumbs>
);
}}
</Route>
<nav className={classes.lists} aria-label="mailbox folders">
<List>
<ListItemLink to="/inbox" open={open} onClick={handleClick} />
<Collapse component="li" in={open} timeout="auto" unmountOnExit>
<List disablePadding>
<ListItemLink
to="/inbox/important"
className={classes.nested}
/>
</List>
</Collapse>
<ListItemLink to="/trash" />
<ListItemLink to="/spam" />
</List>
</nav>
</div>
</MemoryRouter>
);
}