feat: bootstrap docs layout & sidebar

This commit is contained in:
Jean-Philippe Sirois
2019-07-27 15:52:25 -04:00
parent 6ef875f51f
commit 7b8740f5e0
16 changed files with 340 additions and 69 deletions
-30
View File
@@ -1,30 +0,0 @@
import React from "react";
import { SidebarScroller } from "./style";
import Tree from "react-treeview";
const makeTree = () => {
}
export interface SidebarProps {
readonly width: string | number;
}
const Sidebar = ({ width }: SidebarProps) => {
return (
<div style={{ width }}>
<Tree
nodeLabel={<div>"Javascript"</div>}
>
<Tree
nodeLabel={<div>"Javascript"</div>}
>
Test
</Tree>
</Tree>
</div>
)
}
export default Sidebar;
-6
View File
@@ -1,6 +0,0 @@
import styled from "styled-components";
export const SidebarScroller = styled.div`
display: flex;
flex-direction: column;
`
@@ -1,17 +0,0 @@
import React from "react";
import { SidebarTitle } from "./style";
export interface SidebarSectionProps {
readonly title: string;
}
const SidebarSection = ({ title, children }: React.PropsWithChildren<SidebarSectionProps>) => {
return (
<div>
<SidebarTitle>{title}</SidebarTitle>
{children}
</div>
)
}
export default SidebarSection;
-1
View File
@@ -1 +0,0 @@
export { default as Sidebar } from "./Sidebar";
+46
View File
@@ -0,0 +1,46 @@
/**
* Layout component that queries for data
* with Gatsby's useStaticQuery component
*
* See: https://www.gatsbyjs.org/docs/use-static-query/
*/
import React, { PropsWithChildren } from "react"
import { useStaticQuery, graphql } from "gatsby"
import Container from "../Container"
import DocsSidebar from "../DocsSidebar"
import { Main, MainContent } from "./styles"
import Scrollbar from "react-perfect-scrollbar"
import "react-perfect-scrollbar/dist/css/styles.css"
const DocsLayout = ({ children }: PropsWithChildren<{}>) => {
const data = useStaticQuery(graphql`
query {
site {
siteMetadata {
title
}
}
}
`)
return (
<Scrollbar>
<Main>
<DocsSidebar />
<MainContent>
<h1>{data.site.siteMetadata.title}</h1>
{children}
</MainContent>
</Main>
<footer>
© {new Date().getFullYear()}, Built with
{` `}
<a href="https://www.gatsbyjs.org">Gatsby</a>
</footer>
</Scrollbar>
)
}
export default DocsLayout
+41
View File
@@ -0,0 +1,41 @@
// TODO: refactor this into styled components
html {
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/**
* If you already use line highlighting
*/
/* Adjust the position of the line numbers */
.gatsby-highlight pre[class*="language-"].line-numbers {
padding-left: 2.8em;
}
/**
* If you only want to use line numbering
*/
.gatsby-highlight {
background-color: #fdf6e3;
border-radius: 0.3em;
margin: 0.5em 0;
padding: 1em;
overflow: auto;
}
.gatsby-highlight pre[class*="language-"].line-numbers {
padding: 0;
padding-left: 2.8em;
overflow: initial;
}
+19
View File
@@ -0,0 +1,19 @@
import styled from "styled-components"
export const Main = styled.div`
display: flex;
margin: 128px auto 64px !important;
width: 100%;
`
export const MainContent = styled.main`
flex: 1 0 auto;
& > :first-child {
margin-top: 0;
}
& > :last-child {
margin-bottom: 0;
}
`
+142
View File
@@ -0,0 +1,142 @@
import * as R from "ramda"
import React from "react"
import Tree from "react-treeview"
import { useStaticQuery, graphql } from "gatsby"
export interface DocsSidebarProps {
readonly width: string | number
}
interface IFile {
title: string
type: "file"
}
interface IFolder {
title: string
type: "folder"
children: IFileOrFolder[]
}
type IFileOrFolder = IFile | IFolder
const traverse = ([head, ...tail]: string[]): IFileOrFolder => {
const isFile = !tail.length
if (isFile) {
// probably not more than one dot
const [name] = head.split(".")
return {
title: name,
type: "file",
}
}
return {
title: head,
type: "folder",
children: [traverse(tail)],
}
}
const generateFolder = ({
title,
targets,
}: {
title: IFolder["title"]
targets: IFolder[]
}): IFolder => {
const children = join(R.chain(target => target.children, targets))
return {
title,
type: "folder",
children,
}
}
const generateFile = ({ title }: { title: IFile["title"] }): IFile => {
return {
title,
type: "file",
}
}
const join = ([head, ...tail]: IFileOrFolder[]): IFileOrFolder[] => {
if (!head) return []
const [similarFs, remaining] = R.partition(
obj => obj.title === head.title && obj.type === head.type,
tail
)
const targets = [head, ...similarFs]
const { title } = head
const current =
head.type === "folder"
? generateFolder({ title, targets: targets as IFolder[] })
: generateFile({ title })
return [current, ...join(remaining)]
}
interface IFileQuery {
node: {
relativePath: string
childMarkdownRemark: {
frontmatter: {
author: string
date: string
}
}
}
}
interface IAllDocsQuery {
allFile: {
edges: IFileQuery[]
}
}
const ALL_DOCS = graphql`
query {
allFile(filter: { sourceInstanceName: { eq: "docs" } }) {
edges {
node {
relativePath
childMarkdownRemark {
frontmatter {
author
date
}
}
}
}
}
}
`
const plantTree = (item: IFileOrFolder) => {
if (item.type === "file") {
return <div>{item.title}</div>
}
return (
<Tree nodeLabel={<div>{item.title}</div>}>
{item.children.map(plantTree)}
</Tree>
)
}
const DocsSidebar = ({ width }: DocsSidebarProps) => {
const docs = useStaticQuery<IAllDocsQuery>(ALL_DOCS)
const objects = docs.allFile.edges.map(({ node: file }: IFileQuery) =>
traverse(file.relativePath.split("/"))
)
const results = join(objects)
console.log(results)
return <div style={{ width }}>{results.map(node => plantTree(node))}</div>
}
export default DocsSidebar
+6
View File
@@ -0,0 +1,6 @@
import styled from "styled-components"
export const DocsSidebarScroller = styled.div`
display: flex;
flex-direction: column;
`
@@ -0,0 +1,20 @@
import React from "react"
import { SidebarTitle } from "./style"
export interface DocsSidebarSectionProps {
readonly title: string
}
const DocsSidebarSection = ({
title,
children,
}: React.PropsWithChildren<DocsSidebarSectionProps>) => {
return (
<div>
<SidebarTitle>{title}</SidebarTitle>
{children}
</div>
)
}
export default DocsSidebarSection
+1 -1
View File
@@ -18,7 +18,7 @@ import "react-perfect-scrollbar/dist/css/styles.css"
const Layout = ({ children }: PropsWithChildren<{}>) => {
const data = useStaticQuery(graphql`
query SiteTitleQuery {
query {
site {
siteMetadata {
title
+41
View File
@@ -38,3 +38,44 @@ body {
padding-left: 2.8em;
overflow: initial;
}
/* temp */
/* the tree node's style */
.tree-view {
overflow-y: hidden;
}
.tree-view_item {
display: flex;
}
/* style for the children nodes container */
.tree-view_children {
margin-left: 16px;
}
.tree-view_children-collapsed {
height: 0px;
}
.tree-view_arrow {
cursor: pointer;
margin-right: 6px;
display: inline-block;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.tree-view_arrow:after {
content: "";
}
/* rotate the triangle to close it */
.tree-view_arrow-collapsed {
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
transform: rotate(-90deg);
}
+9 -11
View File
@@ -1,27 +1,25 @@
import React from "react";
import { graphql } from "gatsby";
import SEO from "../components/SEO";
import Layout from "../components/Layout";
import { Sidebar } from "../components/Docs";
import React from "react"
import { graphql } from "gatsby"
import SEO from "../components/SEO"
import DocsLayout from "../components/DocsLayout"
// @todo maybe find alternative type for data
const LanguagePost = ({ data }: any) => {
const { html, frontmatter } = data.file.post;
const { html, frontmatter } = data.file.post
console.log(data)
return (
<Layout>
<DocsLayout>
<SEO title={frontmatter.title} />
<Sidebar />
<div dangerouslySetInnerHTML={{ __html: html }} />
</Layout >
</DocsLayout>
)
}
export default LanguagePost;
export default LanguagePost
export const query = graphql`
query LanguagePost($file: String!) {
file(relativePath: {eq: $file }) {
file(relativePath: { eq: $file }) {
post: childMarkdownRemark {
html
frontmatter {