diff --git a/assets/images/navigator.svg b/assets/images/navigator.svg new file mode 100644 index 000000000..dbbde3b2f --- /dev/null +++ b/assets/images/navigator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index a701ec067..bbfbf4475 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -29,6 +29,7 @@ import useRouter from "use-react-router"; import Container from "../Container"; import ErrorPage from "../ErrorPage"; import Navigator from "../Navigator"; +import NavigatorButton from "../NavigatorButton/NavigatorButton"; import AppActionContext from "./AppActionContext"; import AppHeaderContext from "./AppHeaderContext"; import { appLoaderHeight, drawerWidth, drawerWidthExpanded } from "./consts"; @@ -438,9 +439,12 @@ const AppLayout: React.FC = ({ children }) => { checked={isDark} onClick={toggleTheme} /> - + setNavigatorVisibility(true)} + />
) + .add("other", () => ); diff --git a/src/components/NavigatorButton/NavigatorButton.tsx b/src/components/NavigatorButton/NavigatorButton.tsx new file mode 100644 index 000000000..7fd21bb4c --- /dev/null +++ b/src/components/NavigatorButton/NavigatorButton.tsx @@ -0,0 +1,152 @@ +import navigatorIcon from "@assets/images/navigator.svg"; +import Grow from "@material-ui/core/Grow"; +import IconButton, { IconButtonProps } from "@material-ui/core/IconButton"; +import Paper from "@material-ui/core/Paper"; +import Popper from "@material-ui/core/Popper"; +import makeStyles from "@material-ui/core/styles/makeStyles"; +import classNames from "classnames"; +import React from "react"; +import ReactSVG from "react-inlinesvg"; +import { FormattedMessage } from "react-intl"; + +const useStyles = makeStyles( + theme => { + const triangle = (color: string, width: number) => ({ + borderBottom: `${width}px solid ${color}`, + borderLeft: `${width}px solid transparent`, + borderRight: `${width}px solid transparent`, + height: 0, + width: 0 + }); + + return { + keyTile: { + "&:first-child": { + marginLeft: theme.spacing() + }, + alignItems: "center", + background: theme.palette.background.default, + borderRadius: 8, + display: "inline-flex", + height: 32, + justifyContent: "center", + marginLeft: theme.spacing(0.5), + padding: theme.spacing(), + width: 32 + }, + keyTileLabel: { + verticalAlign: "middle" + }, + paper: { + "&:after": { + ...triangle(theme.palette.background.paper, 7), + content: "''", + left: theme.spacing(2) + 2, + position: "absolute", + top: -theme.spacing() + 1 + }, + "&:before": { + ...triangle(theme.palette.divider, 8), + content: "''", + left: theme.spacing(2) + 1, + position: "absolute", + top: -theme.spacing() + }, + border: `1px solid ${theme.palette.divider}`, + borderRadius: 6, + marginTop: theme.spacing(2), + padding: theme.spacing(2), + position: "relative" + }, + + root: { + "& path": { + color: theme.palette.primary.main + }, + "&:not(:hover)": { + backgroundColor: theme.palette.background.paper + }, + border: `1px solid ${theme.palette.divider}`, + height: 40, + marginRight: theme.spacing(2), + width: 40 + } + }; + }, + { + name: "NavigatorButton" + } +); + +export interface NavigatorButtonProps extends IconButtonProps { + isMac: boolean; +} + +const NavigatorButton: React.FC = ({ + className, + isMac, + ...props +}) => { + const classes = useStyles({}); + const helperTimer = React.useRef(null); + const [helperVisibility, setHelperVisibility] = React.useState(false); + const anchor = React.useRef(); + + const setHelper = () => { + helperTimer.current = setTimeout(() => setHelperVisibility(true), 2 * 1000); + }; + + const clearHelper = () => { + if (helperTimer.current) { + clearTimeout(helperTimer.current); + helperTimer.current = null; + } + setHelperVisibility(false); + }; + + return ( + <> + + + + + {({ TransitionProps, placement }) => ( + + + +
+ + {isMac ? "⌘" : "Ctrl"} + +
+
+ K +
+
+
+ )} +
+ + ); +}; + +NavigatorButton.displayName = "NavigatorButton"; +export default NavigatorButton;