Skip to content
This repository was archived by the owner on Jan 24, 2025. It is now read-only.

Commit a01d100

Browse files
committed
feat: add new theme sidebar
1 parent 35fac28 commit a01d100

File tree

23 files changed

+326
-109
lines changed

23 files changed

+326
-109
lines changed

core/docz-core/src/machines/devServer/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,4 @@ const machine = Machine<ServerMachineCtx>({
6262
export const devServerMachine = machine.withConfig({
6363
services,
6464
actions,
65-
})
65+
} as any)

core/docz-core/src/machines/devServer/services/ensureDirs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import * as paths from '../../../config/paths'
44

55
export const ensureDirs = async () => {
66
await fs.ensureDir(paths.docz)
7-
await fs.ensureDir(path.join(paths.docz, 'src/pages'))
7+
return await fs.ensureDir(path.join(paths.docz, 'src/pages'))
88
}

core/docz-utils/src/mdast.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,6 @@ export interface ParsedData {
8080
}
8181

8282
export const getParsedData = (ast: any): ParsedData => {
83-
const node = find(ast, (node: any) => is('yaml', node))
83+
const node = find(ast, (node: any) => is(node, 'yaml'))
8484
return get(node, `data.parsedValue`) || {}
8585
}

core/docz/src/hooks/useMenus.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ const sortMenus = (first: Menus, second: Menus | undefined = []): Menus => {
111111
const search = (val: string, menu: MenuItem[]) => {
112112
const items = menu.map(item => [item].concat(item.menu || []))
113113
const flattened = flattenDepth(2, items)
114-
const flattenedDeduplicated = [...new Set(flattened)]
114+
const flattenedDeduplicated = Array.from(new Set(flattened))
115115
return match(flattenedDeduplicated, val, { keys: ['name'] })
116116
}
117117

@@ -143,6 +143,7 @@ export const useMenus = (opts?: UseMenusParams) => {
143143
return filterMenus(result, opts && opts.filter)
144144
}, [entries, config])
145145

146+
console.log(query)
146147
return query && query.length > 0
147148
? (search(query, sorted) as MenuItem[])
148149
: sorted

core/gatsby-theme-docz/src/base/Layout.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
33
import { useStaticQuery, graphql } from 'gatsby'
44
import { useComponents } from 'docz'
55
import { MDXProvider } from '@mdx-js/react'
6+
import { propEq, get } from 'lodash/fp'
67

78
import Theme from '../docz'
89
import Wrapper from '../docz/wrapper'
@@ -42,12 +43,16 @@ const parseDatabase = data => {
4243
}
4344
}
4445

46+
const findEntry = (db, ctx) => {
47+
const filepath = get('entry.filepath', ctx)
48+
return db.entries.find(propEq('value.filepath', filepath))
49+
}
50+
4551
const Layout = ({ children, ...defaultProps }) => {
4652
const { pageContext: ctx } = defaultProps
4753
const data = useStaticQuery(query)
4854
const db = parseDatabase(data)
49-
const entry =
50-
db.entries && db.entries.find(entry => entry.filepath === ctx.filepath)
55+
const entry = findEntry(db, ctx)
5156

5257
return (
5358
<Fragment>

core/gatsby-theme-docz/src/docz/components/Header/index.js

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ import { Link, useConfig, useCurrentDoc } from 'docz'
44
import styled from '@emotion/styled'
55

66
import { themeProp } from '@docz/utils/theme'
7+
import { breakpoints } from '@docz/theme/breakpoints'
8+
79
import { Edit, Sun, Menu, Github } from '../Icons'
810
import * as styles from './styles'
911

1012
const Wrapper = styled(Box)`
1113
border-bottom: 1px solid ${themeProp('colors.header.border')};
1214
`
1315

14-
export const Header = () => {
16+
export const Header = ({ onOpen, nav }) => {
1517
const config = useConfig()
1618
const { edit = true, ...doc } = useCurrentDoc()
1719
const [colorMode, setColorMode] = useColorMode()
@@ -20,46 +22,53 @@ export const Header = () => {
2022
setColorMode(colorMode === 'light' ? 'dark' : 'light')
2123
}
2224

25+
const handleMenu = () => {
26+
onOpen(s => !s)
27+
if (!nav.current) return
28+
const navLink = nav.current.querySelector('a')
29+
if (navLink) navLink.focus()
30+
}
31+
2332
return (
24-
<Wrapper css={styles.wrapper}>
33+
<Wrapper sx={styles.wrapper}>
2534
<Container>
26-
<div css={styles.innerContainer}>
35+
<div sx={styles.innerContainer}>
2736
<Flex aligmItems="center">
28-
<button css={styles.menuButton}>
29-
<Menu size={30} />
30-
</button>
31-
<Box pl={3}>
32-
<Link to="/" css={styles.link}>
33-
{config.title}
34-
</Link>
37+
<Box sx={styles.menuIcon}>
38+
<button sx={styles.menuButton} onClick={handleMenu}>
39+
<Menu size={30} />
40+
</button>
3541
</Box>
42+
<Link to="/" sx={styles.link}>
43+
{config.title}
44+
</Link>
3645
</Flex>
3746
<Flex>
3847
{config.repository && (
39-
<Box mr={3}>
48+
<Box sx={{ mr: 2 }}>
4049
<a
4150
href={config.repository}
42-
css={styles.headerButton}
51+
sx={styles.headerButton}
4352
target="_blank"
4453
rel="noopener noreferrer"
4554
>
4655
<Github size={15} />
4756
</a>
4857
</Box>
4958
)}
50-
<button css={styles.headerButton} onClick={toggleColorMode}>
59+
<button sx={styles.headerButton} onClick={toggleColorMode}>
5160
<Sun size={15} />
5261
</button>
5362
</Flex>
5463
{edit && doc.link && (
5564
<a
56-
css={styles.editButton}
65+
sx={styles.editButton}
5766
href={doc.link}
5867
target="_blank"
5968
rel="noopener noreferrer"
6069
>
6170
<Edit width={14} />
62-
<Box pl={2}>Edit page</Box>
71+
<Box sx={{ pl: 2 }}>Edit page</Box>
6372
</a>
6473
)}
6574
</div>

core/gatsby-theme-docz/src/docz/components/Header/styles.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
import * as mixins from '@docz/utils/mixins'
2+
import { media } from '@docz/theme/breakpoints'
3+
4+
export const menuIcon = {
5+
mr: 3,
6+
display: 'none',
7+
[media.tablet]: {
8+
display: 'block',
9+
},
10+
}
211

312
export const wrapper = {
413
bg: 'header.bg',

core/gatsby-theme-docz/src/docz/components/Headings/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const heading = Tag => {
77
<Tag {...props}>
88
<a
99
href={`#${props.id}`}
10-
css={{
10+
sx={{
1111
color: 'inherit',
1212
textDecoration: 'none',
1313
':hover': {

core/gatsby-theme-docz/src/docz/components/Icons/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export { default as Edit } from 'react-feather/dist/icons/edit-2'
22
export { default as Sun } from 'react-feather/dist/icons/sun'
33
export { default as Menu } from 'react-feather/dist/icons/menu'
44
export { default as Github } from 'react-feather/dist/icons/github'
5+
export { default as Search } from 'react-feather/dist/icons/search'
Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,33 @@
11
/** @jsx jsx */
2-
import { jsx, css, Layout as BaseLayout, Main, Container } from 'theme-ui'
2+
import { useRef, useState } from 'react'
3+
import { jsx, Layout as BaseLayout, Main, Container } from 'theme-ui'
34
import { Global } from '@emotion/core'
45

56
import global from '@docz/theme/global'
67
import { Header } from '../Header'
8+
import { Sidebar } from '../Sidebar'
9+
import * as styles from './styles'
710

8-
export const Layout = ({ children }) => (
9-
<BaseLayout css={{ '> div': { flex: '1 1 auto' } }}>
10-
<Global styles={global} />
11-
<Main>
12-
<Header />
13-
<Container>{children}</Container>
14-
</Main>
15-
</BaseLayout>
16-
)
11+
export const Layout = ({ children }) => {
12+
const [open, setOpen] = useState(false)
13+
const nav = useRef()
14+
15+
return (
16+
<BaseLayout sx={{ '& > div': { flex: '1 1 auto' } }}>
17+
<Global styles={global} />
18+
<Main>
19+
<Header nav={nav} onOpen={setOpen} />
20+
<Container sx={styles.container}>
21+
<Sidebar
22+
ref={nav}
23+
open={open}
24+
onFocus={() => setOpen(true)}
25+
onBlur={() => setOpen(false)}
26+
onClick={() => setOpen(false)}
27+
/>
28+
<div sx={styles.content}>{children}</div>
29+
</Container>
30+
</Main>
31+
</BaseLayout>
32+
)
33+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { media } from '@docz/theme/breakpoints'
2+
3+
export const container = {
4+
py: 0,
5+
display: 'grid',
6+
gridTemplateColumns: '250px 1fr',
7+
[media.tablet]: {
8+
display: 'block',
9+
},
10+
}
11+
12+
export const content = {
13+
py: 5,
14+
px: 4,
15+
[media.tablet]: {
16+
py: 4,
17+
px: 0,
18+
},
19+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/** @jsx jsx */
2+
import { jsx } from 'theme-ui'
3+
4+
import * as styles from './styles'
5+
import { NavLink } from '../NavLink'
6+
7+
export const NavGroup = ({ item }) => {
8+
const { menu } = item
9+
return (
10+
<div sx={styles.wrapper}>
11+
<div sx={styles.title}>{item.name}</div>
12+
{menu &&
13+
menu.map(menu => {
14+
return (
15+
<NavLink key={menu.id} item={menu}>
16+
{menu.name}
17+
</NavLink>
18+
)
19+
})}
20+
</div>
21+
)
22+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const wrapper = {
2+
my: 3,
3+
}
4+
5+
export const title = {
6+
mb: 1,
7+
fontSize: 0,
8+
fontWeight: 600,
9+
textTransform: 'uppercase',
10+
color: 'sidebar.navGroup',
11+
}
Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,40 @@
11
/** @jsx jsx */
2+
import React from 'react'
23
import { jsx } from 'theme-ui'
34
import { Link } from 'gatsby'
4-
import isAbsoluteURL from 'is-absolute-url'
5+
import { useDocs, useCurrentDoc } from 'docz'
6+
import { get } from 'lodash/fp'
57

6-
const styles = {
7-
display: 'inline-block',
8-
px: 2,
9-
py: 2,
10-
color: 'inherit',
11-
textDecoration: 'none',
12-
fontSize: 1,
13-
fontWeight: 'bold',
14-
'&.active': {
15-
color: 'primary',
16-
},
8+
import * as styles from './styles'
9+
10+
const getHeadings = (route, docs) => {
11+
const doc = docs.find(doc => doc.route === route)
12+
const headings = get('headings', doc)
13+
return headings ? headings.filter(heading => heading.depth === 2) : []
1714
}
1815

19-
export const NavLink = ({ href, ...props }) => {
20-
const isExternal = isAbsoluteURL(href || '')
21-
if (isExternal) {
22-
return <a {...props} href={href} css={styles} />
23-
}
24-
const to = props.to || href
25-
return <Link {...props} to={to} css={styles} activeClassName="active" />
16+
export const NavLink = ({ item, ...props }) => {
17+
const docs = useDocs()
18+
const to = item.route
19+
const headings = docs && getHeadings(to, docs)
20+
const current = useCurrentDoc()
21+
const isCurrent = item.route === current.route
22+
const showHeadings = isCurrent && headings && headings.length > 0
23+
24+
return (
25+
<React.Fragment>
26+
<Link {...props} to={to} sx={styles.link} activeClassName="active" />
27+
{showHeadings &&
28+
headings.map(heading => (
29+
<Link
30+
key={heading.slug}
31+
to={`${to}#${heading.slug}`}
32+
sx={styles.smallLink}
33+
activeClassName="active"
34+
>
35+
{heading.value}
36+
</Link>
37+
))}
38+
</React.Fragment>
39+
)
2640
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export const link = {
2+
my: 2,
3+
display: 'block',
4+
color: 'sidebar.navLink',
5+
textDecoration: 'none',
6+
fontSize: 2,
7+
'&.active': {
8+
color: 'sidebar.navLinkActive',
9+
},
10+
}
11+
12+
export const smallLink = {
13+
...link,
14+
ml: 2,
15+
fontSize: 1,
16+
color: 'sidebar.tocLink',
17+
'&.active': {
18+
color: 'sidebar.tocLinkActive',
19+
},
20+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/** @jsx jsx */
2+
import { jsx } from 'theme-ui'
3+
4+
import * as styles from './styles'
5+
import { Search } from '../Icons'
6+
7+
export const NavSearch = props => {
8+
return (
9+
<div sx={styles.wrapper}>
10+
<Search size={20} sx={styles.icon} />
11+
<input {...props} sx={styles.input} />
12+
</div>
13+
)
14+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export const wrapper = {
2+
mb: 3,
3+
display: 'flex',
4+
alignItems: 'center',
5+
}
6+
7+
export const input = {
8+
outline: 'none',
9+
background: 'none',
10+
border: 'none',
11+
color: 'text',
12+
fontSize: 1,
13+
}
14+
15+
export const icon = {
16+
color: 'border',
17+
mr: 2,
18+
}

0 commit comments

Comments
 (0)