diff options
author | 2021-07-29 13:31:41 -0700 | |
---|---|---|
committer | 2021-07-29 13:31:41 -0700 | |
commit | 6eeafac715aaa077f07dd12d0609301a807a0705 (patch) | |
tree | 0e163a45864794fbe2e926a0a85a189bb500f837 /docs | |
parent | 908139642a7863ce38e567f791aee1972ab6ec1f (diff) | |
download | astro-6eeafac715aaa077f07dd12d0609301a807a0705.tar.gz astro-6eeafac715aaa077f07dd12d0609301a807a0705.tar.zst astro-6eeafac715aaa077f07dd12d0609301a807a0705.zip |
Add algolia-powered search bar to docs site (#917)
* add search bar
* replace cmd+k with slash hotkey
* update api key
* add localhost support for search
Diffstat (limited to 'docs')
-rw-r--r-- | docs/astro.config.mjs | 5 | ||||
-rw-r--r-- | docs/package.json | 3 | ||||
-rw-r--r-- | docs/public/index.css | 17 | ||||
-rw-r--r-- | docs/public/nav.js | 37 | ||||
-rw-r--r-- | docs/public/theme.css | 5 | ||||
-rw-r--r-- | docs/src/components/Search.css | 93 | ||||
-rw-r--r-- | docs/src/components/Search.tsx | 97 | ||||
-rw-r--r-- | docs/src/layouts/Main.astro | 38 |
8 files changed, 217 insertions, 78 deletions
diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 0364de9e6..7ca85bf1b 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -2,5 +2,8 @@ export default { buildOptions: { site: 'https://docs.astro.build/', }, - renderers: ['@astrojs/renderer-preact'], + renderers: [ + '@astrojs/renderer-preact', + '@astrojs/renderer-react', + ], }; diff --git a/docs/package.json b/docs/package.json index 8d342df32..a1d587953 100644 --- a/docs/package.json +++ b/docs/package.json @@ -21,5 +21,8 @@ "pa11y-ci": "^2.4.2", "prettier": "^2.3.2", "start-server-and-test": "^1.12.6" + }, + "dependencies": { + "@docsearch/react": "^1.0.0-alpha.27" } } diff --git a/docs/public/index.css b/docs/public/index.css index ee0673702..5f382e7d0 100644 --- a/docs/public/index.css +++ b/docs/public/index.css @@ -282,21 +282,6 @@ img { align-items: center; } -header button { - background-color: var(--theme-bg); -} - -header button:hover, -header button:focus { - outline: var(--theme-text) solid 1px; -} - -header button:active, -header button[aria-pressed='true'] { - background: var(--theme-text); - color: var(--theme-bg); -} - button { display: flex; align-items: center; @@ -452,7 +437,7 @@ h2.heading { font-size: larger; top: 0.5rem; left: 0.5rem; - z-index: 999; + z-index: 9; display: block; background-color: var(--theme-bg); color: var(--theme-text-accent); diff --git a/docs/public/nav.js b/docs/public/nav.js deleted file mode 100644 index d6c2bcda3..000000000 --- a/docs/public/nav.js +++ /dev/null @@ -1,37 +0,0 @@ -const nav = document.querySelector('body > header'); - -if (!window.matchMedia('(prefers-reduced-motion)').matches) { - window.addEventListener('scroll', onScroll, { passive: true }); -} - -let prev = -1; -let prevDir = 0; -let threshold = 32; - -function onScroll() { - const curr = window.scrollY; - const dir = curr > prev ? 1 : -1; - - if (curr < threshold) { - show(); - document.documentElement.classList.add('initial'); - } else if (dir !== prevDir) { - if (dir === 1) { - hide(); - } else { - show(); - } - } - - prev = curr; -} - -const hide = () => { - nav.classList.add('hidden'); - document.documentElement.classList.add('scrolled'); - document.documentElement.classList.remove('initial'); -}; -const show = () => { - nav.classList.remove('hidden'); - document.documentElement.classList.remove('scrolled'); -}; diff --git a/docs/public/theme.css b/docs/public/theme.css index c43a9e303..1eec0a709 100644 --- a/docs/public/theme.css +++ b/docs/public/theme.css @@ -77,7 +77,6 @@ --theme-code-text: hsla(var(--color-gray-95), 1); --theme-navbar-bg: hsla(var(--color-base-white), 100%, 1); --theme-navbar-height: 6rem; - --theme-sidebar-offset: var(--theme-navbar-height); --theme-selection-color: hsla(var(--color-orange), 1); --theme-selection-bg: hsla(var(--color-orange), var(--theme-accent-opacity)); } @@ -87,10 +86,6 @@ body { color: var(--theme-text); } -:root.scrolled { - --theme-sidebar-offset: 0; -} - :root.theme-dark { color-scheme: dark; --theme-accent-opacity: 0.4; diff --git a/docs/src/components/Search.css b/docs/src/components/Search.css new file mode 100644 index 000000000..53ca9bfd0 --- /dev/null +++ b/docs/src/components/Search.css @@ -0,0 +1,93 @@ +:root { + --docsearch-primary-color: var(--theme-accent); + --docsearch-logo-color: var(--theme-text); +} + +.search { + display: none; + position: relative; + z-index: 10; + flex-grow: 1; + grid-area: search; + padding-left: 0.75rem; + padding-right: 0.7rem; + display: flex; + width: 400px; + max-width: 400px; +} +.search > * { + flex-grow: 1; +} + +.search > :global(.algolia-autocomplete) { + width: 100%; +} + +:global(body.is-nav-open) .search { + display: flex; +} + +.search-input { + flex-grow: 1; + box-sizing: border-box; + width: 100%; + margin: 0; + padding: 0.33em 0.5em; + overflow: visible; + font-weight: 500; + font-size: 100%; + font-family: inherit; + line-height: inherit; + background-color: var(--theme-divider); + border-color: var(--theme-divider); + color: var(--theme-text-light); + border-style: solid; + border-width: 1px; + border-radius: 0.25rem; + outline: 0; + cursor: pointer; + transition-timing-function: ease-out; + transition-duration: 0.2s; + transition-property: border-color, background-color; + -webkit-font-smoothing: antialiased; +} +.no-underline { + text-decoration: none; +} +.search-input:hover { + color: var(--theme-text); +} +.search-input:hover::placeholder { + color: var(--theme-text-light); +} +.search-input::placeholder { + color: var(--theme-text-light); +} + +.search-hint { + position: absolute; + top: 7px; + right: 19px; + padding: 3px 5px; + display: none; + display: none; + align-items: center; + justify-content: center; + letter-spacing: 0.125em; + color: var(--theme-text-light); + font-size: 13px; + font-family: var(--font-mono); + pointer-events: none; + border-color: var(--theme-text-lighter); + color: var(--theme-text-light); + border-style: solid; + border-width: 1px; + border-radius: 0.25rem; + line-height: 14px; +} + +@media (min-width: 50em) { + .search-hint { + display: flex; + } +}
\ No newline at end of file diff --git a/docs/src/components/Search.tsx b/docs/src/components/Search.tsx new file mode 100644 index 000000000..066699fc1 --- /dev/null +++ b/docs/src/components/Search.tsx @@ -0,0 +1,97 @@ +/* jsxImportSource: react */ +import { useState, useCallback, useRef } from 'react' +import { createPortal } from 'react-dom' +import { DocSearchModal, useDocSearchKeyboardEvents } from '@docsearch/react' +import '@docsearch/css//dist/style.css'; +import './Search.css'; + + +export function Search() { + const [isOpen, setIsOpen] = useState(false) + const searchButtonRef = useRef() + const [initialQuery, setInitialQuery] = useState(null) + + const onOpen = useCallback(() => { + setIsOpen(true) + }, [setIsOpen]) + + const onClose = useCallback(() => { + setIsOpen(false) + }, [setIsOpen]) + + const onInput = useCallback( + (e) => { + setIsOpen(true) + setInitialQuery(e.key) + }, + [setIsOpen, setInitialQuery] + ) + + useDocSearchKeyboardEvents({ + isOpen, + onOpen, + onClose, + onInput, + searchButtonRef, + }) + + return ( + <> + <button + type="button" + ref={searchButtonRef} + onClick={onOpen} + className="search-input" + > + <svg + width="24" + height="24" + fill="none" + > + <path + d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" + stroke="currentColor" + strokeWidth="2" + strokeLinecap="round" + strokeLinejoin="round" + /> + </svg> + <span> + Search + </span> + <span + className="search-hint" + > + <span className="sr-only">Press </span> + <kbd>/</kbd> + <span className="sr-only"> to search</span> + </span> + </button> + {isOpen && + createPortal( + <DocSearchModal + initialQuery={initialQuery} + initialScrollY={window.scrollY} + onClose={onClose} + indexName="astro" + apiKey="0f387260ad74f9cbf4353facd29c919c" + transformItems={(items) => { + return items.map((item) => { + // We transform the absolute URL into a relative URL to + // work better on localhost, preview URLS. + const a = document.createElement('a') + a.href = item.url + console.log(a.hash); + const hash = a.hash === '#overview' ? '' : a.hash + return { + ...item, + url: `${a.pathname}${hash}`, + } + }) + }} + />, + document.body + )} + </> + ) +}
\ No newline at end of file diff --git a/docs/src/layouts/Main.astro b/docs/src/layouts/Main.astro index c3b08b242..52b0f84a0 100644 --- a/docs/src/layouts/Main.astro +++ b/docs/src/layouts/Main.astro @@ -4,6 +4,7 @@ import SiteSidebar from '../components/SiteSidebar.astro'; import DocSidebar, { TableOfContents, More } from '../components/DocSidebar/DocSidebar.tsx'; import MenuToggle from '../components/MenuToggle.tsx'; import MetaData from "../components/MetaData.astro"; +import {Search} from "../components/Search.jsx"; import { site } from "../config.ts"; const { content = {}, centered = false } = Astro.props; @@ -64,14 +65,13 @@ if (currentPage) { } header { - z-index: 10; + z-index: 11; height: var(--theme-navbar-height); width: 100%; background-color: var(--theme-navbar-bg); display: flex; align-items: center; justify-content: center; - z-index: 1001; overflow: hidden; position: sticky; top: 0; @@ -80,14 +80,16 @@ if (currentPage) { .logo { display: flex; - align-items: center; - gap: 0; + overflow: hidden; + width: 30px; font-size: 1rem; + flex-shrink: 0; font-weight: 600; - margin: 0; line-height: 1; color: hsla(var(--color-base-white), 100%, 1); text-decoration: none; + gap: 0.5em; + z-index: -1; } .logo a { @@ -127,24 +129,17 @@ if (currentPage) { overflow-x: hidden; } - .logo { - display: flex; - align-items: center; - justify-content: center; - gap: 0.5em; - z-index: -1; - margin: 0 auto; - } - .nav-wrapper { display: flex; align-items: center; - justify-content: space-between; + justify-content: flex-end; + gap: 1em; width: 100%; max-width: 82em; padding: 0 1rem; } + .layout :global(> *) { width: 100%; height: 100%; @@ -160,7 +155,7 @@ if (currentPage) { #sidebar-site { position: fixed; background-color: var(--theme-bg); - z-index: 1000; + z-index: 10; } #article { @@ -263,6 +258,9 @@ if (currentPage) { .sm\:hidden { display: none; } + .logo { + width: auto; + } } @media (min-width: 72em) { @@ -298,7 +296,6 @@ if (currentPage) { <div class="menu-toggle"> <MenuToggle client:idle/> </div> - <div class="logo flex"> <a href="https://astro.build/"> <h1 class="sr-only">Astro</h1> @@ -325,6 +322,10 @@ if (currentPage) { </svg> </a> </div> + <div style="flex-grow: 1;"></div> + <div class="search"> + <Search client:idle /> + </div> </nav> </header> @@ -352,9 +353,8 @@ if (currentPage) { </aside> </main> - <script type="module" src="/nav.js" /> + <!-- Scrollable a11y code helper --> <script type="module" src="/make-scrollable-code-focusable.js" /> - <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-TEL60V1WM9"></script> <script> |