mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-04 01:05:58 +02:00
Merge pull request #58 from the-programmers-hangout/feat-resources-breadcrumbs
feat(resources): implement breadcrumbs
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import React from "react"
|
||||
|
||||
import { IFileOrFolder } from "../ResourcesSidebar/index"
|
||||
import ChevronUp from "../../icons/chevron-up.svg"
|
||||
import { traversePaths } from "../../utils"
|
||||
import * as SC from "./styles"
|
||||
|
||||
interface ResourceBreadcrumbProps {
|
||||
relativePath: any
|
||||
}
|
||||
|
||||
function Link({ item }: { item: IFileOrFolder }) {
|
||||
return <SC.StyledLink to={item.path}>{item.title}</SC.StyledLink>
|
||||
}
|
||||
|
||||
function flatten([
|
||||
currNode,
|
||||
...previousNodes
|
||||
]: IFileOrFolder[]): IFileOrFolder[] {
|
||||
if (currNode.type === "file") {
|
||||
return [...previousNodes, currNode]
|
||||
}
|
||||
|
||||
return flatten([...currNode.children, ...previousNodes, currNode])
|
||||
}
|
||||
|
||||
export function ResourceBreadcrumb({ relativePath }: ResourceBreadcrumbProps) {
|
||||
const paths = relativePath.split("/")
|
||||
const breadcrumbItems = flatten([traversePaths(paths)])
|
||||
|
||||
return (
|
||||
<SC.ResourceBreadcrumbWrapper>
|
||||
{breadcrumbItems.map(item => {
|
||||
if (item.type === "folder") {
|
||||
return (
|
||||
<SC.LinkWrapper>
|
||||
<Link item={item} />
|
||||
<ChevronUp />
|
||||
</SC.LinkWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
return <SC.CurrentPage>{item.title}</SC.CurrentPage>
|
||||
})}
|
||||
</SC.ResourceBreadcrumbWrapper>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import styled from "styled-components"
|
||||
import { Link } from "gatsby"
|
||||
|
||||
export const ResourceBreadcrumbWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
`
|
||||
|
||||
export const LinkWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
|
||||
svg {
|
||||
width: 12px;
|
||||
transform: rotate(90deg);
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
svg path {
|
||||
fill: #04b0a6;
|
||||
}
|
||||
`
|
||||
|
||||
export const StyledLink = styled(Link)`
|
||||
color: #04b0a6;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #045551;
|
||||
}
|
||||
`
|
||||
|
||||
export const CurrentPage = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
`
|
||||
@@ -2,9 +2,11 @@ import React, { Fragment } from "react"
|
||||
|
||||
import { StackedAvatars } from "../StackedAvatars"
|
||||
import ChevronUp from "../../icons/chevron-up.svg"
|
||||
import { ResourceBreadcrumb } from "../ResourceBreadcrumb"
|
||||
import * as SC from "./styles"
|
||||
|
||||
interface ResourceHeaderProps {
|
||||
relativePath: any
|
||||
title: any
|
||||
authors: any
|
||||
createdAt: any
|
||||
@@ -42,6 +44,7 @@ function ExtraLink({
|
||||
}
|
||||
|
||||
export function ResourceHeader({
|
||||
relativePath,
|
||||
title,
|
||||
authors,
|
||||
createdAt,
|
||||
@@ -57,6 +60,8 @@ export function ResourceHeader({
|
||||
|
||||
return (
|
||||
<SC.ResourceHeaderWrapper>
|
||||
<ResourceBreadcrumb relativePath={relativePath} />
|
||||
|
||||
<SC.Title>{title}</SC.Title>
|
||||
|
||||
<SC.Top>
|
||||
|
||||
@@ -18,6 +18,7 @@ export const Title = styled.h1`
|
||||
font-size: ${modularScale(6).fontSize}px;
|
||||
line-height: ${modularScale(6).lineHeight}px;
|
||||
letter-spacing: -1.75px;
|
||||
margin-top: 0;
|
||||
`
|
||||
|
||||
export const Meta = styled.div`
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import partition from "ramda/es/partition"
|
||||
import chain from "ramda/es/chain"
|
||||
|
||||
import { traversePaths } from "../../utils"
|
||||
import {
|
||||
IFileOrFolder,
|
||||
IFile,
|
||||
@@ -9,29 +10,6 @@ import {
|
||||
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,
|
||||
@@ -85,7 +63,7 @@ function join([head, ...tail]: IFileOrFolder[]): IFileOrFolder[] {
|
||||
|
||||
export default function useBuildTree(resources: IAllResourcesQuery) {
|
||||
const objects = resources.allFile.edges.map(({ node: file }: IFileQuery) =>
|
||||
traverse(file.relativePath.split("/"))
|
||||
traversePaths(file.relativePath.split("/"))
|
||||
)
|
||||
|
||||
return join(objects)
|
||||
|
||||
@@ -6,12 +6,14 @@ import { ResourceHeader } from "../components/ResourceHeader"
|
||||
|
||||
// @todo maybe find alternative type for data
|
||||
function LanguagePost({ data }: any) {
|
||||
const { relativePath } = data.file
|
||||
const { html, fields, frontmatter, timeToRead } = data.file.post
|
||||
console.log(data)
|
||||
return (
|
||||
<Fragment>
|
||||
<SEO title={frontmatter.title} />
|
||||
<ResourceHeader
|
||||
relativePath={relativePath}
|
||||
title={frontmatter.title}
|
||||
authors={fields.authors}
|
||||
createdAt={frontmatter.created_at}
|
||||
@@ -29,6 +31,7 @@ export default LanguagePost
|
||||
export const query = graphql`
|
||||
query LanguagePost($file: String!) {
|
||||
file(relativePath: { eq: $file }) {
|
||||
relativePath
|
||||
post: childMarkdownRemark {
|
||||
html
|
||||
fields {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { IFileOrFolder } from "../components/ResourcesSidebar/index"
|
||||
|
||||
export function traversePaths(
|
||||
[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: [traversePaths(tail, path)],
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user