mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-06 16:06:12 +02:00
feat: bootstrap docs layout & sidebar
This commit is contained in:
Generated
+13
-3
@@ -1745,6 +1745,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
|
||||||
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw=="
|
"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": {
|
"@types/reach__router": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.2.4.tgz",
|
||||||
@@ -13774,9 +13779,9 @@
|
|||||||
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
|
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
|
||||||
},
|
},
|
||||||
"ramda": {
|
"ramda": {
|
||||||
"version": "0.21.0",
|
"version": "0.26.1",
|
||||||
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz",
|
||||||
"integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU="
|
"integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ=="
|
||||||
},
|
},
|
||||||
"randombytes": {
|
"randombytes": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
@@ -16270,6 +16275,11 @@
|
|||||||
"json5": "^0.5.0"
|
"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": {
|
"xml2js": {
|
||||||
"version": "0.4.17",
|
"version": "0.4.17",
|
||||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
|
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"author": "TPH",
|
"author": "TPH",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/ramda": "^0.26.18",
|
||||||
"axios": "^0.19.0",
|
"axios": "^0.19.0",
|
||||||
"babel-plugin-styled-components": "^1.10.6",
|
"babel-plugin-styled-components": "^1.10.6",
|
||||||
"gatsby": "^2.13.39",
|
"gatsby": "^2.13.39",
|
||||||
@@ -26,6 +27,7 @@
|
|||||||
"highlight.js": "^9.15.8",
|
"highlight.js": "^9.15.8",
|
||||||
"node-sass": "^4.12.0",
|
"node-sass": "^4.12.0",
|
||||||
"prismjs": "^1.17.1",
|
"prismjs": "^1.17.1",
|
||||||
|
"ramda": "^0.26.1",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6",
|
"react-dom": "^16.8.6",
|
||||||
"react-helmet": "^5.2.1",
|
"react-helmet": "^5.2.1",
|
||||||
|
|||||||
@@ -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;
|
|
||||||
@@ -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 +0,0 @@
|
|||||||
export { default as Sidebar } from "./Sidebar";
|
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
`
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -18,7 +18,7 @@ import "react-perfect-scrollbar/dist/css/styles.css"
|
|||||||
|
|
||||||
const Layout = ({ children }: PropsWithChildren<{}>) => {
|
const Layout = ({ children }: PropsWithChildren<{}>) => {
|
||||||
const data = useStaticQuery(graphql`
|
const data = useStaticQuery(graphql`
|
||||||
query SiteTitleQuery {
|
query {
|
||||||
site {
|
site {
|
||||||
siteMetadata {
|
siteMetadata {
|
||||||
title
|
title
|
||||||
|
|||||||
@@ -38,3 +38,44 @@ body {
|
|||||||
padding-left: 2.8em;
|
padding-left: 2.8em;
|
||||||
overflow: initial;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,27 +1,25 @@
|
|||||||
import React from "react";
|
import React from "react"
|
||||||
import { graphql } from "gatsby";
|
import { graphql } from "gatsby"
|
||||||
import SEO from "../components/SEO";
|
import SEO from "../components/SEO"
|
||||||
import Layout from "../components/Layout";
|
import DocsLayout from "../components/DocsLayout"
|
||||||
import { Sidebar } from "../components/Docs";
|
|
||||||
|
|
||||||
// @todo maybe find alternative type for data
|
// @todo maybe find alternative type for data
|
||||||
const LanguagePost = ({ data }: any) => {
|
const LanguagePost = ({ data }: any) => {
|
||||||
const { html, frontmatter } = data.file.post;
|
const { html, frontmatter } = data.file.post
|
||||||
console.log(data)
|
console.log(data)
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<DocsLayout>
|
||||||
<SEO title={frontmatter.title} />
|
<SEO title={frontmatter.title} />
|
||||||
<Sidebar />
|
|
||||||
<div dangerouslySetInnerHTML={{ __html: html }} />
|
<div dangerouslySetInnerHTML={{ __html: html }} />
|
||||||
</Layout >
|
</DocsLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LanguagePost;
|
export default LanguagePost
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query LanguagePost($file: String!) {
|
query LanguagePost($file: String!) {
|
||||||
file(relativePath: {eq: $file }) {
|
file(relativePath: { eq: $file }) {
|
||||||
post: childMarkdownRemark {
|
post: childMarkdownRemark {
|
||||||
html
|
html
|
||||||
frontmatter {
|
frontmatter {
|
||||||
|
|||||||
Reference in New Issue
Block a user