Skip to content

Commit

Permalink
Add responsive menu (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
WithoutPants authored and Leopere committed Dec 12, 2019
1 parent bb164f1 commit 50930f6
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 86 deletions.
82 changes: 68 additions & 14 deletions ui/v2/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FunctionComponent, useEffect } from "react";
import React, { FunctionComponent, useState } from "react";
import { Route, Switch } from "react-router-dom";
import { ErrorBoundary } from "./components/ErrorBoundary";
import Galleries from "./components/Galleries/Galleries";
Expand All @@ -11,26 +11,80 @@ import { Stats } from "./components/Stats";
import Studios from "./components/Studios/Studios";
import Tags from "./components/Tags/Tags";
import { SceneFilenameParser } from "./components/scenes/SceneFilenameParser";
import { Sidebar } from "./components/Sidebar";
import { IconName } from "@blueprintjs/core";

export interface IMenuItem {
icon: IconName
text: string
href: string
}

interface IProps {}

export const App: FunctionComponent<IProps> = (props: IProps) => {
const [menuOpen, setMenuOpen] = useState<boolean>(false);

function getSidebarClosedClass() {
if (!menuOpen) {
return " sidebar-closed";
}

return "";
}

const menuItems: IMenuItem[] = [
{
icon: "video",
text: "Scenes",
href: "/scenes"
},
{
href: "/scenes/markers",
icon: "map-marker",
text: "Markers"
},
{
href: "/galleries",
icon: "media",
text: "Galleries"
},
{
href: "/performers",
icon: "person",
text: "Performers"
},
{
href: "/studios",
icon: "mobile-video",
text: "Studios"
},
{
href: "/tags",
icon: "tag",
text: "Tags"
}
];

return (
<div className="bp3-dark">
<ErrorBoundary>
<MainNavbar />
<Switch>
<Route exact={true} path="/" component={Stats} />
<Route path="/scenes" component={Scenes} />
{/* <Route path="/scenes/:id" component={Scene} /> */}
<Route path="/galleries" component={Galleries} />
<Route path="/performers" component={Performers} />
<Route path="/tags" component={Tags} />
<Route path="/studios" component={Studios} />
<Route path="/settings" component={Settings} />
<Route path="/sceneFilenameParser" component={SceneFilenameParser} />
<Route component={PageNotFound} />
</Switch>
<MainNavbar onMenuToggle={() => setMenuOpen(!menuOpen)} menuItems={menuItems}/>
<Sidebar className={getSidebarClosedClass()} menuItems={menuItems}/>
<div className={"main" + getSidebarClosedClass()}>
<Switch>
<Route exact={true} path="/" component={Stats} />
<Route path="/scenes" component={Scenes} />
{/* <Route path="/scenes/:id" component={Scene} /> */}
<Route path="/galleries" component={Galleries} />
<Route path="/performers" component={Performers} />
<Route path="/tags" component={Tags} />
<Route path="/studios" component={Studios} />
<Route path="/settings" component={Settings} />
<Route path="/sceneFilenameParser" component={SceneFilenameParser} />
<Route component={PageNotFound} />
</Switch>
</div>
</ErrorBoundary>
</div>
);
Expand Down
109 changes: 38 additions & 71 deletions ui/v2/src/components/MainNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ import {
NavbarDivider,
NavbarGroup,
NavbarHeading,
Button,
} from "@blueprintjs/core";
import React, { FunctionComponent, useEffect, useState } from "react";
import { Link, NavLink } from "react-router-dom";
import useLocation from "react-use/lib/useLocation";
import { IMenuItem } from "../App";

interface IProps {}
interface IProps {
onMenuToggle() : void
menuItems: IMenuItem[]
}

export const MainNavbar: FunctionComponent<IProps> = (props) => {
const [newButtonPath, setNewButtonPath] = useState<string | undefined>(undefined);
Expand Down Expand Up @@ -46,76 +51,38 @@ export const MainNavbar: FunctionComponent<IProps> = (props) => {
}

return (
<Navbar fixedToTop={true}>
<div>
<NavbarGroup align="left">
<NavbarHeading><Link to="/" className="bp3-button bp3-minimal">Stash</Link></NavbarHeading>
<NavbarDivider />
<>
<Navbar fixedToTop={true}>
<div>
<NavbarGroup align="left">
<Button className="menu-button" icon="menu" onClick={() => props.onMenuToggle()}/>
<NavbarHeading><Link to="/" className="bp3-button bp3-minimal">Stash</Link></NavbarHeading>
<NavbarDivider />

<NavLink
exact={true}
to="/scenes"
className="bp3-button bp3-minimal bp3-icon-video"
activeClassName="bp3-active"
>
Scenes
</NavLink>

<NavLink
exact={true}
to="/scenes/markers"
className="bp3-button bp3-minimal bp3-icon-map-marker"
activeClassName="bp3-active"
>
Markers
</NavLink>

<NavLink
exact={true}
to="/galleries"
className="bp3-button bp3-minimal bp3-icon-media"
activeClassName="bp3-active"
>
Galleries
</NavLink>

<NavLink
exact={true}
to="/performers"
className="bp3-button bp3-minimal bp3-icon-person"
activeClassName="bp3-active"
>
Performers
</NavLink>

<NavLink
exact={true}
to="/studios"
className="bp3-button bp3-minimal bp3-icon-mobile-video"
activeClassName="bp3-active"
>
Studios
</NavLink>

<NavLink
exact={true}
to="/tags"
className="bp3-button bp3-minimal bp3-icon-tag"
activeClassName="bp3-active"
>
Tags
</NavLink>
</NavbarGroup>
<NavbarGroup align="right">
{renderNewButton()}
<NavLink
exact={true}
to="/settings"
className="bp3-button bp3-minimal bp3-icon-cog"
activeClassName="bp3-active"
/>
</NavbarGroup>
</div>
</Navbar>
{props.menuItems.map((i) => {
return (
<NavLink
exact={true}
to={i.href}
className={"bp3-button bp3-minimal collapsible-navlink bp3-icon-" + i.icon}
activeClassName="bp3-active"
>
{i.text}
</NavLink>
);
})}
</NavbarGroup>
<NavbarGroup align="right">
{renderNewButton()}
<NavLink
exact={true}
to="/settings"
className="bp3-button bp3-minimal bp3-icon-cog"
activeClassName="bp3-active"
/>
</NavbarGroup>
</div>
</Navbar>
</>
);
};
32 changes: 32 additions & 0 deletions ui/v2/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
MenuItem,
Menu,
IconName,
} from "@blueprintjs/core";
import React, { FunctionComponent } from "react";
import { IMenuItem } from "../App";

interface IProps {
className: string
menuItems: IMenuItem[]
}

export const Sidebar: FunctionComponent<IProps> = (props) => {
return (
<>
<div className={"sidebar" + props.className}>
<Menu large={true}>
{props.menuItems.map((i) => {
return (
<MenuItem
icon={i.icon}
text={i.text}
href={i.href}
/>
)
})}
</Menu>
</div>
</>
);
};
48 changes: 47 additions & 1 deletion ui/v2/src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -476,4 +476,50 @@ span.block {

.aliases-field > label{
font-weight: 300;
}
}

@media only screen and (max-width: 768px) {
// collapse menu items into sidemenu
.collapsible-navlink {
display: none;
}
}


.sidebar {
position: fixed;
top: 50px;
bottom: 0;
left: 0;
width: 200px;
background-color: #394b59;
transition: left 0.5s;
z-index: 11;
}

.sidebar.sidebar-closed {
left: -200px;
transition: left 0.5s;
}

// overlay menu on smaller devices
@media only screen and (min-width: 768px) {
// hide menu button on larger devices
.menu-button {
display: none;
}

.main {
margin-left: 200px;
transition: margin-left 0.5s;
}

.sidebar {
left: -200px;
}

.main.sidebar-closed {
margin-left: 0px;
transition: margin-left 0.5s;
}
}

0 comments on commit 50930f6

Please sign in to comment.