From a01d100615f107124dcd4a687207fdbf2fec0289 Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Wed, 26 Jun 2019 16:41:34 -0300 Subject: [PATCH] feat: add new theme sidebar --- .../docz-core/src/machines/devServer/index.ts | 2 +- .../machines/devServer/services/ensureDirs.ts | 2 +- core/docz-utils/src/mdast.ts | 2 +- core/docz/src/hooks/useMenus.ts | 3 +- core/gatsby-theme-docz/src/base/Layout.js | 9 +- .../src/docz/components/Header/index.js | 39 +++++--- .../src/docz/components/Header/styles.js | 9 ++ .../src/docz/components/Headings/index.js | 2 +- .../src/docz/components/Icons/index.js | 1 + .../src/docz/components/Layout/index.js | 37 ++++++-- .../src/docz/components/Layout/styles.js | 19 ++++ .../src/docz/components/NavGroup/index.js | 22 +++++ .../src/docz/components/NavGroup/styles.js | 11 +++ .../src/docz/components/NavLink/index.js | 52 ++++++---- .../src/docz/components/NavLink/styles.js | 20 ++++ .../src/docz/components/NavSearch/index.js | 14 +++ .../src/docz/components/NavSearch/styles.js | 18 ++++ .../src/docz/components/Sidebar/index.js | 94 ++++++++----------- .../src/docz/components/Sidebar/styles.js | 47 ++++++++++ .../src/docz/theme/breakpoints.js | 14 +++ .../gatsby-theme-docz/src/docz/theme/index.js | 2 +- .../gatsby-theme-docz/src/docz/theme/modes.js | 14 +++ .../gatsby-theme-docz/src/node/createPages.js | 2 +- 23 files changed, 326 insertions(+), 109 deletions(-) create mode 100644 core/gatsby-theme-docz/src/docz/components/Layout/styles.js create mode 100644 core/gatsby-theme-docz/src/docz/components/NavGroup/index.js create mode 100644 core/gatsby-theme-docz/src/docz/components/NavGroup/styles.js create mode 100644 core/gatsby-theme-docz/src/docz/components/NavLink/styles.js create mode 100644 core/gatsby-theme-docz/src/docz/components/NavSearch/index.js create mode 100644 core/gatsby-theme-docz/src/docz/components/NavSearch/styles.js create mode 100644 core/gatsby-theme-docz/src/docz/components/Sidebar/styles.js create mode 100644 core/gatsby-theme-docz/src/docz/theme/breakpoints.js diff --git a/core/docz-core/src/machines/devServer/index.ts b/core/docz-core/src/machines/devServer/index.ts index 235645948..6d70774f8 100644 --- a/core/docz-core/src/machines/devServer/index.ts +++ b/core/docz-core/src/machines/devServer/index.ts @@ -62,4 +62,4 @@ const machine = Machine({ export const devServerMachine = machine.withConfig({ services, actions, -}) +} as any) diff --git a/core/docz-core/src/machines/devServer/services/ensureDirs.ts b/core/docz-core/src/machines/devServer/services/ensureDirs.ts index 834054d5f..fe41655c0 100644 --- a/core/docz-core/src/machines/devServer/services/ensureDirs.ts +++ b/core/docz-core/src/machines/devServer/services/ensureDirs.ts @@ -4,5 +4,5 @@ import * as paths from '../../../config/paths' export const ensureDirs = async () => { await fs.ensureDir(paths.docz) - await fs.ensureDir(path.join(paths.docz, 'src/pages')) + return await fs.ensureDir(path.join(paths.docz, 'src/pages')) } diff --git a/core/docz-utils/src/mdast.ts b/core/docz-utils/src/mdast.ts index 5ff5965fb..ed6ca9165 100644 --- a/core/docz-utils/src/mdast.ts +++ b/core/docz-utils/src/mdast.ts @@ -80,6 +80,6 @@ export interface ParsedData { } export const getParsedData = (ast: any): ParsedData => { - const node = find(ast, (node: any) => is('yaml', node)) + const node = find(ast, (node: any) => is(node, 'yaml')) return get(node, `data.parsedValue`) || {} } diff --git a/core/docz/src/hooks/useMenus.ts b/core/docz/src/hooks/useMenus.ts index 25934438b..da8ab1ef9 100644 --- a/core/docz/src/hooks/useMenus.ts +++ b/core/docz/src/hooks/useMenus.ts @@ -111,7 +111,7 @@ const sortMenus = (first: Menus, second: Menus | undefined = []): Menus => { const search = (val: string, menu: MenuItem[]) => { const items = menu.map(item => [item].concat(item.menu || [])) const flattened = flattenDepth(2, items) - const flattenedDeduplicated = [...new Set(flattened)] + const flattenedDeduplicated = Array.from(new Set(flattened)) return match(flattenedDeduplicated, val, { keys: ['name'] }) } @@ -143,6 +143,7 @@ export const useMenus = (opts?: UseMenusParams) => { return filterMenus(result, opts && opts.filter) }, [entries, config]) + console.log(query) return query && query.length > 0 ? (search(query, sorted) as MenuItem[]) : sorted diff --git a/core/gatsby-theme-docz/src/base/Layout.js b/core/gatsby-theme-docz/src/base/Layout.js index 302ccbbfd..fb063f60c 100644 --- a/core/gatsby-theme-docz/src/base/Layout.js +++ b/core/gatsby-theme-docz/src/base/Layout.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import { useStaticQuery, graphql } from 'gatsby' import { useComponents } from 'docz' import { MDXProvider } from '@mdx-js/react' +import { propEq, get } from 'lodash/fp' import Theme from '../docz' import Wrapper from '../docz/wrapper' @@ -42,12 +43,16 @@ const parseDatabase = data => { } } +const findEntry = (db, ctx) => { + const filepath = get('entry.filepath', ctx) + return db.entries.find(propEq('value.filepath', filepath)) +} + const Layout = ({ children, ...defaultProps }) => { const { pageContext: ctx } = defaultProps const data = useStaticQuery(query) const db = parseDatabase(data) - const entry = - db.entries && db.entries.find(entry => entry.filepath === ctx.filepath) + const entry = findEntry(db, ctx) return ( diff --git a/core/gatsby-theme-docz/src/docz/components/Header/index.js b/core/gatsby-theme-docz/src/docz/components/Header/index.js index 7219cf8bf..4880c7f31 100644 --- a/core/gatsby-theme-docz/src/docz/components/Header/index.js +++ b/core/gatsby-theme-docz/src/docz/components/Header/index.js @@ -4,6 +4,8 @@ import { Link, useConfig, useCurrentDoc } from 'docz' import styled from '@emotion/styled' import { themeProp } from '@docz/utils/theme' +import { breakpoints } from '@docz/theme/breakpoints' + import { Edit, Sun, Menu, Github } from '../Icons' import * as styles from './styles' @@ -11,7 +13,7 @@ const Wrapper = styled(Box)` border-bottom: 1px solid ${themeProp('colors.header.border')}; ` -export const Header = () => { +export const Header = ({ onOpen, nav }) => { const config = useConfig() const { edit = true, ...doc } = useCurrentDoc() const [colorMode, setColorMode] = useColorMode() @@ -20,26 +22,33 @@ export const Header = () => { setColorMode(colorMode === 'light' ? 'dark' : 'light') } + const handleMenu = () => { + onOpen(s => !s) + if (!nav.current) return + const navLink = nav.current.querySelector('a') + if (navLink) navLink.focus() + } + return ( - + -
+
- - - - {config.title} - + + + + {config.title} + {config.repository && ( - + @@ -47,19 +56,19 @@ export const Header = () => { )} - {edit && doc.link && ( - Edit page + Edit page )}
diff --git a/core/gatsby-theme-docz/src/docz/components/Header/styles.js b/core/gatsby-theme-docz/src/docz/components/Header/styles.js index 108050a50..16b9e588b 100644 --- a/core/gatsby-theme-docz/src/docz/components/Header/styles.js +++ b/core/gatsby-theme-docz/src/docz/components/Header/styles.js @@ -1,4 +1,13 @@ import * as mixins from '@docz/utils/mixins' +import { media } from '@docz/theme/breakpoints' + +export const menuIcon = { + mr: 3, + display: 'none', + [media.tablet]: { + display: 'block', + }, +} export const wrapper = { bg: 'header.bg', diff --git a/core/gatsby-theme-docz/src/docz/components/Headings/index.js b/core/gatsby-theme-docz/src/docz/components/Headings/index.js index c959c5063..f072d4b24 100644 --- a/core/gatsby-theme-docz/src/docz/components/Headings/index.js +++ b/core/gatsby-theme-docz/src/docz/components/Headings/index.js @@ -7,7 +7,7 @@ const heading = Tag => { ( - div': { flex: '1 1 auto' } }}> - -
-
- {children} -
-
-) +export const Layout = ({ children }) => { + const [open, setOpen] = useState(false) + const nav = useRef() + + return ( + div': { flex: '1 1 auto' } }}> + +
+
+ + setOpen(true)} + onBlur={() => setOpen(false)} + onClick={() => setOpen(false)} + /> +
{children}
+
+
+
+ ) +} diff --git a/core/gatsby-theme-docz/src/docz/components/Layout/styles.js b/core/gatsby-theme-docz/src/docz/components/Layout/styles.js new file mode 100644 index 000000000..72a31e001 --- /dev/null +++ b/core/gatsby-theme-docz/src/docz/components/Layout/styles.js @@ -0,0 +1,19 @@ +import { media } from '@docz/theme/breakpoints' + +export const container = { + py: 0, + display: 'grid', + gridTemplateColumns: '250px 1fr', + [media.tablet]: { + display: 'block', + }, +} + +export const content = { + py: 5, + px: 4, + [media.tablet]: { + py: 4, + px: 0, + }, +} diff --git a/core/gatsby-theme-docz/src/docz/components/NavGroup/index.js b/core/gatsby-theme-docz/src/docz/components/NavGroup/index.js new file mode 100644 index 000000000..e157e5669 --- /dev/null +++ b/core/gatsby-theme-docz/src/docz/components/NavGroup/index.js @@ -0,0 +1,22 @@ +/** @jsx jsx */ +import { jsx } from 'theme-ui' + +import * as styles from './styles' +import { NavLink } from '../NavLink' + +export const NavGroup = ({ item }) => { + const { menu } = item + return ( +
+
{item.name}
+ {menu && + menu.map(menu => { + return ( + + {menu.name} + + ) + })} +
+ ) +} diff --git a/core/gatsby-theme-docz/src/docz/components/NavGroup/styles.js b/core/gatsby-theme-docz/src/docz/components/NavGroup/styles.js new file mode 100644 index 000000000..494d7c612 --- /dev/null +++ b/core/gatsby-theme-docz/src/docz/components/NavGroup/styles.js @@ -0,0 +1,11 @@ +export const wrapper = { + my: 3, +} + +export const title = { + mb: 1, + fontSize: 0, + fontWeight: 600, + textTransform: 'uppercase', + color: 'sidebar.navGroup', +} diff --git a/core/gatsby-theme-docz/src/docz/components/NavLink/index.js b/core/gatsby-theme-docz/src/docz/components/NavLink/index.js index 176ba3c28..9088afd44 100644 --- a/core/gatsby-theme-docz/src/docz/components/NavLink/index.js +++ b/core/gatsby-theme-docz/src/docz/components/NavLink/index.js @@ -1,26 +1,40 @@ /** @jsx jsx */ +import React from 'react' import { jsx } from 'theme-ui' import { Link } from 'gatsby' -import isAbsoluteURL from 'is-absolute-url' +import { useDocs, useCurrentDoc } from 'docz' +import { get } from 'lodash/fp' -const styles = { - display: 'inline-block', - px: 2, - py: 2, - color: 'inherit', - textDecoration: 'none', - fontSize: 1, - fontWeight: 'bold', - '&.active': { - color: 'primary', - }, +import * as styles from './styles' + +const getHeadings = (route, docs) => { + const doc = docs.find(doc => doc.route === route) + const headings = get('headings', doc) + return headings ? headings.filter(heading => heading.depth === 2) : [] } -export const NavLink = ({ href, ...props }) => { - const isExternal = isAbsoluteURL(href || '') - if (isExternal) { - return
- } - const to = props.to || href - return +export const NavLink = ({ item, ...props }) => { + const docs = useDocs() + const to = item.route + const headings = docs && getHeadings(to, docs) + const current = useCurrentDoc() + const isCurrent = item.route === current.route + const showHeadings = isCurrent && headings && headings.length > 0 + + return ( + + + {showHeadings && + headings.map(heading => ( + + {heading.value} + + ))} + + ) } diff --git a/core/gatsby-theme-docz/src/docz/components/NavLink/styles.js b/core/gatsby-theme-docz/src/docz/components/NavLink/styles.js new file mode 100644 index 000000000..80a5d9ce2 --- /dev/null +++ b/core/gatsby-theme-docz/src/docz/components/NavLink/styles.js @@ -0,0 +1,20 @@ +export const link = { + my: 2, + display: 'block', + color: 'sidebar.navLink', + textDecoration: 'none', + fontSize: 2, + '&.active': { + color: 'sidebar.navLinkActive', + }, +} + +export const smallLink = { + ...link, + ml: 2, + fontSize: 1, + color: 'sidebar.tocLink', + '&.active': { + color: 'sidebar.tocLinkActive', + }, +} diff --git a/core/gatsby-theme-docz/src/docz/components/NavSearch/index.js b/core/gatsby-theme-docz/src/docz/components/NavSearch/index.js new file mode 100644 index 000000000..2d1282d07 --- /dev/null +++ b/core/gatsby-theme-docz/src/docz/components/NavSearch/index.js @@ -0,0 +1,14 @@ +/** @jsx jsx */ +import { jsx } from 'theme-ui' + +import * as styles from './styles' +import { Search } from '../Icons' + +export const NavSearch = props => { + return ( +
+ + +
+ ) +} diff --git a/core/gatsby-theme-docz/src/docz/components/NavSearch/styles.js b/core/gatsby-theme-docz/src/docz/components/NavSearch/styles.js new file mode 100644 index 000000000..42d186206 --- /dev/null +++ b/core/gatsby-theme-docz/src/docz/components/NavSearch/styles.js @@ -0,0 +1,18 @@ +export const wrapper = { + mb: 3, + display: 'flex', + alignItems: 'center', +} + +export const input = { + outline: 'none', + background: 'none', + border: 'none', + color: 'text', + fontSize: 1, +} + +export const icon = { + color: 'border', + mr: 2, +} diff --git a/core/gatsby-theme-docz/src/docz/components/Sidebar/index.js b/core/gatsby-theme-docz/src/docz/components/Sidebar/index.js index e846ab236..d5cf1b2a1 100644 --- a/core/gatsby-theme-docz/src/docz/components/Sidebar/index.js +++ b/core/gatsby-theme-docz/src/docz/components/Sidebar/index.js @@ -1,61 +1,43 @@ /** @jsx jsx */ -import React from 'react' -import { jsx, Box } from 'theme-ui' +import React, { Fragment, useState } from 'react' import { Global } from '@emotion/core' +import { jsx, Box } from 'theme-ui' +import { useMenus } from 'docz' + +import * as styles from './styles' +import { NavSearch } from '../NavSearch' +import { NavLink } from '../NavLink' +import { NavGroup } from '../NavGroup' -export const Sidebar = React.forwardRef((props, ref) => ( - - {props.open && ( - - { + const [query, setQuery] = useState('') + const menus = useMenus({ query }) + + const handleChange = ev => { + setQuery(ev.target.value) + } + + return ( + + + {props.open && } + + + + {menus && + menus.map(menu => { + if (!menu.route) return + return ( + + {menu.name} + + ) + })} - )} - - helo world - - -)) + + ) +}) diff --git a/core/gatsby-theme-docz/src/docz/components/Sidebar/styles.js b/core/gatsby-theme-docz/src/docz/components/Sidebar/styles.js new file mode 100644 index 000000000..3f12f3635 --- /dev/null +++ b/core/gatsby-theme-docz/src/docz/components/Sidebar/styles.js @@ -0,0 +1,47 @@ +import { media } from '@docz/theme/breakpoints' + +export const global = { + body: { + overflow: 'hidden', + }, +} + +export const overlay = ({ open }) => ({ + position: 'fixed', + top: 104, + right: 0, + bottom: 0, + left: 0, + background: 'rgba(0,0,0,0.6)', + transition: 'all .2s ease-out', + visibility: open ? 'visible' : 'hidden', + opacity: open ? 1 : 0, +}) + +export const wrapper = ({ open }) => ({ + py: 4, + mr: 4, + flexDirection: 'column', + position: 'sticky', + top: 0, + zIndex: 1, + minWidth: 0, + maxHeight: '100vh', + borderRight: '1px solid #000', + borderColor: 'border', + overflow: 'auto', + WebkitOverflowScrolling: 'touch', + + [media.tablet]: { + display: 'block', + position: 'fixed', + top: 104, + left: 0, + bottom: 0, + width: 256, + px: 4, + bg: 'background', + transition: 'transform .2s ease-out', + transform: open ? 'translateX(0)' : 'translateX(-100%)', + }, +}) diff --git a/core/gatsby-theme-docz/src/docz/theme/breakpoints.js b/core/gatsby-theme-docz/src/docz/theme/breakpoints.js new file mode 100644 index 000000000..bfffc0c81 --- /dev/null +++ b/core/gatsby-theme-docz/src/docz/theme/breakpoints.js @@ -0,0 +1,14 @@ +const em = px => `${px / 16}em` +const mountMedia = val => `@media screen and (max-width: ${em(val)})` + +export const breakpoints = { + mobile: 630, + tablet: 920, + desktop: 1120, +} + +export const media = { + mobile: mountMedia(breakpoints.mobile), + tablet: mountMedia(breakpoints.tablet), + desktop: mountMedia(breakpoints.desktop), +} diff --git a/core/gatsby-theme-docz/src/docz/theme/index.js b/core/gatsby-theme-docz/src/docz/theme/index.js index 5212ba547..a25313900 100644 --- a/core/gatsby-theme-docz/src/docz/theme/index.js +++ b/core/gatsby-theme-docz/src/docz/theme/index.js @@ -1,5 +1,5 @@ import moraga from 'typography-theme-moraga' -import { toTheme } from 'theme-ui-typography' +import { toTheme } from '@theme-ui/typography' import { merge } from 'lodash/fp' import * as modes from './modes' diff --git a/core/gatsby-theme-docz/src/docz/theme/modes.js b/core/gatsby-theme-docz/src/docz/theme/modes.js index 90d5d8795..ed2016b38 100644 --- a/core/gatsby-theme-docz/src/docz/theme/modes.js +++ b/core/gatsby-theme-docz/src/docz/theme/modes.js @@ -8,6 +8,13 @@ export const light = { link: colors.blue, background: colors.white, border: colors.grayLight, + sidebar: { + navGroup: colors.grayLight, + navLink: colors.grayDark, + navLinkActive: colors.blue, + tocLink: colors.gray, + tocLinkActive: colors.grayDark, + }, header: { bg: colors.grayExtraLight, text: colors.dark, @@ -27,6 +34,13 @@ export const dark = { link: colors.skyBlue, background: colors.grayExtraDark, border: colors.grayDark, + sidebar: { + navGroup: colors.gray, + navLink: colors.grayLight, + navLinkActive: colors.skyBlue, + tocLink: colors.gray, + tocLinkActive: colors.grayLight, + }, header: { bg: colors.dark, text: colors.grayLight, diff --git a/core/gatsby-theme-docz/src/node/createPages.js b/core/gatsby-theme-docz/src/node/createPages.js index e5a987dca..06b989ea8 100644 --- a/core/gatsby-theme-docz/src/node/createPages.js +++ b/core/gatsby-theme-docz/src/node/createPages.js @@ -23,7 +23,7 @@ const ENTRIES_QUERY = ` } ` -module.exports = ({ graphql, actions }) => { +module.exports = ({ graphql, actions, ...props }) => { return graphql(ENTRIES_QUERY).then(({ data, errors }) => { const hasErrors = errors && errors.length > 0 const entries = get('allDoczEntries.edges', data)