Add hidden & layered breadcrumbs

- Override style of given components
This commit is contained in:
tudi2d
2021-02-12 00:27:49 +01:00
parent f4f4ad1f4f
commit c040c9d118
2 changed files with 170 additions and 65 deletions
@@ -13,9 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { Breadcrumbs } from '.';
import { Popover, Typography, Box, List, ListItem } from '@material-ui/core';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
import React, { Fragment } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { Breadcrumbs } from '.';
import { Link } from '../../components/Link';
export default {
@@ -24,12 +27,101 @@ export default {
};
// export const InHeader = () => <Breadcrumbs pages={pages} />;
export const OutsideOfHeader = () => (
<MemoryRouter>
<Breadcrumbs>
<Link to="/">Home</Link>
<Link to="/">Home</Link>
</Breadcrumbs>
</MemoryRouter>
);
// export const ExampleUsage = () => <Breadcrumbs pages={pages} />;
export const OutsideOfHeader = () => {
const [anchorEl, setAnchorEl] = React.useState<HTMLAnchorElement | null>(
null,
);
const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
return (
<MemoryRouter>
<p>
It might be the case that you want to keep your breadcrumbs outside of
the header. In that case, they should be positioned above the title of
the page.
</p>
<h2>Standard breadcrumbs</h2>
<p>
Underlined pages are links. This should show a hierarchical
relationship.
</p>
<Breadcrumbs>
<Link to="/">General Page</Link>
<Link to="/">Second Page</Link>
<Typography>Current page</Typography>
</Breadcrumbs>
<Breadcrumbs>
<Link to="/">General Page</Link>
<Typography>Current page</Typography>
</Breadcrumbs>
<Breadcrumbs>
<Typography>Current page</Typography>
</Breadcrumbs>
<h2>Hidden breadcrumbs</h2>
<p>
Use this when you have more than three breadcrumbs. When user clicks on
ellipses, expand the breadcrumbs out.
</p>
<Breadcrumbs>
<Link to="/">General Page</Link>
<Link to="/">Second Page</Link>
<Link to="/">Third Page</Link>
<Link to="/">Fourth Page</Link>
<Typography>Current page</Typography>
</Breadcrumbs>
<h2>Layered breadcrumbs</h2>
<p>
Use this when you want to show alternative breadcrumbs on the same
hierarchical level.
</p>
<Fragment>
<Breadcrumbs>
<Link to="/">General Page</Link>
<Link to="/" onClick={handleClick}>
<Box display="flex" alignItems="center">
<span>Second Page</span>
{open ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</Box>
</Link>
<Typography>Current page</Typography>
</Breadcrumbs>
<Popover
open={open}
onClose={handleClose}
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
<List>
<ListItem button style={{ textDecoration: 'underline' }}>
Parallel second page
</ListItem>
<ListItem button style={{ textDecoration: 'underline' }}>
Another parallel second page
</ListItem>
<ListItem button style={{ textDecoration: 'underline' }}>
Yet another, parallel second page
</ListItem>
</List>
</Popover>
</Fragment>
</MemoryRouter>
);
};
@@ -14,75 +14,88 @@
* limitations under the License.
*/
import React, { Fragment } from 'react';
import {
Typography,
Breadcrumbs as MUIBreadcrumbs,
Box,
Breadcrumbs as MaterialBreadcrumbs,
List,
ListItem,
Popover,
Typography,
withStyles,
} from '@material-ui/core';
import React, { ComponentProps, Fragment } from 'react';
type BreadcrumbsProps = {
children?: React.ReactNode;
};
type Props = ComponentProps<typeof MaterialBreadcrumbs>;
const UnderlinedText = withStyles({ root: { textDecoration: 'underline' } })(
Typography,
);
const ClickableText = withStyles({
root: {
textDecoration: 'underline',
cursor: 'pointer',
},
})(Typography);
const StyledBreadcrumbs = withStyles({
root: {},
li: { textDecoration: 'underline' },
})(MUIBreadcrumbs);
const StyledBox = withStyles(theme => ({
root: {
textDecoration: 'underline',
color: theme.palette.text.primary,
},
}))(Box);
export const Breadcrumbs = ({ children }: BreadcrumbsProps) => {
export const Breadcrumbs = ({ children, ...props }: Props) => {
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(
null,
);
if (children instanceof Array) {
const [firstPage, secondPage, ...expandablePages] = children;
const currentPage = children[children.length - 1];
const hasHiddenBreadcrumbs = children.length > 3;
const childrenArray = React.Children.toArray(children);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const [firstPage, secondPage, ...expandablePages] = childrenArray;
const currentPage = expandablePages.length
? expandablePages.pop()
: childrenArray[childrenArray.length - 1];
const hasHiddenBreadcrumbs = childrenArray.length > 3;
const handleClose = () => {
setAnchorEl(null);
};
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const open = Boolean(anchorEl);
return (
<Fragment>
<StyledBreadcrumbs aria-label="breadcrumb">
{children.length > 1 && firstPage}
{children.length > 2 && secondPage}
{hasHiddenBreadcrumbs && (
<UnderlinedText onClick={handleClick}>...</UnderlinedText>
)}
{currentPage}
</StyledBreadcrumbs>
<Popover
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
The content of the Popover.
</Popover>
</Fragment>
);
}
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
return (
<StyledBreadcrumbs aria-label="breadcrumb">{children}</StyledBreadcrumbs>
<Fragment>
<MaterialBreadcrumbs aria-label="breadcrumb" {...props}>
{childrenArray.length > 1 && <StyledBox clone>{firstPage}</StyledBox>}
{childrenArray.length > 2 && <StyledBox clone>{secondPage}</StyledBox>}
{hasHiddenBreadcrumbs && (
<ClickableText onClick={handleClick}>...</ClickableText>
)}
<Box style={{ fontStyle: 'italic' }} color="text.primary">
{currentPage}
</Box>
</MaterialBreadcrumbs>
<Popover
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
<List>
{expandablePages.map(pageLink => (
<ListItem button>
<StyledBox clone>{pageLink}</StyledBox>
</ListItem>
))}
</List>
</Popover>
</Fragment>
);
};