Skip to content

Commit

Permalink
Merge pull request #5239 from reactioncommerce/feat-mikemurray-side-p…
Browse files Browse the repository at this point in the history
…anel

feat: Add DetailDrawer component for supplementary views
  • Loading branch information
kieckhafer authored Jun 27, 2019
2 parents 365bbe7 + 809eae9 commit 6cebfa6
Show file tree
Hide file tree
Showing 19 changed files with 567 additions and 118 deletions.
85 changes: 85 additions & 0 deletions imports/client/ui/components/DetailDrawer/DetailDrawer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { Children } from "react";
import PropTypes from "prop-types";
import AppBar from "@material-ui/core/AppBar";
import IconButton from "@material-ui/core/IconButton";
import Toolbar from "@material-ui/core/Toolbar";
import Drawer from "@material-ui/core/Drawer";
import withStyles from "@material-ui/core/styles/withStyles";
import CloseIcon from "mdi-material-ui/Close";
import { Typography } from "@material-ui/core";
import { UIContext } from "../../context/UIContext";

const styles = (theme) => ({
action: {
marginLeft: theme.spacing.unit
},
content: {
paddingTop: theme.spacing.unit,
marginLeft: "-1px",
marginRight: "-1px"
},
title: {
flex: 1,
paddingLeft: theme.spacing.unit
}
});

/**
* Detail drawer used for displaying supplementary info and actions for a view.
* @param {Object} props Component props
* @returns {React.Component} Sidebar component
*/
function DetailDrawer(props) {
const {
anchor,
children,
classes,
title
} = props;

return (
<UIContext.Consumer>
{({ isMobile, onCloseDetailDrawer, isDetailDrawerOpen }) => (
<Drawer
elevation={2}
variant={isMobile ? "temporary" : "persistent"}
anchor={anchor}
open={isDetailDrawerOpen}
onClose={onCloseDetailDrawer}
ModalProps={{
keepMounted: true // Better open performance on mobile.
}}
>
<AppBar
color="default"
elevation={0}
position="sticky"
>
<Toolbar>
<Typography className={classes.title} variant="h3">{title}</Typography>
<IconButton onClick={onCloseDetailDrawer} size="small">
<CloseIcon />
</IconButton>
</Toolbar>
</AppBar>
{Children.map(children, (child) => (
<div className={classes.content}>{child}</div>
))}
</Drawer>
)}
</UIContext.Consumer>
);
}

DetailDrawer.propTypes = {
anchor: PropTypes.oneOf(["left", "right", "top", "bottom"]),
children: PropTypes.node,
classes: PropTypes.object,
title: PropTypes.string
};

DetailDrawer.defaultProps = {
anchor: "right"
};

export default withStyles(styles, { name: "RuiDetailDrawer" })(DetailDrawer);
1 change: 1 addition & 0 deletions imports/client/ui/components/DetailDrawer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./DetailDrawer";
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import PropTypes from "prop-types";
import Button from "@material-ui/core/Button";
import { UIContext } from "../../context/UIContext";

/**
* Detail drawer open button
* @param {Object} props Component props
* @returns {React.Component} Sidebar component
*/
function DetailDrawerButton(props) {
const {
component: ComponentProp,
children,
...otherProps
} = props;

return (
<UIContext.Consumer>
{({ onToggleDetailDrawer }) => (
<ComponentProp {...otherProps} onClick={onToggleDetailDrawer}>{children}</ComponentProp>
)}
</UIContext.Consumer>
);
}

DetailDrawerButton.propTypes = {
children: PropTypes.node,
component: PropTypes.func
};

DetailDrawerButton.defaultProps = {
component: Button
};

export default DetailDrawerButton;
1 change: 1 addition & 0 deletions imports/client/ui/components/DetailDrawerButton/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./DetailDrawerButton";
13 changes: 10 additions & 3 deletions imports/client/ui/components/PrimaryAppBar/PrimaryAppBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const styles = (theme) => ({
primarySidebarOpen: {
...theme.mixins.leadingPaddingWhenPrimaryDrawerIsOpen
},
detailDrawerOpen: {
...theme.mixins.trailingPaddingWhenDetailDrawerIsOpen
},
title: {
flex: 1
}
Expand All @@ -31,13 +34,17 @@ const styles = (theme) => ({
function PrimaryAppBar({ children, classes, title }) {
return (
<UIContext.Consumer>
{({ isMobile, isPrimarySidebarOpen, onTogglePrimarySidebar }) => {
{({ isMobile, isDetailDrawerOpen, isPrimarySidebarOpen, onTogglePrimarySidebar }) => {
const toolbarClassName = classNames({
// Add padding to the right when the primary sidebar is open,
// Add padding to the left when the primary sidebar is open,
// only if we're on desktop. On mobile the sidebar floats over
// the content like a modal that's docked to either the left
// or right side of the screen.
[classes.primarySidebarOpen]: isPrimarySidebarOpen && !isMobile
[classes.primarySidebarOpen]: isPrimarySidebarOpen && !isMobile,

// Add padding to the right when the detail sidebar is open.
// Omit on mobile as the sidebar will float over content.
[classes.detailDrawerOpen]: isDetailDrawerOpen && !isMobile
});

return (
Expand Down
13 changes: 12 additions & 1 deletion imports/client/ui/components/Sidebar/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ const activeClassName = "nav-item-active";
const routeSort = (routeA, routeB) => (routeA.priority || Number.MAX_SAFE_INTEGER) - (routeB.priority || Number.MAX_SAFE_INTEGER);

const styles = (theme) => ({
closeButton: {
"color": theme.palette.colors.white,
"backgroundColor": theme.palette.colors.darkBlue500,
"&:hover": {
"backgroundColor": theme.palette.colors.darkBlue600,
// Reset on touch devices, it doesn't add specificity
"@media (hover: none)": {
backgroundColor: theme.palette.colors.darkBlue500
}
}
},
icon: {
width: 32,
display: "flex",
Expand Down Expand Up @@ -115,7 +126,7 @@ function Sidebar(props) {
<ShopLogoWithData className={classes.shopLogo} shouldShowShopName size={32} />

<Hidden mdUp>
<Fab color="secondary" onClick={onDrawerClose} size="small">
<Fab classes={{ root: classes.closeButton }} onClick={onDrawerClose} size="small">
<CloseIcon />
</Fab>
</Hidden>
Expand Down
3 changes: 3 additions & 0 deletions imports/client/ui/context/UIContext.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { createContext } from "react";

export const UIContext = createContext({
isDetailDrawerOpen: false,
isMobile: false,
isPrimarySidebarOpen: true,
onCloseDetailDrawer: () => { },
onClosePrimarySidebar: () => { },
onToggleDetailDrawer: () => { },
onTogglePrimarySidebar: () => { }
});
13 changes: 9 additions & 4 deletions imports/client/ui/layouts/ContentViewExtraWideLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@ const styles = (theme) => ({
flexGrow: 1,
transition: "padding 225ms cubic-bezier(0, 0, 0.2, 1) 0ms"
},
leftSidebarOpen: {
leadingDrawerOpen: {
...theme.mixins.leadingPaddingWhenPrimaryDrawerIsOpen
},
trailingDrawerOpen: {
...theme.mixins.leadingPaddingWhenPrimaryDrawerIsOpen
}
});

const ContentViewExtraWideLayout = ({ children, classes, isSidebarOpen }) => (
const ContentViewExtraWideLayout = ({ children, classes, isLeadingDrawerOpen, isTrailingDrawerOpen }) => (
<div
className={
classNames(classes.root, {
[classes.leftSidebarOpen]: isSidebarOpen
[classes.leadingDrawerOpen]: isLeadingDrawerOpen,
[classes.trailingDrawerOpen]: isTrailingDrawerOpen
})
}
>
Expand All @@ -38,8 +42,9 @@ const ContentViewExtraWideLayout = ({ children, classes, isSidebarOpen }) => (
ContentViewExtraWideLayout.propTypes = {
children: PropTypes.node,
classes: PropTypes.object,
isLeadingDrawerOpen: PropTypes.bool,
isMobile: PropTypes.bool,
isSidebarOpen: PropTypes.bool
isTrailingDrawerOpen: PropTypes.bool
};

export default withStyles(styles, { name: "RuiContentViewExtraWideLayout" })(ContentViewExtraWideLayout);
13 changes: 9 additions & 4 deletions imports/client/ui/layouts/ContentViewFullLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ const styles = (theme) => ({
transition: "padding 225ms cubic-bezier(0, 0, 0.2, 1) 0ms",
overflow: "hidden"
},
leftSidebarOpen: {
leadingDrawerOpen: {
paddingLeft: theme.spacing.drawerWidth
},
trailingDrawerOpen: {
paddingRight: theme.spacing.detailDrawerWidth
}
});

const ContentViewFullLayout = ({ children, classes, isSidebarOpen }) => (
const ContentViewFullLayout = ({ children, classes, isLeadingDrawerOpen, isTrailingDrawerOpen }) => (
<div
className={
classNames(classes.root, {
[classes.leftSidebarOpen]: isSidebarOpen
[classes.leadingDrawerOpen]: isLeadingDrawerOpen,
[classes.trailingDrawerOpen]: isTrailingDrawerOpen
})
}
>
Expand All @@ -37,8 +41,9 @@ const ContentViewFullLayout = ({ children, classes, isSidebarOpen }) => (
ContentViewFullLayout.propTypes = {
children: PropTypes.node,
classes: PropTypes.object,
isLeadingDrawerOpen: PropTypes.bool,
isMobile: PropTypes.bool,
isSidebarOpen: PropTypes.bool
isTrailingDrawerOpen: PropTypes.bool
};

export default withStyles(styles, { name: "RuiContentViewFullLayout" })(ContentViewFullLayout);
13 changes: 9 additions & 4 deletions imports/client/ui/layouts/ContentViewStandardLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ const styles = (theme) => ({
paddingBottom: theme.spacing.unit * 2,
margin: "0 auto"
},
leftSidebarOpen: {
leadingDrawerOpen: {
paddingLeft: theme.spacing.drawerWidth
},
trailingDrawerOpen: {
paddingRight: theme.spacing.detailDrawerWidth
}
});

const ContentViewStandardLayout = ({ children, classes, isSidebarOpen }) => (
const ContentViewStandardLayout = ({ children, classes, isLeadingDrawerOpen, isTrailingDrawerOpen }) => (
<div
className={
classNames(classes.root, {
[classes.leftSidebarOpen]: isSidebarOpen
[classes.leadingDrawerOpen]: isLeadingDrawerOpen,
[classes.trailingDrawerOpen]: isTrailingDrawerOpen
})
}
>
Expand All @@ -39,8 +43,9 @@ const ContentViewStandardLayout = ({ children, classes, isSidebarOpen }) => (
ContentViewStandardLayout.propTypes = {
children: PropTypes.node,
classes: PropTypes.object,
isLeadingDrawerOpen: PropTypes.bool,
isMobile: PropTypes.bool,
isSidebarOpen: PropTypes.bool
isTrailingDrawerOpen: PropTypes.bool
};

export default withStyles(styles, { name: "RuiContentViewStandardLayout" })(ContentViewStandardLayout);
Loading

0 comments on commit 6cebfa6

Please sign in to comment.