diff --git a/package-lock.json b/package-lock.json index 20f77ea..9b1622e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1745,6 +1745,11 @@ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==" }, + "@types/ramda": { + "version": "0.26.18", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.26.18.tgz", + "integrity": "sha512-wK3NLaAkL/ht7Nw4IZsOagJuYqzZgoboFvILolOPtmoKyy25gTdz/uvB/bXsv6vdWENYv+ml5ph873P2d/+9HA==" + }, "@types/reach__router": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.2.4.tgz", @@ -13774,9 +13779,9 @@ "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" }, "ramda": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz", - "integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU=" + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz", + "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==" }, "randombytes": { "version": "2.1.0", @@ -16270,6 +16275,11 @@ "json5": "^0.5.0" } }, + "ramda": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz", + "integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU=" + }, "xml2js": { "version": "0.4.17", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", diff --git a/package.json b/package.json index 2fe6ad3..26ddca5 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "version": "0.1.0", "author": "TPH", "dependencies": { + "@types/ramda": "^0.26.18", "axios": "^0.19.0", "babel-plugin-styled-components": "^1.10.6", "gatsby": "^2.13.39", @@ -26,6 +27,7 @@ "highlight.js": "^9.15.8", "node-sass": "^4.12.0", "prismjs": "^1.17.1", + "ramda": "^0.26.1", "react": "^16.8.6", "react-dom": "^16.8.6", "react-helmet": "^5.2.1", diff --git a/src/components/Docs/Sidebar/index.tsx b/src/components/Docs/Sidebar/index.tsx deleted file mode 100644 index 4769aac..0000000 --- a/src/components/Docs/Sidebar/index.tsx +++ /dev/null @@ -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 ( -
- "Javascript"
} - > - "Javascript"} - > - Test - - - - ) -} - -export default Sidebar; \ No newline at end of file diff --git a/src/components/Docs/Sidebar/style.tsx b/src/components/Docs/Sidebar/style.tsx deleted file mode 100644 index 0ba5a63..0000000 --- a/src/components/Docs/Sidebar/style.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import styled from "styled-components"; - -export const SidebarScroller = styled.div` - display: flex; - flex-direction: column; -` \ No newline at end of file diff --git a/src/components/Docs/SidebarSection/index.tsx b/src/components/Docs/SidebarSection/index.tsx deleted file mode 100644 index 6786ace..0000000 --- a/src/components/Docs/SidebarSection/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react"; -import { SidebarTitle } from "./style"; - -export interface SidebarSectionProps { - readonly title: string; -} - -const SidebarSection = ({ title, children }: React.PropsWithChildren) => { - return ( -
- {title} - {children} -
- ) -} - -export default SidebarSection; \ No newline at end of file diff --git a/src/components/Docs/index.ts b/src/components/Docs/index.ts deleted file mode 100644 index 3564e0a..0000000 --- a/src/components/Docs/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Sidebar } from "./Sidebar"; \ No newline at end of file diff --git a/src/components/DocsLayout/index.tsx b/src/components/DocsLayout/index.tsx new file mode 100644 index 0000000..6d09c2f --- /dev/null +++ b/src/components/DocsLayout/index.tsx @@ -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 ( + +
+ + +

{data.site.siteMetadata.title}

+ {children} +
+
+
+ © {new Date().getFullYear()}, Built with + {` `} + Gatsby +
+
+ ) +} + +export default DocsLayout diff --git a/src/components/DocsLayout/layout.scss b/src/components/DocsLayout/layout.scss new file mode 100644 index 0000000..e033dcd --- /dev/null +++ b/src/components/DocsLayout/layout.scss @@ -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; +} diff --git a/src/components/DocsLayout/styles.tsx b/src/components/DocsLayout/styles.tsx new file mode 100644 index 0000000..5bc63b3 --- /dev/null +++ b/src/components/DocsLayout/styles.tsx @@ -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; + } +` diff --git a/src/components/DocsSidebar/index.tsx b/src/components/DocsSidebar/index.tsx new file mode 100644 index 0000000..caabcbf --- /dev/null +++ b/src/components/DocsSidebar/index.tsx @@ -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
{item.title}
+ } + + return ( + {item.title}}> + {item.children.map(plantTree)} + + ) +} + +const DocsSidebar = ({ width }: DocsSidebarProps) => { + const docs = useStaticQuery(ALL_DOCS) + + const objects = docs.allFile.edges.map(({ node: file }: IFileQuery) => + traverse(file.relativePath.split("/")) + ) + const results = join(objects) + + console.log(results) + + return
{results.map(node => plantTree(node))}
+} + +export default DocsSidebar diff --git a/src/components/DocsSidebar/style.tsx b/src/components/DocsSidebar/style.tsx new file mode 100644 index 0000000..8b67f01 --- /dev/null +++ b/src/components/DocsSidebar/style.tsx @@ -0,0 +1,6 @@ +import styled from "styled-components" + +export const DocsSidebarScroller = styled.div` + display: flex; + flex-direction: column; +` diff --git a/src/components/DocsSidebarSection/index.tsx b/src/components/DocsSidebarSection/index.tsx new file mode 100644 index 0000000..e04e899 --- /dev/null +++ b/src/components/DocsSidebarSection/index.tsx @@ -0,0 +1,20 @@ +import React from "react" +import { SidebarTitle } from "./style" + +export interface DocsSidebarSectionProps { + readonly title: string +} + +const DocsSidebarSection = ({ + title, + children, +}: React.PropsWithChildren) => { + return ( +
+ {title} + {children} +
+ ) +} + +export default DocsSidebarSection diff --git a/src/components/Docs/SidebarSection/style.tsx b/src/components/DocsSidebarSection/style.tsx similarity index 100% rename from src/components/Docs/SidebarSection/style.tsx rename to src/components/DocsSidebarSection/style.tsx diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index bfe4f70..68d9645 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -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 diff --git a/src/components/Layout/layout.scss b/src/components/Layout/layout.scss index 5b224f1..f73f5dd 100644 --- a/src/components/Layout/layout.scss +++ b/src/components/Layout/layout.scss @@ -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); +} diff --git a/src/templates/languagePost.tsx b/src/templates/languagePost.tsx index 7611b9c..a0c94b8 100644 --- a/src/templates/languagePost.tsx +++ b/src/templates/languagePost.tsx @@ -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 ( - + -
- + ) } -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 {