on master help sign in
swipe to close menu on mobile
commite84ad81dbdf7f6218817ddb99d65ecbdc0834163 authorGavin Atkinson <gvnatknsn@protonmail.com> dateWed 14 Jul 2021, 12:36 (5 years ago) parentf2cc401
5 files changed+95−128
components/Header.js+2−52 components/MenuTray.js+77−20 components/Sidebar.js+10−56 package-lock.json+5 package.json+1
components/Header.js+2−52
@@ -23,7 +23,7 @@ function ActiveLink({ children, href, className, currentPath }) {
2323}
2424
2525export default function Header(props) {
26− const [isOpen, toggleTray] = useState(false);
26+ const [isOpen, setTray] = useState(false);
2727
2828 const currentPath = useRouter().asPath;
2929
@@ -91,7 +91,7 @@ export default function Header(props) {
9191 {
9292 // Small screen header
9393 }
94− <MenuTray isOpen={isOpen} toggleTray={toggleTray}>
94+ <MenuTray isOpen={isOpen} setTray={setTray}>
9595 <Link href="/">
9696 <a className="type-ui mb-12">Urbit</a>
9797 </Link>
@@ -124,56 +124,6 @@ export default function Header(props) {
124124 Grants
125125 </ActiveLink>
126126 </MenuTray>
127−
128− {
129− // Mobile menu button and search button
130− }
131− <div className="block md:hidden">
132− <button
133− onClick={(e) => {
134− e.stopPropagation();
135− props.search.toggleSearch(e);
136− }}
137− className={`z-10 fixed px-4 items-center justify-center type-ui rounded-xl h-16 bg-white text-gray left-4 right-4 bottom-4 mobile-search-button-width ${
138− isOpen ? "flex" : "hidden"
139− }`}
140− >
141− Search
142− </button>
143− <button
144− onClick={() => toggleTray(!isOpen)}
145− className="z-10 fixed bottom-4 right-4 w-16 h-16 bg-ultraDeepWall flex items-center justify-center rounded-full"
146− >
147− {isOpen ? (
148− <svg
149− width="16"
150− height="16"
151− viewBox="0 0 16 16"
152− fill="none"
153− xmlns="http://www.w3.org/2000/svg"
154− >
155− <path
156− fill-rule="evenodd"
157− clip-rule="evenodd"
158− d="M0.39382 13.7045C-0.131273 14.2296 -0.131274 15.081 0.39382 15.6061C0.918913 16.1312 1.77026 16.1312 2.29535 15.6061L7.99999 9.90142L13.7047 15.6061C14.2297 16.1312 15.0811 16.1312 15.6062 15.6061C16.1313 15.081 16.1313 14.2296 15.6062 13.7046L9.90152 7.99989L15.6061 2.29535C16.1312 1.77026 16.1312 0.918913 15.6061 0.39382C15.081 -0.131273 14.2296 -0.131273 13.7045 0.39382L7.99999 6.09836L2.29548 0.393844C1.77038 -0.131249 0.919038 -0.13125 0.393945 0.393844C-0.131148 0.918937 -0.131148 1.77028 0.393945 2.29537L6.09846 7.99989L0.39382 13.7045Z"
159− fill="white"
160− />
161− </svg>
162− ) : (
163− <svg
164− width="16"
165− height="16"
166− viewBox="0 0 16 17"
167− fill="none"
168− xmlns="http://www.w3.org/2000/svg"
169− >
170− <rect width="16" height="3" rx="1.5" fill="white" />
171− <rect y="7" width="16" height="3" rx="1.5" fill="white" />
172− <rect y="14" width="16" height="3" rx="1.5" fill="white" />
173− </svg>
174− )}
175− </button>
176− </div>
177127 </header>
178128 );
179129}
components/MenuTray.js+77−20
@@ -1,47 +1,104 @@
11import classnames from "classnames";
2+import { useSwipeable } from "react-swipeable";
23
3−export default function MenuTray(props) {
4+export default function MenuTray({ isOpen, setTray, search, children }) {
45 // Locks document scrolling when menu is open
5−
66 if (typeof document !== "undefined") {
7− if (props.isOpen) {
7+ if (isOpen) {
88 document.body.style.overflow = "hidden";
99 } else {
1010 document.body.style.overflow = "visible";
1111 }
1212 }
1313
14+ const handlers = useSwipeable({
15+ onSwipedLeft: (e) => setTray(false),
16+ });
17+
1418 // Slides the tray in or out from the left
1519 const trayClasses = classnames({
16− "tray-menu-open": props.isOpen,
17− "tray-menu-closed": !props.isOpen,
20+ "tray-menu-open": isOpen,
21+ "tray-menu-closed": !isOpen,
1822 });
1923
2024 // Fades the background overlay in or out
2125 const overlayClasses = classnames({
22− "tray-overlay-open": props.isOpen,
23− "tray-overlay-closed": !props.isOpen,
26+ "tray-overlay-open": isOpen,
27+ "tray-overlay-closed": !isOpen,
2428 });
2529
2630 // Hides or shows the menu
2731 const menuClasses = classnames({
28− "menu-open": props.isOpen,
29− "menu-closed": !props.isOpen,
32+ "menu-open": isOpen,
33+ "menu-closed": !isOpen,
3034 });
3135
3236 return (
33− <nav className={`z-10 w-screen h-screen top-0 left-0 fixed ${menuClasses}`}>
34− <div
35− onClick={() => props.toggleTray(!props.isOpen)}
36− className={`bg-washedWhite w-screen h-screen ${overlayClasses}`}
37− />
38− <div
39− className={`absolute bg-wall h-screen top-0 left-0 tray-menu-width overflow-y-scroll mb-24 ${trayClasses}`}
37+ <>
38+ <nav
39+ {...handlers}
40+ className={`z-10 w-screen h-screen top-0 left-0 fixed block md:hidden ${menuClasses}`}
4041 >
41− <div className="flex flex-col px-4 md:px-8 pt-8 md:pt-10 lg:pt-12">
42− {props.children}
42+ <div
43+ onClick={() => setTray(!isOpen)}
44+ className={`bg-washedWhite w-screen h-screen ${overlayClasses}`}
45+ />
46+ <div
47+ className={`absolute bg-wall h-screen top-0 left-0 tray-menu-width overflow-y-scroll mb-24 ${trayClasses}`}
48+ >
49+ <div
50+ {...handlers}
51+ className="flex flex-col px-4 md:px-8 pt-8 md:pt-10 lg:pt-12"
52+ >
53+ {children}
54+ </div>
4355 </div>
44− </div>
45− </nav>
56+
57+ <button
58+ onClick={(e) => {
59+ e.stopPropagation();
60+ search.toggleSearch(e);
61+ }}
62+ className={`z-10 fixed px-4 items-center justify-center type-ui rounded-xl h-16 bg-white text-gray left-4 right-4 bottom-4 mobile-search-button-width ${
63+ isOpen ? "flex" : "hidden"
64+ }`}
65+ >
66+ Search
67+ </button>
68+ </nav>
69+ <button
70+ onClick={() => setTray(!isOpen)}
71+ className="z-10 fixed bottom-4 right-4 w-16 h-16 bg-ultraDeepWall flex items-center justify-center rounded-full"
72+ >
73+ {isOpen ? (
74+ <svg
75+ width="16"
76+ height="16"
77+ viewBox="0 0 16 16"
78+ fill="none"
79+ xmlns="http://www.w3.org/2000/svg"
80+ >
81+ <path
82+ fillRule="evenodd"
83+ clipRule="evenodd"
84+ d="M0.39382 13.7045C-0.131273 14.2296 -0.131274 15.081 0.39382 15.6061C0.918913 16.1312 1.77026 16.1312 2.29535 15.6061L7.99999 9.90142L13.7047 15.6061C14.2297 16.1312 15.0811 16.1312 15.6062 15.6061C16.1313 15.081 16.1313 14.2296 15.6062 13.7046L9.90152 7.99989L15.6061 2.29535C16.1312 1.77026 16.1312 0.918913 15.6061 0.39382C15.081 -0.131273 14.2296 -0.131273 13.7045 0.39382L7.99999 6.09836L2.29548 0.393844C1.77038 -0.131249 0.919038 -0.13125 0.393945 0.393844C-0.131148 0.918937 -0.131148 1.77028 0.393945 2.29537L6.09846 7.99989L0.39382 13.7045Z"
85+ fill="white"
86+ />
87+ </svg>
88+ ) : (
89+ <svg
90+ width="16"
91+ height="16"
92+ viewBox="0 0 16 17"
93+ fill="none"
94+ xmlns="http://www.w3.org/2000/svg"
95+ >
96+ <rect width="16" height="3" rx="1.5" fill="white" />
97+ <rect y="7" width="16" height="3" rx="1.5" fill="white" />
98+ <rect y="14" width="16" height="3" rx="1.5" fill="white" />
99+ </svg>
100+ )}
101+ </button>
102+ </>
46103 );
47104}
components/Sidebar.js+10−56
@@ -3,7 +3,7 @@ import { useState } from "react";
33import MenuTray from "./MenuTray";
44
55export default function Sidebar(props) {
6− const [isOpen, toggleTray] = useState(false);
6+ const [isOpen, setTray] = useState(false);
77 return (
88 <>
99 <div className="hidden md:flex flex-col w-96 bg-wall max-h-screen h-screen">
@@ -18,61 +18,15 @@ export default function Sidebar(props) {
1818 </div>
1919 </div>
2020
21− <div className="block md:hidden">
22− <MenuTray isOpen={isOpen} toggleTray={toggleTray}>
23− <header className="flex flex-shrink-0 justify-between items-center pb-8">
24− <Link href="/">
25− <a className="type-ui text-gray">Urbit</a>
26− </Link>
27− </header>
28− {props.children}
29− <div className="pt-64" />
30− </MenuTray>
31− <button
32− onClick={(e) => {
33− e.stopPropagation();
34− props.search.toggleSearch(e);
35− }}
36− className={`z-10 fixed px-4 items-center justify-center type-ui rounded-xl h-16 bg-white text-gray left-4 right-4 bottom-4 mobile-search-button-width ${
37− isOpen ? "flex" : "hidden"
38− }`}
39− >
40− Search
41− </button>
42− <button
43− onClick={() => toggleTray(!isOpen)}
44− className="z-10 fixed bottom-4 right-4 w-16 h-16 bg-ultraDeepWall flex items-center justify-center rounded-full"
45− >
46− {isOpen ? (
47− <svg
48− width="16"
49− height="16"
50− viewBox="0 0 16 16"
51− fill="none"
52− xmlns="http://www.w3.org/2000/svg"
53− >
54− <path
55− fill-rule="evenodd"
56− clip-rule="evenodd"
57− d="M0.39382 13.7045C-0.131273 14.2296 -0.131274 15.081 0.39382 15.6061C0.918913 16.1312 1.77026 16.1312 2.29535 15.6061L7.99999 9.90142L13.7047 15.6061C14.2297 16.1312 15.0811 16.1312 15.6062 15.6061C16.1313 15.081 16.1313 14.2296 15.6062 13.7046L9.90152 7.99989L15.6061 2.29535C16.1312 1.77026 16.1312 0.918913 15.6061 0.39382C15.081 -0.131273 14.2296 -0.131273 13.7045 0.39382L7.99999 6.09836L2.29548 0.393844C1.77038 -0.131249 0.919038 -0.13125 0.393945 0.393844C-0.131148 0.918937 -0.131148 1.77028 0.393945 2.29537L6.09846 7.99989L0.39382 13.7045Z"
58− fill="white"
59− />
60− </svg>
61− ) : (
62− <svg
63− width="16"
64− height="16"
65− viewBox="0 0 16 17"
66− fill="none"
67− xmlns="http://www.w3.org/2000/svg"
68− >
69− <rect width="16" height="3" rx="1.5" fill="white" />
70− <rect y="7" width="16" height="3" rx="1.5" fill="white" />
71− <rect y="14" width="16" height="3" rx="1.5" fill="white" />
72− </svg>
73− )}
74− </button>
75− </div>
21+ <MenuTray isOpen={isOpen} setTray={setTray}>
22+ <header className="flex flex-shrink-0 justify-between items-center pb-8">
23+ <Link href="/">
24+ <a className="type-ui text-gray">Urbit</a>
25+ </Link>
26+ </header>
27+ {props.children}
28+ <div className="pt-64" />
29+ </MenuTray>
7630 </>
7731 );
7832}
package-lock.json+5
@@ -5694,6 +5694,11 @@
56945694 "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
56955695 "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg=="
56965696 },
5697+ "react-swipeable": {
5698+ "version": "6.1.2",
5699+ "resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-6.1.2.tgz",
5700+ "integrity": "sha512-vfZtOZNivwd/aI+ZZH1Grx0eQBdbV1UI3pB9p65jbW5guHHdSIPpKsND6XmaiZXP5REOOc9Ckfr36ChswPqwsA=="
5701+ },
56975702 "readable-stream": {
56985703 "version": "2.3.7",
56995704 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
package.json+1
@@ -26,6 +26,7 @@
2626 "react": "17.0.2",
2727 "react-dom": "17.0.2",
2828 "react-hotkeys": "^2.0.0",
29+ "react-swipeable": "^6.1.2",
2930 "remark": "^13.0.0",
3031 "remark-gfm": "^1.0.0",
3132 "remark-heading-id": "^1.0.0",