Backdrop and menu

This commit is contained in:
Max Lynch
2020-12-21 15:10:40 -06:00
parent b0aec7fc3d
commit f7974d10ac
6 changed files with 90 additions and 56 deletions
+17
View File
@@ -0,0 +1,17 @@
import classNames from 'classnames';
import { useCallback, useEffect, useState } from 'react';
const Backdrop = ({ open, onClose }) => {
return (
<div
onClick={onClose}
className={classNames('fixed z-10 inset-0 bg-black transition-opacity w-full h-full', {
'pointer-events-none': !open,
'opacity-10': open,
'opacity-0': !open,
})}
></div>
);
};
export default Backdrop;
+29
View File
@@ -0,0 +1,29 @@
import classNames from 'classnames';
const Menu = ({ open, onClose }) => (
<div
className={classNames(
'fixed z-40 transform transform-gpu translate w-48 h-full bg-gray-100 transition-transform',
{
'-translate-x-full': !open,
'-translate-x-0': open,
}
)}
>
<div className="p-4">
<h2 className="text-xl select-none">Menu</h2>
</div>
<ul>
<li>
<a
href="#"
className="text-gray-800 hover:text-gray-400 block px-4 py-2 rounded-md text-base font-medium"
>
Calendar
</a>
</li>
</ul>
</div>
);
export default Menu;
+7 -44
View File
@@ -1,30 +1,28 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from 'react';
import { Plugins } from '@capacitor/core'; import { Plugins } from '@capacitor/core';
const Nav = ({ page }) => { const Nav = ({ page, onShowMenu }) => {
const [showMenu, setShowMenu] = useState(false); const [showMenu, setShowMenu] = useState(false);
const [showMobileMenu, setShowMobileMenu] = useState(false);
useEffect(() => { useEffect(() => {
Plugins.StatusBar.setStyle({ Plugins.StatusBar.setStyle({
style: 'DARK' style: 'DARK',
}); });
}, []); }, []);
return ( return (
<nav <nav
className="bg-gray-800 w-full flex-0 flex items-end flex-row" className="bg-gray-800 w-full flex-0 flex items-end flex-row z-10"
style={{ style={{
height: `calc(env(safe-area-inset-bottom, 0px) + 64px)` height: `calc(env(safe-area-inset-bottom, 0px) + 64px)`,
}} }}
> >
<div className="max-w-7xl mx-auto px-2 sm:px-6 lg:px-8 flex-1"> <div className="max-w-7xl mx-auto px-2 sm:px-6 lg:px-8 flex-1">
<div className="relative flex items-center justify-between h-16"> <div className="relative flex items-center justify-between h-16">
<div <div
className="absolute inset-y-0 left-0 flex items-center sm:hidden" className="absolute inset-y-0 left-0 flex items-center sm:hidden"
onClick={() => setShowMobileMenu(!showMobileMenu)} onClick={onShowMenu}
> >
{/* Mobile menu button*/} {/* Mobile menu button*/}
<button <button
@@ -204,43 +202,8 @@ const Nav = ({ page }) => {
</div> </div>
</div> </div>
</div> </div>
{/*
Mobile menu, toggle classes based on menu state.
Menu open: "block", Menu closed: "hidden"
*/}
<div className={`${showMobileMenu ? '' : 'hidden sm:hidden'}`}>
<div className="px-2 pt-2 pb-3 space-y-1">
{/* Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" */}
<a
href="#"
className="bg-gray-900 text-white block px-3 py-2 rounded-md text-base font-medium"
>
Dashboard
</a>
<a
href="#"
className="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
>
Team
</a>
<a
href="#"
className="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
>
Projects
</a>
<a
href="#"
className="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
>
Calendar
</a>
</div>
</div>
</nav> </nav>
); );
} };
export default Nav; export default Nav;
+2 -1
View File
@@ -4132,7 +4132,8 @@
"prettier": { "prettier": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
"integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==" "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
"dev": true
}, },
"pretty-hrtime": { "pretty-hrtime": {
"version": "1.0.3", "version": "1.0.3",
+3 -1
View File
@@ -16,9 +16,11 @@
"classnames": "^2.2.6", "classnames": "^2.2.6",
"next": "10.0.3", "next": "10.0.3",
"postcss": "^8.2.1", "postcss": "^8.2.1",
"prettier": "^2.2.1",
"react": "17.0.1", "react": "17.0.1",
"react-dom": "17.0.1", "react-dom": "17.0.1",
"tailwindcss": "^2.0.2" "tailwindcss": "^2.0.2"
},
"devDependencies": {
"prettier": "^2.2.1"
} }
} }
+31 -9
View File
@@ -1,6 +1,8 @@
import { useState } from 'react'; import { useCallback, useState } from 'react';
import App from '../components/App'; import App from '../components/App';
import Backdrop from '../components/Backdrop';
import Menu from '../components/Menu';
import Nav from '../components/Nav'; import Nav from '../components/Nav';
import Home from '../components/pages/Home'; import Home from '../components/pages/Home';
import Profile from '../components/pages/Profile'; import Profile from '../components/pages/Profile';
@@ -9,34 +11,54 @@ import Tab from '../components/Tab';
import TabBar from '../components/TabBar'; import TabBar from '../components/TabBar';
const pages = [ const pages = [
{ id: 'home', title: 'Home', icon: "home-outline", selectedIcon: "home", component: Home }, { id: 'home', title: 'Home', icon: 'home-outline', selectedIcon: 'home', component: Home },
{ id: 'profile', title: 'Profile', icon: "person-outline", selectedIcon: "person", component: Profile }, {
{ id: 'settings', title: 'Settings', icon: "cog-outline", selectedIcon: "cog", component: Settings }, id: 'profile',
] title: 'Profile',
icon: 'person-outline',
selectedIcon: 'person',
component: Profile,
},
{
id: 'settings',
title: 'Settings',
icon: 'cog-outline',
selectedIcon: 'cog',
component: Settings,
},
];
const CurrentPage = ({ page }) => { const CurrentPage = ({ page }) => {
return ( return (
<div className="flex-1 overflow-hidden relative"> <div className="flex-1 overflow-hidden relative">
{pages.map(p => { {pages.map(p => {
const Page = p.component; const Page = p.component;
return <Page selected={page.id === p.id} /> return <Page selected={page.id === p.id} />;
})} })}
</div> </div>
) );
} };
export default function Index() { export default function Index() {
const [page, setPage] = useState(pages[0]); const [page, setPage] = useState(pages[0]);
const [showMenu, setShowMenu] = useState(false);
const openMenu = useCallback(() => {
setShowMenu(true);
}, []);
return ( return (
<App> <App>
<Nav page={page} /> <Menu open={showMenu} onClose={() => setShowMenu(false)} />
<Nav page={page} onShowMenu={openMenu} />
<CurrentPage page={page} /> <CurrentPage page={page} />
<TabBar> <TabBar>
{pages.map(p => ( {pages.map(p => (
<Tab key={p.id} {...p} onClick={() => setPage(p)} selected={p.id === page.id} /> <Tab key={p.id} {...p} onClick={() => setPage(p)} selected={p.id === page.id} />
))} ))}
</TabBar> </TabBar>
<Backdrop open={showMenu} onClose={() => setShowMenu(false)} />
</App> </App>
); );
} }