on master help sign in
various: refactor search into _app
commit83cdd8622e16ffde1d09cad7ba8d23d67c21fe72 authorMatilde Park <matilde@tlon.io> dateMon 28 Jun 2021, 16:57 (5 years ago) parentaa9f8ab
12 files changed+147−162
components/Container.js+4−14 components/Search.js+93−90 pages/404.js+1−5 pages/_app.js+22−4 pages/blog.js+2−6 pages/blog/[slug].js+2−6 pages/docs/[[...slug]].js+7−12 pages/events.js+2−6 pages/events/[slug].js+2−6 pages/faq.js+2−2 pages/grants.js+8−6 pages/index.js+2−5
components/Container.js+4−14
@@ -1,18 +1,8 @@
1−import { configure, GlobalHotKeys } from "react-hotkeys";
21// Ensures the root container is always 100vw, min 100vh, and centers all children along the y-axis
3−export default function Container({ toggleSearch, children }) {
4− const keyMap = { search: ["command+k", "ctrl+k", "esc"] };
5− const handlers = { search: toggleSearch };
6− configure({
7− ignoreTags: [],
8− });
9−
2+export default function Container({ children }) {
103 return (
11− <>
12− <GlobalHotKeys keyMap={keyMap} handlers={handlers} />
13− <div className="flex flex-col min-h-screen w-screen items-center">
14− {children}
15− </div>
16− </>
4+ <div className="flex flex-col min-h-screen w-screen items-center">
5+ {children}
6+ </div>
177 );
188}
components/Search.js+93−90
@@ -53,101 +53,104 @@ export default function Search(props) {
5353 }, []);
5454
5555 return (
56− <div className="fixed w-screen h-screen bg-black bg-opacity-30 z-50 flex flex-col">
57− <div className="p-12 w-100 flex flex-col min-h-0">
58− <div className="relative flex flex-col" ref={searchRef}>
59− <input
60− className="bg-white type-ui text-green rounded-xl border-transparent p-2 outline-none relative"
61− onChange={onChange}
62− onFocus={onFocus}
63− placeholder="Search..."
64− type="text"
65− value={query}
66− autoFocus={true}
67− />
68− {query.length > 0 && (
69− <span
70− onClick={clear}
71− className="absolute right-3"
72− style={{ top: 13 }}
73− >
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"
56+ <>
57+ <div className="fixed w-screen h-screen bg-black bg-opacity-30 z-50 flex flex-col">
58+ <div className="p-12 w-100 flex flex-col min-h-0">
59+ <div className="relative flex flex-col" ref={searchRef}>
60+ <input
61+ className="bg-white type-ui text-green rounded-xl border-transparent p-2 outline-none relative"
62+ onChange={onChange}
63+ onFocus={onFocus}
64+ placeholder="Search..."
65+ type="text"
66+ value={query}
67+ autoFocus={true}
68+ />
69+ {query.length > 0 && (
70+ <span
71+ onClick={clear}
72+ className="absolute right-3"
73+ style={{ top: 13 }}
8074 >
81− <path
82− fill-rule="evenodd"
83− clip-rule="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.1311 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.131249 0.393945 0.393844C-0.131148 0.918937 -0.131148 1.77028 0.393945 2.29537L6.09846 7.99989L0.39382 13.7045Z"
85− fill="black"
86− fill-opacity="0.6"
87− />
88− </svg>
89− </span>
90− )}
91− </div>
92− <div
93− className={
94− "bg-white overflow-scroll min-h-0 rounded-xl border-transparent mt-2 " +
95− (query.length > 0 ? "" : "hidden")
96− }
97− >
98− {active && glossaryResults.length > 0 && (
99− <ul>
100− {glossaryResults.map(({ name, link, desc, symbol }) => {
101− return (
102− <div className="border-b border-gray">
103− <p className="font-semibold text-sm pb-4 text-gray pl-3 pt-2">
104− Glossary Result
105− </p>
106− <li key={link} className="cursor-pointer hover:bg-wall">
107− <Link href={link} as={link}>
108− <div className="font-semibold px-3">
109− {symbol.length > 0 && (
110− <code className="mr-1">{symbol}</code>
111− )}
112− {name}
113− <p className="font-normal text-base pt-1 pb-4">
114− {desc}
115− </p>
116− </div>
117− </Link>
118− </li>
119− </div>
120− );
121− })}
122− </ul>
123− )}
124− {active && results.length > 0 && (
125− <ul className="p-2">
126− <div>
127− <p className="font-semibold text-sm pb-4 text-gray">
128− {results.length} results for "{query}"
129− </p>
130− </div>
131− {results
132− .filter((e) => e.parent !== "Glossary")
133− .map(({ title, slug, content, parent }) => {
75+ <svg
76+ width="16"
77+ height="16"
78+ viewBox="0 0 16 16"
79+ fill="none"
80+ xmlns="http://www.w3.org/2000/svg"
81+ >
82+ <path
83+ fill-rule="evenodd"
84+ clip-rule="evenodd"
85+ 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.1311 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.131249 0.393945 0.393844C-0.131148 0.918937 -0.131148 1.77028 0.393945 2.29537L6.09846 7.99989L0.39382 13.7045Z"
86+ fill="black"
87+ fill-opacity="0.6"
88+ />
89+ </svg>
90+ </span>
91+ )}
92+ </div>
93+ <div
94+ className={
95+ "bg-white overflow-scroll min-h-0 rounded-xl border-transparent mt-2 " +
96+ (query.length > 0 ? "" : "hidden")
97+ }
98+ >
99+ {active && glossaryResults.length > 0 && (
100+ <ul>
101+ {glossaryResults.map(({ name, link, desc, symbol }) => {
134102 return (
135− <li key={slug} className="cursor-pointer hover:bg-wall">
136− <Link href={slug} as={slug}>
137− <div>
138− <p className="font-medium text-base">
139− {parent} / {title}
140− </p>
141− <p className="text-base font-regular">{content}</p>
142− </div>
143− </Link>
144− </li>
103+ <div className="border-b border-gray">
104+ <p className="font-semibold text-sm pb-4 text-gray pl-3 pt-2">
105+ Glossary Result
106+ </p>
107+ <li key={link} className="cursor-pointer hover:bg-wall">
108+ <Link href={link} as={link}>
109+ <div className="font-semibold px-3">
110+ {symbol.length > 0 && (
111+ <code className="mr-1">{symbol}</code>
112+ )}
113+ {name}
114+ <p className="font-normal text-base pt-1 pb-4">
115+ {desc}
116+ </p>
117+ </div>
118+ </Link>
119+ </li>
120+ </div>
145121 );
146122 })}
147− </ul>
148− )}
123+ </ul>
124+ )}
125+ {active && results.length > 0 && (
126+ <ul className="p-2">
127+ <div>
128+ <p className="font-semibold text-sm pb-4 text-gray">
129+ {results.length} results for "{query}"
130+ </p>
131+ </div>
132+ {results
133+ .filter((e) => e.parent !== "Glossary")
134+ .map(({ title, slug, content, parent }) => {
135+ return (
136+ <li key={slug} className="cursor-pointer hover:bg-wall">
137+ <Link href={slug} as={slug}>
138+ <div>
139+ <p className="font-medium text-base">
140+ {parent} / {title}
141+ </p>
142+ <p className="text-base font-regular">{content}</p>
143+ </div>
144+ </Link>
145+ </li>
146+ );
147+ })}
148+ </ul>
149+ )}
150+ </div>
149151 </div>
150152 </div>
151− </div>
153+ {props.children}
154+ </>
152155 );
153156}
pages/404.js+1−5
@@ -1,15 +1,11 @@
1−import { useState } from "react";
21import Container from "../components/Container";
32import SingleColumn from "../components/SingleColumn";
43import Header from "../components/Header";
54import Footer from "../components/Footer";
6−import Search from "../components/Search";
75
86export default function NotFound() {
9− const [showSearch, toggleSearch] = useState(false);
107 return (
11− <Container toggleSearch={() => toggleSearch((state) => !state)}>
12− {showSearch && <Search toggleSearch={() => toggleSearch(false)} />}
8+ <Container>
139 <SingleColumn>
1410 <Header toggleSearch={() => toggleSearch(true)} />
1511 <section className="layout-wide pt-48">
pages/_app.js+22−4
@@ -1,8 +1,26 @@
1−import 'tailwindcss/tailwind.css'
2−import '../styles/globals.css'
1+import "tailwindcss/tailwind.css";
2+import { useState } from "react";
3+import { configure, GlobalHotKeys } from "react-hotkeys";
4+import Search from "../components/Search";
5+import "../styles/globals.css";
36
47function MyApp({ Component, pageProps }) {
5− return <Component {...pageProps} />
8+ const [showSearch, toggleSearch] = useState(false);
9+
10+ const invertToggle = () => toggleSearch((state) => !state);
11+ const keyMap = { search: ["command+k", "ctrl+k", "esc"] };
12+ const handlers = { search: invertToggle };
13+ configure({
14+ ignoreTags: [],
15+ });
16+
17+ return (
18+ <>
19+ <GlobalHotKeys keyMap={keyMap} handlers={handlers} />
20+ {showSearch && <Search toggleSearch={() => toggleSearch(false)} />}
21+ <Component {...pageProps} toggleSearch={invertToggle} />
22+ </>
23+ );
624}
725
8−export default MyApp
26+export default MyApp;
pages/blog.js+2−6
@@ -1,19 +1,15 @@
11import Head from "next/head";
22import Link from "next/link";
3−import { useState } from "react";
43import Container from "../components/Container";
5−import Search from "../components/Search";
64import Footer from "../components/Footer";
75import Header from "../components/Header";
86import SingleColumn from "../components/SingleColumn";
97import BackgroundImage from "../components/BackgroundImage";
108import { getAllPosts, formatDate } from "../lib/lib";
119
12−export default function Blog({ posts }) {
13− const [showSearch, toggleSearch] = useState(false);
10+export default function Blog({ posts, toggleSearch }) {
1411 return (
15− <Container toggleSearch={() => toggleSearch((state) => !state)}>
16− {showSearch && <Search toggleSearch={() => toggleSearch(false)} />}
12+ <Container>
1713 <SingleColumn>
1814 <Header toggleSearch={() => toggleSearch(true)} />
1915 <section className="layout-wide">
pages/blog/[slug].js+2−6
@@ -1,5 +1,4 @@
11import { useRouter } from "next/router";
2−import { useState } from "react";
32import {
43 getPostBySlug,
54 getAllPosts,
@@ -14,22 +13,19 @@ import Container from "../../components/Container";
1413import Markdown from "../../components/Markdown";
1514import Header from "../../components/Header";
1615import Footer from "../../components/Footer";
17−import Search from "../../components/Search";
1816import BackgroundImage from "../../components/BackgroundImage";
1917import SingleColumn from "../../components/SingleColumn";
2018import NewsletterSignup from "../../components/NewletterSignup";
2119import PostPreview from "../../components/PostPreview";
2220import { name, contact } from "../../lib/constants";
2321
24−export default function Post({ post, nextPost, previousPost }) {
22+export default function Post({ post, nextPost, previousPost, toggleSearch }) {
2523 const router = useRouter();
2624 if (!router.isFallback && !post?.slug) {
2725 return <ErrorPage />;
2826 }
29− const [showSearch, toggleSearch] = useState(false);
3027 return (
31− <Container toggleSearch={() => toggleSearch((state) => !state)}>
32− {showSearch && <Search toggleSearch={() => toggleSearch(!showSearch)} />}
28+ <Container>
3329 <SingleColumn>
3430 <Header toggleSearch={() => toggleSearch(true)} />
3531 <section className="flex flex-col layout-wide">
pages/docs/[[...slug]].js+7−12
@@ -8,8 +8,6 @@ import { getDocs, formatDate, buildPageTree, getPage } from "../../lib/lib";
88import Markdown from "../../components/Markdown";
99import ContentArea from "../../components/ContentArea";
1010import Sidebar from "../../components/Sidebar";
11−import Search from "../../components/Search";
12−import { configure, GlobalHotKeys } from "react-hotkeys";
1311
1412const breadcrumbs = (posts, paths) => {
1513 const results = [
@@ -96,21 +94,18 @@ const pageTree = (thisLink, tree, level = 0) => {
9694 );
9795};
9896
99−export default function DocsLayout({ posts, data, content, params }) {
100− const [showSearch, toggleSearch] = useState(false);
101− const toggle = () => toggleSearch((state) => !state);
102− const keyMap = { search: ["command+k", "ctrl+k", "esc"] };
103− const handlers = { search: toggle };
104− configure({
105− ignoreTags: [],
106− });
97+export default function DocsLayout({
98+ posts,
99+ data,
100+ content,
101+ params,
102+ toggleSearch,
103+}) {
107104 return (
108105 <>
109106 <Head>
110107 <title>{data.title} / Documentation / Urbit.org</title>
111108 </Head>
112− <GlobalHotKeys keyMap={keyMap} handlers={handlers} />
113− {showSearch && <Search toggleSearch={() => toggleSearch(!showSearch)} />}
114109 <div className="flex w-screen h-screen min-h-screen w-screen overflow-hidden">
115110 <Sidebar>{childPages("/docs", posts.children)}</Sidebar>
116111 <ContentArea
pages/events.js+2−6
@@ -69,13 +69,9 @@ function EventCard(props) {
6969 );
7070}
7171
72−export default function Events({ pastEvents, currentEvents }) {
73− const [showSearch, toggleSearch] = useState(false);
72+export default function Events({ pastEvents, currentEvents, toggleSearch }) {
7473 return (
75− <Container toggleSearch={() => toggleSearch((state) => !state)}>
76− {showSearch && (
77− <Search toggleSearch={() => toggleSearch(!toggleSearch)} />
78− )}
74+ <Container>
7975 <SingleColumn>
8076 <Header toggleSearch={() => toggleSearch(true)} />
8177 <section className="layout-wide">
pages/events/[slug].js+2−6
@@ -1,5 +1,4 @@
11import { useRouter } from "next/router";
2−import { useState } from "react";
32import {
43 getPostBySlug,
54 getAllPosts,
@@ -14,22 +13,19 @@ import Container from "../../components/Container";
1413import Markdown from "../../components/Markdown";
1514import Header from "../../components/Header";
1615import Footer from "../../components/Footer";
17−import Search from "../../components/Search";
1816import BackgroundImage from "../../components/BackgroundImage";
1917import SingleColumn from "../../components/SingleColumn";
2018import NewsletterSignup from "../../components/NewletterSignup";
2119import PostPreview from "../../components/PostPreview";
2220import { name, contact } from "../../lib/constants";
2321
24−export default function Event({ post, nextPost, previousPost }) {
22+export default function Event({ post, nextPost, previousPost, toggleSearch }) {
2523 const router = useRouter();
2624 if (!router.isFallback && !post?.slug) {
2725 return <ErrorPage />;
2826 }
29− const [showSearch, toggleSearch] = useState(false);
3027 return (
31− <Container toggleSearch={() => toggleSearch((state) => !state)}>
32− {showSearch && <Search toggleSearch={() => toggleSearch(false)} />}
28+ <Container>
3329 <SingleColumn>
3430 <Header toggleSearch={() => toggleSearch(true)} />
3531 <section className="flex flex-col layout-wide pt-24">
pages/faq.js+2−2
@@ -8,11 +8,11 @@ import SingleColumn from "../components/SingleColumn";
88import BackgroundImage from "../components/BackgroundImage";
99import { getAllPosts, formatDate } from "../lib/lib";
1010
11−export default function Blog({ posts }) {
11+export default function Blog({ posts, toggleSearch }) {
1212 return (
1313 <Container>
1414 <SingleColumn>
15− <Header />
15+ <Header toggleSearch={() => toggleSearch(true)} />
1616 <section className="layout-wide">
1717 <div className="measure">
1818 <h2 className="pb-16">Urbit Blog</h2>
pages/grants.js+8−6
@@ -59,12 +59,17 @@ function toggleAll(currentArray, fullSet) {
5959 }
6060}
6161
62−export default function Grants({ posts, categories, types, featuredGrants }) {
62+export default function Grants({
63+ posts,
64+ categories,
65+ types,
66+ featuredGrants,
67+ toggleSearch,
68+}) {
6369 const [activeTags, setTags] = useState([]);
6470 const [activeTypes, setTypes] = useState(types);
6571 const [includeCompleted, setIncludeCompleted] = useState(false);
6672 const [tab, setTab] = useState(0);
67− const [showSearch, toggleSearch] = useState(false);
6873
6974 const filteredPosts = posts.filter((post) => {
7075 // Posts are returned if they match both the selected category and selected tags, or if the user has no category filters set.
@@ -85,11 +90,8 @@ export default function Grants({ posts, categories, types, featuredGrants }) {
8590 });
8691
8792 return (
88− <Container toggleSearch={() => toggleSearch((state) => !state)}>
93+ <Container>
8994 <SingleColumn>
90− {showSearch && (
91− <Search toggleSearch={() => toggleSearch(!toggleSearch)} />
92− )}
9395 <Header toggleSearch={() => toggleSearch(true)} />
9496 {
9597 // Heading and introduction
pages/index.js+2−5
@@ -5,7 +5,6 @@ import Container from "../components/Container";
55import SingleColumn from "../components/SingleColumn";
66import Header from "../components/Header";
77import Footer from "../components/Footer";
8−import Search from "../components/Search";
98import BackgroundImage from "../components/BackgroundImage";
109import TabCarousel from "../components/TabCarousel";
1110import NewsletterSignup from "../components/NewletterSignup";
@@ -13,13 +12,11 @@ import PostPreview from "../components/PostPreview";
1312import { getAllPosts, formatDate, getOpenGrantsCount } from "../lib/lib";
1413import { contact } from "../lib/constants";
1514
16−export default function Home({ posts, events, openGrantsCount }) {
15+export default function Home({ posts, events, openGrantsCount, toggleSearch }) {
1716 const [tab, setTab] = useState(0);
18− const [showSearch, toggleSearch] = useState(false);
1917 return (
20− <Container toggleSearch={() => toggleSearch((state) => !state)}>
18+ <Container>
2119 <SingleColumn>
22− {showSearch && <Search toggleSearch={() => toggleSearch(false)} />}
2320 <Header toggleSearch={() => toggleSearch(true)} />
2421
2522 {