Add styles to menu
This commit is contained in:
parent
7f8ea0f254
commit
c1c5713592
5 changed files with 123 additions and 30 deletions
|
@ -203,7 +203,6 @@ const useStyles = makeStyles(
|
||||||
textAlign: "right"
|
textAlign: "right"
|
||||||
},
|
},
|
||||||
view: {
|
view: {
|
||||||
backgroundColor: theme.palette.background.default,
|
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
marginLeft: 0,
|
marginLeft: 0,
|
||||||
|
|
|
@ -1,26 +1,87 @@
|
||||||
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
|
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
|
||||||
import Paper from "@material-ui/core/Paper";
|
import Paper from "@material-ui/core/Paper";
|
||||||
import Popper from "@material-ui/core/Popper";
|
import Popper from "@material-ui/core/Popper";
|
||||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
|
||||||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||||
|
import Typography from "@material-ui/core/Typography";
|
||||||
|
import classNames from "classnames";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import SVG from "react-inlinesvg";
|
||||||
|
|
||||||
import { IMenuItem } from "../AppLayout/menuStructure";
|
import { IMenuItem } from "../AppLayout/menuStructure";
|
||||||
|
|
||||||
export interface MenuItemProps {
|
export interface MenuItemProps {
|
||||||
|
active: boolean;
|
||||||
|
isMenuShrunk: boolean;
|
||||||
menuItem: IMenuItem;
|
menuItem: IMenuItem;
|
||||||
onClick: (url: string, event: React.MouseEvent) => void;
|
onClick: (url: string, event: React.MouseEvent) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
theme => ({
|
theme => ({
|
||||||
|
hideLabel: {
|
||||||
|
"&$label": {
|
||||||
|
opacity: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
"& svg": {
|
||||||
|
height: 24,
|
||||||
|
width: 24
|
||||||
|
},
|
||||||
|
marginRight: theme.spacing(1.5),
|
||||||
|
transition: theme.transitions.duration.shortest + "ms"
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
cursor: "pointer",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
opacity: 1,
|
||||||
|
transition: theme.transitions.duration.shortest + "ms"
|
||||||
|
},
|
||||||
paper: {
|
paper: {
|
||||||
borderRadius: 16,
|
borderRadius: 16,
|
||||||
|
cursor: "default",
|
||||||
padding: theme.spacing(3)
|
padding: theme.spacing(3)
|
||||||
},
|
},
|
||||||
popper: {
|
popper: {
|
||||||
marginLeft: theme.spacing(3),
|
marginLeft: theme.spacing(3),
|
||||||
zIndex: 2
|
zIndex: 2
|
||||||
|
},
|
||||||
|
root: {
|
||||||
|
"&:hover": {
|
||||||
|
color: theme.palette.primary.main
|
||||||
|
},
|
||||||
|
borderBottomRightRadius: 100,
|
||||||
|
borderTopRightRadius: 100,
|
||||||
|
color: theme.palette.text.disabled,
|
||||||
|
cursor: "pointer",
|
||||||
|
display: "flex",
|
||||||
|
height: 56,
|
||||||
|
marginBottom: theme.spacing(),
|
||||||
|
overflow: "hidden",
|
||||||
|
padding: theme.spacing(2, 3),
|
||||||
|
transition: theme.transitions.duration.shortest + "ms",
|
||||||
|
width: 72
|
||||||
|
},
|
||||||
|
rootActive: {
|
||||||
|
"&$root": {
|
||||||
|
background: theme.palette.background.paper,
|
||||||
|
boxShadow: `9px 9px 20px 0 ${theme.palette.grey[300]}`,
|
||||||
|
color: theme.palette.primary.main
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rootExpanded: {
|
||||||
|
width: 210
|
||||||
|
},
|
||||||
|
subMenuLabel: {
|
||||||
|
"&$label": {
|
||||||
|
"&:not(:last-child)": {
|
||||||
|
marginBottom: theme.spacing(2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"&:hover": {
|
||||||
|
color: theme.palette.primary.main
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
@ -28,7 +89,12 @@ const useStyles = makeStyles(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const MenuItem: React.FC<MenuItemProps> = ({ menuItem, onClick }) => {
|
const MenuItem: React.FC<MenuItemProps> = ({
|
||||||
|
active,
|
||||||
|
menuItem,
|
||||||
|
isMenuShrunk,
|
||||||
|
onClick
|
||||||
|
}) => {
|
||||||
const classes = useStyles({});
|
const classes = useStyles({});
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const anchor = React.useRef<HTMLDivElement>(null);
|
const anchor = React.useRef<HTMLDivElement>(null);
|
||||||
|
@ -43,8 +109,25 @@ const MenuItem: React.FC<MenuItemProps> = ({ menuItem, onClick }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={anchor} onClick={event => handleClick(event, menuItem)}>
|
<div
|
||||||
{menuItem.label}
|
className={classNames(classes.root, {
|
||||||
|
[classes.rootActive]: active,
|
||||||
|
[classes.rootExpanded]: !isMenuShrunk
|
||||||
|
})}
|
||||||
|
ref={anchor}
|
||||||
|
onClick={event => handleClick(event, menuItem)}
|
||||||
|
>
|
||||||
|
{menuItem.icon && <SVG className={classes.icon} src={menuItem.icon} />}
|
||||||
|
<Typography
|
||||||
|
className={classNames(classes.label, {
|
||||||
|
[classes.hideLabel]: isMenuShrunk
|
||||||
|
})}
|
||||||
|
variant="body2"
|
||||||
|
data-test="menu-item-label"
|
||||||
|
data-test-id={menuItem.testingContextId}
|
||||||
|
>
|
||||||
|
{menuItem.label}
|
||||||
|
</Typography>
|
||||||
{menuItem.children && (
|
{menuItem.children && (
|
||||||
<Popper
|
<Popper
|
||||||
className={classes.popper}
|
className={classes.popper}
|
||||||
|
@ -60,13 +143,16 @@ const MenuItem: React.FC<MenuItemProps> = ({ menuItem, onClick }) => {
|
||||||
>
|
>
|
||||||
<Paper elevation={6} className={classes.paper}>
|
<Paper elevation={6} className={classes.paper}>
|
||||||
{menuItem.children.map(subMenuItem => (
|
{menuItem.children.map(subMenuItem => (
|
||||||
<div
|
<Typography
|
||||||
|
className={classNames(classes.label, classes.subMenuLabel)}
|
||||||
key={subMenuItem.url}
|
key={subMenuItem.url}
|
||||||
onClick={event => handleClick(event, subMenuItem)}
|
onClick={event => handleClick(event, subMenuItem)}
|
||||||
data-test="select-option"
|
data-test="submenu-item-label"
|
||||||
|
data-test-id={subMenuItem.testingContextId}
|
||||||
|
variant="body2"
|
||||||
>
|
>
|
||||||
{subMenuItem.label}
|
{subMenuItem.label}
|
||||||
</div>
|
</Typography>
|
||||||
))}
|
))}
|
||||||
</Paper>
|
</Paper>
|
||||||
</ClickAwayListener>
|
</ClickAwayListener>
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
import logoLight from "@assets/images/logo-sidebar-light.svg";
|
import logoLight from "@assets/images/logo-sidebar-light.svg";
|
||||||
|
import configurationIcon from "@assets/images/menu-configure-icon.svg";
|
||||||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||||
import {
|
import { configurationMenuUrl } from "@saleor/configuration";
|
||||||
configurationMenuUrl,
|
|
||||||
createConfigurationMenu
|
|
||||||
} from "@saleor/configuration";
|
|
||||||
import { User } from "@saleor/fragments/types/User";
|
import { User } from "@saleor/fragments/types/User";
|
||||||
import useLocalStorage from "@saleor/hooks/useLocalStorage";
|
import useLocalStorage from "@saleor/hooks/useLocalStorage";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import classNames from "classnames";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import SVG from "react-inlinesvg";
|
import SVG from "react-inlinesvg";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
@ -19,16 +16,10 @@ import { isMenuActive } from "./utils";
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
theme => ({
|
theme => ({
|
||||||
logo: {
|
logo: {
|
||||||
margin: "36px 0 0 19px"
|
margin: `36px 0 ${theme.spacing(3)}px 19px`
|
||||||
},
|
},
|
||||||
root: {
|
root: {
|
||||||
transition: "width 0.5s ease",
|
transition: "width 0.5s ease"
|
||||||
width: 210
|
|
||||||
},
|
|
||||||
shrunk: {
|
|
||||||
"&$root": {
|
|
||||||
width: 72
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
@ -62,16 +53,12 @@ const SideBar: React.FC<SideBarProps> = ({
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={classes.root}>
|
||||||
className={classNames(classes.root, {
|
|
||||||
[classes.shrunk]: isShrunk
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div className={classes.logo}>
|
<div className={classes.logo}>
|
||||||
<SVG src={logoLight} />
|
<SVG src={logoLight} />
|
||||||
</div>
|
</div>
|
||||||
{menuItems.map(menuItem => {
|
{menuItems.map(menuItem => {
|
||||||
// const isActive = isMenuActive(location, menuItem);
|
const isActive = isMenuActive(location, menuItem);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
menuItem.permission &&
|
menuItem.permission &&
|
||||||
|
@ -82,13 +69,27 @@ const SideBar: React.FC<SideBarProps> = ({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <MenuItem menuItem={menuItem} onClick={onMenuItemClick} />;
|
return (
|
||||||
|
<MenuItem
|
||||||
|
active={isActive}
|
||||||
|
isMenuShrunk={isShrunk}
|
||||||
|
menuItem={menuItem}
|
||||||
|
onClick={onMenuItemClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
{renderConfigure && (
|
{renderConfigure && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
active={
|
||||||
|
!menuItems.reduce(
|
||||||
|
(acc, menuItem) => acc || isMenuActive(location, menuItem),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
isMenuShrunk={isShrunk}
|
||||||
menuItem={{
|
menuItem={{
|
||||||
ariaLabel: "configure",
|
ariaLabel: "configure",
|
||||||
icon: null,
|
icon: configurationIcon,
|
||||||
label: intl.formatMessage(sectionNames.configuration),
|
label: intl.formatMessage(sectionNames.configuration),
|
||||||
testingContextId: "configure",
|
testingContextId: "configure",
|
||||||
url: configurationMenuUrl
|
url: configurationMenuUrl
|
||||||
|
|
|
@ -4,6 +4,13 @@ import { matchPath } from "react-router";
|
||||||
import { IMenuItem } from "../AppLayout/menuStructure";
|
import { IMenuItem } from "../AppLayout/menuStructure";
|
||||||
|
|
||||||
export function isMenuActive(location: string, menuItem: IMenuItem) {
|
export function isMenuActive(location: string, menuItem: IMenuItem) {
|
||||||
|
if (menuItem.children) {
|
||||||
|
return menuItem.children.reduce(
|
||||||
|
(acc, subMenuItem) => acc || isMenuActive(location, subMenuItem),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return location.split("?")[0] === orderDraftListUrl().split("?")[0] &&
|
return location.split("?")[0] === orderDraftListUrl().split("?")[0] &&
|
||||||
menuItem.url.split("?")[0] === orderListUrl().split("?")[0]
|
menuItem.url.split("?")[0] === orderListUrl().split("?")[0]
|
||||||
? false
|
? false
|
||||||
|
|
|
@ -196,7 +196,7 @@ export const sectionNames = defineMessages({
|
||||||
description: "draft orders section name"
|
description: "draft orders section name"
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
defaultMessage: "Home",
|
defaultMessage: "Dashboard",
|
||||||
description: "home section name"
|
description: "home section name"
|
||||||
},
|
},
|
||||||
navigation: {
|
navigation: {
|
||||||
|
|
Loading…
Reference in a new issue