ui: basic style the docs & link to pages

This commit is contained in:
Jean-Philippe Sirois
2019-07-27 15:52:25 -04:00
parent 7b8740f5e0
commit 94e9aecf0e
6 changed files with 70 additions and 24 deletions
+2 -2
View File
@@ -26,7 +26,7 @@ const DocsLayout = ({ children }: PropsWithChildren<{}>) => {
`) `)
return ( return (
<Scrollbar> <div>
<Main> <Main>
<DocsSidebar /> <DocsSidebar />
<MainContent> <MainContent>
@@ -39,7 +39,7 @@ const DocsLayout = ({ children }: PropsWithChildren<{}>) => {
{` `} {` `}
<a href="https://www.gatsbyjs.org">Gatsby</a> <a href="https://www.gatsbyjs.org">Gatsby</a>
</footer> </footer>
</Scrollbar> </div>
) )
} }
+1 -1
View File
@@ -7,7 +7,7 @@ export const Main = styled.div`
` `
export const MainContent = styled.main` export const MainContent = styled.main`
flex: 1 0 auto; flex: 1 1 auto;
& > :first-child { & > :first-child {
margin-top: 0; margin-top: 0;
+47 -15
View File
@@ -1,26 +1,29 @@
import * as R from "ramda" import * as R from "ramda"
import React from "react" import React, { useState } from "react"
import Tree from "react-treeview" import Tree from "react-treeview"
import { useStaticQuery, graphql } from "gatsby" import { useStaticQuery, graphql } from "gatsby"
import * as SC from "./styles"
export interface DocsSidebarProps {
readonly width: string | number
}
interface IFile { interface IFile {
title: string title: string
type: "file" type: "file"
path: string
} }
interface IFolder { interface IFolder {
title: string title: string
type: "folder" type: "folder"
path: string
children: IFileOrFolder[] children: IFileOrFolder[]
} }
type IFileOrFolder = IFile | IFolder type IFileOrFolder = IFile | IFolder
const traverse = ([head, ...tail]: string[]): IFileOrFolder => { const traverse = (
[head, ...tail]: string[],
basePath = "/docs"
): IFileOrFolder => {
const path = basePath + "/" + head
const isFile = !tail.length const isFile = !tail.length
if (isFile) { if (isFile) {
// probably not more than one dot // probably not more than one dot
@@ -28,20 +31,24 @@ const traverse = ([head, ...tail]: string[]): IFileOrFolder => {
return { return {
title: name, title: name,
type: "file", type: "file",
path,
} }
} }
return { return {
title: head, title: head,
type: "folder", type: "folder",
children: [traverse(tail)], path,
children: [traverse(tail, path)],
} }
} }
const generateFolder = ({ const generateFolder = ({
title, title,
path,
targets, targets,
}: { }: {
title: IFolder["title"] title: IFolder["title"]
path: IFile["path"]
targets: IFolder[] targets: IFolder[]
}): IFolder => { }): IFolder => {
const children = join(R.chain(target => target.children, targets)) const children = join(R.chain(target => target.children, targets))
@@ -49,13 +56,21 @@ const generateFolder = ({
return { return {
title, title,
type: "folder", type: "folder",
path,
children, children,
} }
} }
const generateFile = ({ title }: { title: IFile["title"] }): IFile => { const generateFile = ({
title,
path,
}: {
title: IFile["title"]
path: IFile["path"]
}): IFile => {
return { return {
title, title,
path,
type: "file", type: "file",
} }
} }
@@ -68,12 +83,12 @@ const join = ([head, ...tail]: IFileOrFolder[]): IFileOrFolder[] => {
tail tail
) )
const targets = [head, ...similarFs] const targets = [head, ...similarFs]
const { title } = head const { title, path } = head
const current = const current =
head.type === "folder" head.type === "folder"
? generateFolder({ title, targets: targets as IFolder[] }) ? generateFolder({ title, path, targets: targets as IFolder[] })
: generateFile({ title }) : generateFile({ title, path })
return [current, ...join(remaining)] return [current, ...join(remaining)]
} }
@@ -116,17 +131,30 @@ const ALL_DOCS = graphql`
const plantTree = (item: IFileOrFolder) => { const plantTree = (item: IFileOrFolder) => {
if (item.type === "file") { if (item.type === "file") {
return <div>{item.title}</div> return <SC.PageLink to={item.path}>{item.title}</SC.PageLink>
}
return <Folder item={item} />
}
function Folder({ item }: { item: IFolder }) {
const [collapsed, setCollapse] = useState(false)
function toggleCollapse() {
setCollapse(prevState => !prevState)
} }
return ( return (
<Tree nodeLabel={<div>{item.title}</div>}> <Tree
collapsed={collapsed}
nodeLabel={<div onClick={toggleCollapse}>{item.title}</div>}
>
{item.children.map(plantTree)} {item.children.map(plantTree)}
</Tree> </Tree>
) )
} }
const DocsSidebar = ({ width }: DocsSidebarProps) => { const DocsSidebar = () => {
const docs = useStaticQuery<IAllDocsQuery>(ALL_DOCS) const docs = useStaticQuery<IAllDocsQuery>(ALL_DOCS)
const objects = docs.allFile.edges.map(({ node: file }: IFileQuery) => const objects = docs.allFile.edges.map(({ node: file }: IFileQuery) =>
@@ -136,7 +164,11 @@ const DocsSidebar = ({ width }: DocsSidebarProps) => {
console.log(results) console.log(results)
return <div style={{ width }}>{results.map(node => plantTree(node))}</div> return (
<SC.DocsSidebarWrapper>
{results.map(node => plantTree(node))}
</SC.DocsSidebarWrapper>
)
} }
export default DocsSidebar export default DocsSidebar
-6
View File
@@ -1,6 +0,0 @@
import styled from "styled-components"
export const DocsSidebarScroller = styled.div`
display: flex;
flex-direction: column;
`
+14
View File
@@ -0,0 +1,14 @@
import styled from "styled-components"
import { Link } from "gatsby"
export const DocsSidebarWrapper = styled.div`
box-sizing: border-box;
padding: 0 16px;
flex: 0 0 300px;
`
export const PageLink = styled(Link)`
display: block;
padding: 4px 0;
color: #1c61df;
`
+6
View File
@@ -47,6 +47,12 @@ body {
.tree-view_item { .tree-view_item {
display: flex; display: flex;
cursor: pointer;
}
.tree-view_item,
.tree-view_children > div {
padding: 4px 0;
} }
/* style for the children nodes container */ /* style for the children nodes container */