From 021a1d4aa2a39f3caf1eca3c2aaf21c8213969f0 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Sirois Date: Tue, 30 Jul 2019 06:44:57 -0400 Subject: [PATCH] feat: implement collapsable first level tree --- src/SidebarProvider.tsx | 35 +++++++++++++++++++++++ src/components/ResourcesLayout/index.tsx | 5 ++-- src/components/ResourcesSidebar/index.tsx | 35 +++++++++++++++++++---- src/hooks/useSidebar.tsx | 12 ++++++++ 4 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 src/SidebarProvider.tsx create mode 100644 src/hooks/useSidebar.tsx diff --git a/src/SidebarProvider.tsx b/src/SidebarProvider.tsx new file mode 100644 index 0000000..c30a2dd --- /dev/null +++ b/src/SidebarProvider.tsx @@ -0,0 +1,35 @@ +import React, { useState } from "react" + +interface SidebarProviderProps { + children: React.ReactNode +} + +export interface SidebarContextInterface { + current: number + setCurrent: (index: number) => void +} + +export const SidebarContext = React.createContext( + null +) + +export function SidebarProvider({ + children, +}: SidebarProviderProps): JSX.Element { + const [current, setCurrent] = useState(0) + + function selectFirstLevel(index: number) { + setCurrent(index) + } + + return ( + + {children} + + ) +} diff --git a/src/components/ResourcesLayout/index.tsx b/src/components/ResourcesLayout/index.tsx index 08af008..dda7b7b 100644 --- a/src/components/ResourcesLayout/index.tsx +++ b/src/components/ResourcesLayout/index.tsx @@ -11,6 +11,7 @@ import { useStaticQuery, graphql } from "gatsby" import { GlobalStyles } from "../../globalStyles" import { ResourcesSidebar } from "../ResourcesSidebar" import * as SC from "./styles" +import { SidebarProvider } from "../../SidebarProvider" export function ResourcesLayout({ children }: PropsWithChildren<{}>) { const data = useStaticQuery(graphql` @@ -24,7 +25,7 @@ export function ResourcesLayout({ children }: PropsWithChildren<{}>) { `) return ( -
+ @@ -35,6 +36,6 @@ export function ResourcesLayout({ children }: PropsWithChildren<{}>) { -
+ ) } diff --git a/src/components/ResourcesSidebar/index.tsx b/src/components/ResourcesSidebar/index.tsx index b56a513..e2affd9 100644 --- a/src/components/ResourcesSidebar/index.tsx +++ b/src/components/ResourcesSidebar/index.tsx @@ -2,6 +2,7 @@ import React, { useState } from "react" import Tree from "react-treeview" import { useStaticQuery, graphql } from "gatsby" import useBuildTree from "./useBuildTree" +import useSidebar from "./../../hooks/useSidebar" import banner from "../../images/tph-banner.png" import * as SC from "./styles" @@ -57,20 +58,24 @@ const ALL_RESOURCES = graphql` } ` -function plantTree(item: IFileOrFolder) { +function plantTree(item: IFileOrFolder, index?: number, firstLevel?: boolean) { if (item.type === "file") { return ( - + {item.title} ) } - return + if (firstLevel && index !== undefined) { + return + } + + return } function Folder({ item }: { item: IFolder }) { - const [collapsed, setCollapse] = useState(false) + const [collapsed, setCollapse] = useState(true) function toggleCollapse() { setCollapse(prevState => !prevState) @@ -82,7 +87,23 @@ function Folder({ item }: { item: IFolder }) { collapsed={collapsed} nodeLabel={
{item.title}
} > - {item.children.map(plantTree)} + {item.children.map(node => plantTree(node))} + + + ) +} + +function FirstLevelFolder({ item, index }: { item: IFolder; index: number }) { + const { current, setCurrent } = useSidebar() + const collapsed = current !== index + + return ( + + setCurrent(index)}>{item.title}} + > + {item.children.map(node => plantTree(node))} ) @@ -95,7 +116,9 @@ export function ResourcesSidebar() { return ( - {tree.map(node => plantTree(node))} + + {tree.map((node, index) => plantTree(node, index, true))} + ) } diff --git a/src/hooks/useSidebar.tsx b/src/hooks/useSidebar.tsx new file mode 100644 index 0000000..ab3a4b4 --- /dev/null +++ b/src/hooks/useSidebar.tsx @@ -0,0 +1,12 @@ +import { useContext } from "react" +import { SidebarContext, SidebarContextInterface } from "../SidebarProvider" + +export default function useSidebar(): SidebarContextInterface { + const sidebarContext = useContext(SidebarContext) + + if (!sidebarContext) { + throw Error("Need context") + } + + return sidebarContext +}