mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-04 23:44:11 +02:00
chore: rename docs to resources
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import React, { useState } from "react"
|
||||
import Tree from "react-treeview"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
import useBuildTree from "./useBuildTree"
|
||||
import * as SC from "./styles"
|
||||
|
||||
export interface IFile {
|
||||
title: string
|
||||
type: "file"
|
||||
path: string
|
||||
}
|
||||
|
||||
export interface IFolder {
|
||||
title: string
|
||||
type: "folder"
|
||||
path: string
|
||||
children: IFileOrFolder[]
|
||||
}
|
||||
|
||||
export type IFileOrFolder = IFile | IFolder
|
||||
|
||||
export interface IFileQuery {
|
||||
node: {
|
||||
relativePath: string
|
||||
childMarkdownRemark: {
|
||||
frontmatter: {
|
||||
author: string
|
||||
date: string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface IAllResourcesQuery {
|
||||
allFile: {
|
||||
edges: IFileQuery[]
|
||||
}
|
||||
}
|
||||
|
||||
const ALL_RESOURCES = graphql`
|
||||
query {
|
||||
allFile(filter: { sourceInstanceName: { eq: "resources" } }) {
|
||||
edges {
|
||||
node {
|
||||
relativePath
|
||||
childMarkdownRemark {
|
||||
frontmatter {
|
||||
authors
|
||||
title
|
||||
date
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
function plantTree(item: IFileOrFolder) {
|
||||
if (item.type === "file") {
|
||||
return (
|
||||
<SC.PageLink to={item.path} activeClassName="active">
|
||||
{item.title}
|
||||
</SC.PageLink>
|
||||
)
|
||||
}
|
||||
|
||||
return <Folder item={item} />
|
||||
}
|
||||
|
||||
function Folder({ item }: { item: IFolder }) {
|
||||
const [collapsed, setCollapse] = useState(false)
|
||||
|
||||
function toggleCollapse() {
|
||||
setCollapse(prevState => !prevState)
|
||||
}
|
||||
|
||||
return (
|
||||
<Tree
|
||||
collapsed={collapsed}
|
||||
nodeLabel={<div onClick={toggleCollapse}>{item.title}</div>}
|
||||
>
|
||||
{item.children.map(plantTree)}
|
||||
</Tree>
|
||||
)
|
||||
}
|
||||
|
||||
export function ResourcesSidebar() {
|
||||
const resources = useStaticQuery<IAllResourcesQuery>(ALL_RESOURCES)
|
||||
const tree = useBuildTree(resources)
|
||||
|
||||
return (
|
||||
<SC.ResourcesSidebarWrapper>
|
||||
{tree.map(node => plantTree(node))}
|
||||
</SC.ResourcesSidebarWrapper>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import styled from "styled-components"
|
||||
import { Link } from "gatsby"
|
||||
|
||||
export const ResourcesSidebarWrapper = 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;
|
||||
|
||||
&.active {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,92 @@
|
||||
import partition from "ramda/es/partition"
|
||||
import chain from "ramda/es/chain"
|
||||
|
||||
import {
|
||||
IFileOrFolder,
|
||||
IFile,
|
||||
IFolder,
|
||||
IAllResourcesQuery,
|
||||
IFileQuery,
|
||||
} from "./index"
|
||||
|
||||
function traverse(
|
||||
[head, ...tail]: string[],
|
||||
basePath = "/resources"
|
||||
): IFileOrFolder {
|
||||
const path = basePath + "/" + head
|
||||
const isFile = !tail.length
|
||||
if (isFile) {
|
||||
// probably not more than one dot
|
||||
const [name] = head.split(".")
|
||||
return {
|
||||
title: name,
|
||||
type: "file",
|
||||
path,
|
||||
}
|
||||
}
|
||||
return {
|
||||
title: head,
|
||||
type: "folder",
|
||||
path,
|
||||
children: [traverse(tail, path)],
|
||||
}
|
||||
}
|
||||
|
||||
function generateFolder({
|
||||
title,
|
||||
path,
|
||||
targets,
|
||||
}: {
|
||||
title: IFolder["title"]
|
||||
path: IFile["path"]
|
||||
targets: IFolder[]
|
||||
}): IFolder {
|
||||
const children = join(chain(target => target.children, targets))
|
||||
|
||||
return {
|
||||
title,
|
||||
type: "folder",
|
||||
path,
|
||||
children,
|
||||
}
|
||||
}
|
||||
|
||||
function generateFile({
|
||||
title,
|
||||
path,
|
||||
}: {
|
||||
title: IFile["title"]
|
||||
path: IFile["path"]
|
||||
}): IFile {
|
||||
return {
|
||||
title,
|
||||
type: "file",
|
||||
path,
|
||||
}
|
||||
}
|
||||
|
||||
function join([head, ...tail]: IFileOrFolder[]): IFileOrFolder[] {
|
||||
if (!head) return []
|
||||
|
||||
const [similarFs, remaining] = partition(
|
||||
obj => obj.title === head.title && obj.type === head.type,
|
||||
tail
|
||||
)
|
||||
const targets = [head, ...similarFs]
|
||||
const { title, path } = head
|
||||
|
||||
const current =
|
||||
head.type === "folder"
|
||||
? generateFolder({ title, path, targets: targets as IFolder[] })
|
||||
: generateFile({ title, path })
|
||||
|
||||
return [current, ...join(remaining)]
|
||||
}
|
||||
|
||||
export default function useBuildTree(resources: IAllResourcesQuery) {
|
||||
const objects = resources.allFile.edges.map(({ node: file }: IFileQuery) =>
|
||||
traverse(file.relativePath.split("/"))
|
||||
)
|
||||
|
||||
return join(objects)
|
||||
}
|
||||
Reference in New Issue
Block a user