Skip to content

Commit db5e0ef

Browse files
committed
feat: explicit toc definition, collapsible toc items, landing pages for all groups
1 parent b1f1652 commit db5e0ef

15 files changed

+294
-272
lines changed

config.js

+114-23
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,128 @@
11
// config for all the things
2-
2+
// docsSections defines the docs tree. Items are either a path to a markdown file,
3+
// or a group object with title, path, description, items
4+
// top-level group objects also have colorClass
35
const docsSections = [
46
{
5-
id: 'tutorials',
6-
text: 'Tutorials',
7-
link: '/docs/tutorials',
8-
subtitle: 'Learn how Qri Works',
7+
title: 'Tutorials',
8+
path: '/docs/tutorials',
99
description: 'Welcome! These tutorials are aimed at beginners and will break things down so you can get started quickly.',
10-
colorClass: 'text-qriorange-600'
10+
colorClass: 'text-qriorange-600',
11+
items: []
1112
},
1213
{
13-
id: 'guides',
14-
text: 'Guides',
15-
link: '/docs/guides',
16-
subtitle: 'Learn how to do things in Qri',
14+
title: 'Guides',
15+
path: '/docs/guides',
1716
description: 'These step-by-step guides will help you perform specific tasks. Refer to them when you need to do one thing well.',
18-
colorClass: 'text-qripink-600'
17+
colorClass: 'text-qripink-600',
18+
items: []
1919
},
2020
{
21-
id: 'concepts',
22-
text: 'Concepts',
23-
link: '/docs/concepts',
24-
subtitle: 'Dive Deeper into Qri',
21+
title: 'Concepts',
22+
path: '/docs/concepts',
2523
description: 'These docs will help explain Qri\'s core concepts and underlying technology',
26-
colorClass: 'text-qrigreen-600'
24+
colorClass: 'text-qrigreen-600',
25+
items: [
26+
{
27+
title: 'Understanding Qri',
28+
path: '/docs/concepts/understanding-qri',
29+
description: 'This section provides detailed explanations of core Qri concepts',
30+
items: [
31+
'/docs/concepts/understanding-qri/what-is-qri',
32+
'/docs/concepts/understanding-qri/how-qri-defines-a-dataset',
33+
'/docs/concepts/understanding-qri/how-qri-version-control-works',
34+
'/docs/concepts/understanding-qri/how-qri-data-transforms-and-automation-work'
35+
]
36+
},
37+
{
38+
title: 'Under the Hood',
39+
path: '/docs/concepts/under-the-hood',
40+
description: 'Dive deeper into underlying Qri concepts',
41+
items: [
42+
'/docs/concepts/under-the-hood/content-addressing',
43+
'/docs/concepts/under-the-hood/how-qri-uses-ipfs',
44+
'/docs/concepts/under-the-hood/why-starlark'
45+
]
46+
}
47+
]
2748
},
2849
{
29-
id: 'reference',
30-
text: 'Reference',
31-
link: '/docs/reference',
32-
subtitle: 'Get the specs',
50+
title: 'Reference',
51+
path: '/docs/reference',
3352
description: 'These technical reference docs will help you use Qri\'s APIs and write custom data transform scripts',
34-
colorClass: 'text-qrinavy-300'
53+
colorClass: 'text-qrinavy-300',
54+
items: [
55+
{
56+
title: 'Starlark Language',
57+
path: '/docs/reference/starlark-language',
58+
description: 'Starlark is an untyped dynamic language with high-level data types, first-class functions with lexical scope, and automatic memory management or garbage collection.',
59+
items: [
60+
'/docs/reference/starlark-language/overview',
61+
'/docs/reference/starlark-language/lexical-elements',
62+
'/docs/reference/starlark-language/data-types',
63+
'/docs/reference/starlark-language/value-concepts',
64+
'/docs/reference/starlark-language/expressions',
65+
'/docs/reference/starlark-language/statements',
66+
'/docs/reference/starlark-language/built-in-constants-and-functions',
67+
{
68+
title: 'Built-in Methods',
69+
path: '/docs/reference/starlark-language/built-in-methods',
70+
description: 'Built-in methods for the Starlark data types',
71+
items: [
72+
'/docs/reference/starlark-language/built-in-methods/dict',
73+
'/docs/reference/starlark-language/built-in-methods/list',
74+
'/docs/reference/starlark-language/built-in-methods/set',
75+
'/docs/reference/starlark-language/built-in-methods/string'
76+
]
77+
}
78+
]
79+
},
80+
{
81+
title: 'Qri HTTP API',
82+
path: '/docs/reference/qri-http-api',
83+
description: 'You can interacto with qri.cloud or with your local qri node via HTTP requests',
84+
items: [
85+
'/docs/reference/qri-http-api/json-api-spec'
86+
]
87+
},
88+
{
89+
title: 'Starlark Libraries',
90+
path: '/docs/reference/starlark-libraries',
91+
description: 'These packages extend Starlark\'s core functionality, and can turbo-charge your Qri transform scripts',
92+
items: [
93+
'/docs/reference/starlark-libraries/overview',
94+
'/docs/reference/starlark-libraries/bsoup',
95+
{
96+
title: 'compress',
97+
path: '/docs/reference/starlark-libraries/compress',
98+
description: 'A set of Starlark packages for various types of compression/decompression',
99+
items: [
100+
'/docs/reference/starlark-libraries/compress/gzip'
101+
]
102+
},
103+
{
104+
title: 'encoding',
105+
path: '/docs/reference/starlark-libraries/encoding',
106+
description: 'A set of Starlark packages for various types of encoding/decoding',
107+
items: [
108+
'/docs/reference/starlark-libraries/encoding/base64',
109+
'/docs/reference/starlark-libraries/encoding/csv',
110+
'/docs/reference/starlark-libraries/encoding/json',
111+
'/docs/reference/starlark-libraries/encoding/yaml'
112+
]
113+
},
114+
'/docs/reference/starlark-libraries/geo',
115+
'/docs/reference/starlark-libraries/hash',
116+
'/docs/reference/starlark-libraries/html',
117+
'/docs/reference/starlark-libraries/http',
118+
'/docs/reference/starlark-libraries/math',
119+
'/docs/reference/starlark-libraries/re',
120+
'/docs/reference/starlark-libraries/time',
121+
'/docs/reference/starlark-libraries/xlsx',
122+
'/docs/reference/starlark-libraries/zipfile'
123+
]
124+
}
125+
]
35126
}
36127
// {
37128
// id: 'transform-snippets',
@@ -78,8 +169,8 @@ const config = {
78169
],
79170
docsLinks: [
80171
...docsSections.map((d) => ({
81-
text: d.text,
82-
link: d.link,
172+
text: d.title,
173+
link: d.path,
83174
colorClass: d.colorClass
84175
})),
85176
{

gatsby-node.js

+28-13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ const fetch = require('node-fetch')
33
const startCase = require('lodash.startcase')
44
const webpack = require('webpack')
55

6+
const config = require('./config')
7+
68
// [ fromPath, toPath ]
79
const redirects = [
810
['/odw2021', 'https://us02web.zoom.us/meeting/register/tZwuf-mvqjojGNfpfgJmRTH1KQ3uC3kniOBE'],
@@ -60,9 +62,8 @@ exports.createPages = ({ graphql, actions }) => {
6062
site {
6163
siteMetadata {
6264
docsSections {
63-
text
64-
link
65-
subtitle
65+
title
66+
path
6667
description
6768
colorClass
6869
}
@@ -101,16 +102,31 @@ exports.createPages = ({ graphql, actions }) => {
101102
})
102103
})
103104

104-
// create the top-level docs section pages
105-
result.data.site.siteMetadata.docsSections.forEach((docsSectionInfo) => {
106-
createPage({
107-
path: docsSectionInfo.link,
108-
component: path.resolve('./src/layouts/DocsSectionLandingPageLayout.js'),
109-
context: {
110-
filePathRegex: '\/'.concat(docsSectionInfo.link).concat('\/') // eslint-disable-line
105+
let colorClass = ''
106+
107+
const createDocsSectionPages = (sections) => {
108+
sections.forEach((d) => {
109+
// save the top level colorClass to pass to section pages
110+
if (d.colorClass) {
111+
colorClass = d.colorClass
112+
}
113+
if (d.items) {
114+
createPage({
115+
path: d.path,
116+
component: path.resolve('./src/layouts/DocsSectionLandingPageLayout.js'),
117+
context: {
118+
sectionInfo: d,
119+
colorClass
120+
}
121+
})
122+
123+
createDocsSectionPages(d.items)
111124
}
112125
})
113-
})
126+
}
127+
128+
// create the docs section pages
129+
createDocsSectionPages(config.docsSections)
114130
})
115131
)
116132
})
@@ -184,8 +200,7 @@ exports.onCreateNode = ({ node, getNode, actions }) => {
184200
createNodeField({
185201
name: 'slug',
186202
node,
187-
// trim leading number and hyphen from filename
188-
value: `/${value.replace(/\d{2}-/, '')}`
203+
value: `/${value}`
189204
})
190205

191206
createNodeField({

readme.md

+4-8
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,13 @@ Things such as the site title, navbar links, docs group ordering, etc are all co
2828

2929
Documentation pages can be added by creating markdown files in the `/docs` directory. Directories in `/docs` become groups, and each documentation article must belong to a group.
3030

31-
### Ordering Groups
31+
### Docs Article Ordering
3232

33-
Group ordering is config-driven using `config.sidebar.forcedNavOrder`
33+
Ordering and Grouping of Docs are driven by `docsSections` in `config.js`. This array includes the full hierarchy used in the docs table of contents (left sidebar). Entries can either be a path to a markdown file (equivalent to that article's url) or an object with `title`, `path`, `description`, and `items` defining a group. The sidebar items will be displayed in whatever order the strings or objects appear in the array.
3434

35-
### Grouping Documentation Articles
35+
Groups need a `path` because we auto-generate an index page for groups, and they are clickable in the sidebar.
3636

37-
Articles can be grouped by adding them to a directory. The directory name will be used for the title unless a markdown file with the same name as the directory exists at the same level as the directory (in this case, the `metaTitle` frontmatter will be used.)
38-
39-
### Ordering Documentation Articles
40-
41-
Docs articles will be displayed in the table of contents in filename order. You can prepend a number like `01-overview.md` to coerce the ordering.
37+
Gatsby will create a page for every markdown file it finds, but only articles included in `docsSections` will show up in the sidebar.
4238

4339
There is a frontmatter item `weight` which used to be used for ordering but is now deprecated
4440

src/components/CustomIcon.js

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ const CustomIcon = ({
99
}) => {
1010
let dimension = 22
1111

12+
if (size === '4xs') {
13+
dimension = 8
14+
}
15+
1216
if (size === '3xs') {
1317
dimension = 10
1418
}

src/components/DocsCard.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import classNames from 'classnames'
44
import Link from './Link'
55
import Icon from './Icon'
66

7-
const DocsCard = ({ docsSectionInfo, title, description, url, titlePrefix = '' }) => {
7+
const DocsCard = ({ title, description, url, titlePrefix = '', colorClass }) => {
88
const titleContent = titlePrefix ? `${titlePrefix} - ${title}` : title
99
return (
1010
<Link
@@ -16,7 +16,7 @@ const DocsCard = ({ docsSectionInfo, title, description, url, titlePrefix = '' }
1616
className='rounded-lg border-solid border border-qrigray-100 box-border px-4 py-3 flex h-32'
1717
>
1818
<div className="flex-shrink-0">
19-
<Icon icon='docsRing' size='3xs' className={classNames('mb-1 mr-2.5', docsSectionInfo.colorClass)} />
19+
<Icon icon='docsRing' size='3xs' className={classNames('mb-1 mr-2.5', colorClass)} />
2020
</div>
2121
<div className="flex-grow flex flex-col">
2222
<div className='font-bold text-sm text-black mb-2'>{titleContent}</div>

src/components/DocsCards.js

+11-16
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,20 @@ import React from 'react'
22

33
import DocsCard from './DocsCard'
44

5-
const DocsCards = ({ docsSectionInfo, items, titlePrefix = '' }) => {
5+
const DocsCards = ({ title, description, items, colorClass }) => {
66
return (
7-
<>
8-
{items.map(({ url, title, description, items: childItems }) => {
9-
if (childItems.length) {
10-
return <DocsCards docsSectionInfo={docsSectionInfo} items={childItems} titlePrefix={title} />
11-
}
12-
return (
7+
<div>
8+
<div className='mt-6 mb-5 font-semibold text-qrigray-400 text-xs uppercase'>{title}</div>
9+
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'>
10+
{items?.map((d) => (
1311
<DocsCard
14-
key={title}
15-
docsSectionInfo={docsSectionInfo}
16-
title={title}
17-
description={description}
18-
url={url}
19-
titlePrefix={titlePrefix}
12+
key={d.title}
13+
colorClass={colorClass}
14+
{...d}
2015
/>
21-
)
22-
})}
23-
</>
16+
))}
17+
</div>
18+
</div>
2419
)
2520
}
2621

src/components/DocsSectionLandingPage.js

+15-13
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,26 @@ import DocsContentWide from './DocsContentWide'
55
import { calculateTreeData } from './sidebar/tree'
66
import DocsCards from './DocsCards'
77

8-
const DocsSectionLandingPage = ({ docsSectionInfo, allMdx }) => {
9-
const tree = calculateTreeData(allMdx.edges)
10-
const groups = tree.items[0].items[0].items
8+
const DocsSectionLandingPage = ({ docsSectionInfo, allMdx, colorClass }) => {
9+
const tree = calculateTreeData(docsSectionInfo.items, allMdx.edges)
10+
11+
const topLevelItems = tree.filter(d => !d.items)
12+
const groups = tree.filter(d => d.items)
1113

1214
return (
1315
<DocsContentWide>
1416
{ docsSectionInfo && (
1517
<div className='text-qrigray-600 font-light'>
16-
<div className={classNames('font-black text-3xl mb-6', docsSectionInfo.colorClass)}>{docsSectionInfo.text}</div>
17-
<div className={classNames('mb-4 text-sm')}>{docsSectionInfo.description}</div>
18-
{groups.map(({ label, items, title }) => (
19-
<div className='' key={label}>
20-
<div className='mt-6 mb-5 font-semibold text-qrigray-400 text-xs'>{title}</div>
21-
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'>
22-
<DocsCards docsSectionInfo={docsSectionInfo} items={items} />
23-
</div>
24-
</div>
25-
))}
18+
<div className={classNames('font-black text-3xl mb-6', colorClass)}>{docsSectionInfo.title}</div>
19+
<div className={classNames('mb-4 text-sm text-qrigray-700')}>{docsSectionInfo.description}</div>
20+
{
21+
topLevelItems && <DocsCards items={topLevelItems} colorClass={colorClass} />
22+
}
23+
{
24+
groups.map((d) => (
25+
<DocsCards key={d} {...d} colorClass={colorClass} />
26+
))
27+
}
2628
</div>
2729
)}
2830
</DocsContentWide>

src/components/ExpansionArrow.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react'
2+
import classNames from 'classnames'
3+
4+
import IconButton from './IconButton'
5+
6+
const ExpansionArrow = ({ expanded = false, size = 'xs', onClick }) => (
7+
<div
8+
onClick={onClick}
9+
className={classNames('inline-block transform transition-all', {
10+
'rotate-90': expanded
11+
})}>
12+
<IconButton icon='caretRight' size={size} />
13+
</div>
14+
)
15+
16+
export default ExpansionArrow

src/components/RightSidebar.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const RightSidebar = ({ location }) => (
6060
<div className='border-l border-qrigray-200 hidden lg:block flex-grow' style={{
6161
minWidth: 160
6262
}}>
63-
<div className='sticky overflow-y-scroll' style={{
63+
<div className='hide-scrollbars sticky overflow-y-scroll' style={{
6464
height: 'calc(100vh - 75px)',
6565
top: 75
6666
}}>

src/components/search/SearchModal.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,8 @@ const SearchModal = ({ onClose }) => {
5959
site {
6060
siteMetadata {
6161
docsSections {
62-
id
63-
text
64-
link
65-
subtitle
62+
title
63+
path
6664
description
6765
colorClass
6866
}

0 commit comments

Comments
 (0)