Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style DocSearch #1714

Merged
merged 6 commits into from
May 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ coverage
.envrc
.publish-log.txt
.yarn-error.log

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"scripts": {
"build": "preconstruct build",
"build:docs": "yarn build && yarn workspace docs build",
"dev:docs": "yarn workspace docs start",
"clean": "lerna run clean && rimraf packages/*/{dist,rts2_cache*}",
"format": "prettier --write \"**/*.{ts,js,json}\" \"**/*.md\" \"**/*.mdx\"",
"test": "jest",
Expand Down
4 changes: 3 additions & 1 deletion packages/docs/gatsby-browser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// @ts-check

import * as React from 'react'

import { WrapPageElement } from './src'
import { WrapPageElement, setDocSearchComponents } from './src'

export const wrapPageElement = (props) => <WrapPageElement {...props} />
3 changes: 3 additions & 0 deletions packages/docs/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ module.exports = {
},
},
],
flags: {
DEV_SSR: true,
},
}
8 changes: 7 additions & 1 deletion packages/docs/gatsby-ssr.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// @ts-check

import * as React from 'react'

import { WrapPageElement } from './src'
import { WrapPageElement, setDocSearchComponents } from './src'

export const wrapPageElement = (props) => <WrapPageElement {...props} />

export const onRenderBody = (args) => {
setDocSearchComponents(args)
}
29 changes: 16 additions & 13 deletions packages/docs/src/components/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Head from './head'
import MenuButton from './menu-button'
import NavLink from './nav-link'
import Button from './button'
import SearchInput from './search-input'
import Sidebar from '../sidebar.mdx'

const modes = ['default', 'dark', 'deep', 'swiss']
Expand Down Expand Up @@ -57,7 +58,6 @@ export default function DocsLayout(props) {
const next = modes[(i + 1) % modes.length]
setMode(next)
}

return (
<Themed.root>
<Head {...props} />
Expand Down Expand Up @@ -89,18 +89,21 @@ export default function DocsLayout(props) {
Theme UI
</Link>
</Flex>
<Flex>
<NavLink href="https://github.com/system-ui/theme-ui">
GitHub
</NavLink>
<Button
sx={{
ml: 2,
whiteSpace: 'pre',
}}
onClick={cycleMode}>
{getModeName(mode)}
</Button>
<Flex sx={{ gap: [0, 2] }}>
<SearchInput />
<Flex sx={{ alignItems: 'center' }}>
<NavLink href="https://github.com/system-ui/theme-ui">
GitHub
</NavLink>
<Button
sx={{
ml: 2,
whiteSpace: 'pre',
}}
onClick={cycleMode}>
{getModeName(mode)}
</Button>
</Flex>
</Flex>
</Flex>
)}
Expand Down
140 changes: 140 additions & 0 deletions packages/docs/src/components/search-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// @ts-check
/** @jsx jsx */

import { jsx } from 'theme-ui'
import { Input } from '@theme-ui/components'

/**
* @type {import("theme-ui").ThemeUIStyleObject}
* @see https://docsearch.algolia.com/docs/styling/
*/
const algoliaStyles = {
'.algolia-autocomplete': {
color: 'text',
'.ds-dropdown-menu': {
backgroundColor: 'background',

boxShadow: 'rgba(0, 0, 0, 0.15) 0px 48px 100px 0px',

'&:before': {
backgroundColor: 'inherit',
color: 'muted',
borderColor: 'currentColor',
},
},
'.ds-dropdown-menu [class^=ds-dataset-]': {
backgroundColor: 'inherit',
color: 'muted',
border: '1px solid currentColor',
},
'.algolia-docsearch-suggestion': {
color: 'text',
backgroundColor: 'inherit',
},
'.algolia-docsearch-suggestion--subcategory-column': {
color: 'text',
},
'.algolia-docsearch-suggestion--highlight': {
color: 'primary',
'--shadow-color': (theme) => theme.colors.muted,
boxShadow: 'inset 0 -2px 0 0 var(--shadow-color)',
},
'.algolia-docsearch-suggestion--subcategory-column-text': {},
'.algolia-docsearch-suggestion--text': {
fontSize: 1,
color: 'gray',
},
'.algolia-docsearch-suggestion--title': {
fontWeight: 'bold',
color: 'text',
fontSize: 1,
'.algolia-docsearch-suggestion--highlight': {
verticalAlign: 'middle',
},
},
'.algolia-docsearch-suggestion--category-header': {
display: 'none !important',
borderBottom: '1px solid transparent',
fontSize: 1,
color: 'text',
},
'.algolia-docsearch-suggestion--content:before': {
backgroundColor: 'gray',
opacity: 0.2,
},
'.algolia-docsearch-suggestion--subcategory-column:before': {
display: 'none',
},
'.ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content': {
backgroundColor: 'muted',
},
'@media (max-width: 768px)': {
// todo: make docsearch autocomplete dropdown responsive
},
},
}

/**
* @type {import("theme-ui").ThemeUIStyleObject}
*/
const resetButtonStyles = {
'input[type="search"]': {
'&::-webkit-search-cancel-button': {
WebkitAppearance: 'none',
height: '1em',
width: '1em',
borderRadius: '50em',
background: (th) => {
const textColor = (th.rawColors || th.colors).text
const fill = encodeURIComponent(String(textColor))
return `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='${fill}' d='M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z'/%3E%3C/svg%3E");`
},
backgroundSize: 'contain',
opacity: 0,
pointerEvents: 'none',
},
'&:focus::-webkit-search-cancel-button': {
opacity: 0.3,
pointerEvents: 'all',
},
},
}

const searchFormStyles = {
...resetButtonStyles,
...algoliaStyles,

// Search results are not responsive.
'@media (max-width: 475px)': {
display: 'none',
},
}

export default function SearchInput() {
return (
<form sx={searchFormStyles}>
<Input
type="search"
id="algolia-docs-search"
placeholder="Search the docs"
aria-label="Search docs"
autoComplete="off"
sx={{
minWidth: ['unset', 100],
borderColor: 'transparent',
backgroundColor: 'muted',
px: 2,
py: 2,
color: 'inherit',
textDecoration: 'none',
fontSize: 1,
fontWeight: 'bold',
'::placeholder': {
color: 'text',
opacity: 0.4,
},
}}
/>
</form>
)
}
8 changes: 7 additions & 1 deletion packages/docs/src/gatsby-plugin-theme-ui/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// @ts-check
import prism from '@theme-ui/prism/presets/theme-ui'

/**
* @type {import("theme-ui").ThemeUIStyleObject}
*/
const tableCellStyle = {
textAlign: 'left',
py: '4px',
Expand All @@ -9,6 +13,9 @@ const tableCellStyle = {
borderBottomStyle: 'solid',
}

/**
* @type {import("theme-ui").Theme & { prism: typeof prism }}
*/
const theme = {
colors: {
text: '#000000',
Expand Down Expand Up @@ -84,7 +91,6 @@ const theme = {
variant: 'default',
my: 2,
textAlign: 'justify',
textAlignLast: 'last',
textJustify: 'auto',
},
display: {
Expand Down
65 changes: 61 additions & 4 deletions packages/docs/src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,69 @@
// @ts-check

/** @jsx jsx */
import { jsx } from 'theme-ui'
import Layout from './components/layout'

export const WrapPageElement = ({ element, props }) => (
<Layout {...props} children={element} />
)

export { default as Banner } from './components/banner'
export { default as Tiles } from './components/tiles'
export { default as Cards } from './components/cards'
export { default as Note } from './components/note'

/**
* @param {import("gatsby").WrapPageElementBrowserArgs} props
*/
export const WrapPageElement = ({ element, props }) => (
<Layout {...props} children={element} />
)

/**
* @see https://docsearch.algolia.com/
* @param {import("gatsby").RenderBodyArgs} args
*/
export const setDocSearchComponents = ({
setHeadComponents,
setPostBodyComponents,
}) => {
setHeadComponents([
<link
key="algolia-css"
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css"
/>,
])
setPostBodyComponents([
<script
key="algolia-cdn"
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>,
<script
key="algolia-script"
type="text/javascript"
dangerouslySetInnerHTML={{
__html: `
var observer = new MutationObserver(function () {
var searchSelector = "#algolia-docs-search";
var searchInput = document.querySelector(searchSelector);
if (searchInput) {
docsearch({
apiKey: "84ed820927eee5fa5018c9f1abe70390",
indexName: "theme-ui",
inputSelector: searchSelector,
debug: true
})
observer.disconnect()
observer = null
}
});
// start observing
document.addEventListener("DOMContentLoaded", function() {
observer.observe(document, {
childList: true,
subtree: true
});
});
`,
}}
/>,
])
}