Skip to content

Commit

Permalink
feat(menu): adds collapsable drop-downs (#11)
Browse files Browse the repository at this point in the history
* refactor(sidebars): refactors sidebars to be more modular and easier to work with
* feat(toc): adds collapsable chapters
  • Loading branch information
claymcleod committed Feb 6, 2021
1 parent cb297f6 commit 2f330e4
Show file tree
Hide file tree
Showing 10 changed files with 342 additions and 153 deletions.
5 changes: 3 additions & 2 deletions src/components/docs/doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class BaseLayout extends Component {
title: currentTitle,
chapters: currentChapters,
} = currentModule
const CurrentIconImported = require("../../images/icons/" + currentIcon)
const currentIconImported = require("../../images/icons/" + currentIcon)

const flattenedChapters = []
currentChapters.forEach(chapter => {
Expand Down Expand Up @@ -127,7 +127,7 @@ class BaseLayout extends Component {
isMobileMenuOpen={this.state.isMobileMenuOpen}
openMobileMenu={this.openMobileMenu}
closeMobileMenu={this.closeMobileMenu}
CurrentIconImported={CurrentIconImported}
currentIconImported={currentIconImported}
currentTitle={currentTitle}
domains={domains}
currentChapters={currentChapters}
Expand Down Expand Up @@ -210,6 +210,7 @@ export const pageQuery = graphql`
subtitle
chapters {
title
collapsable
pages {
title
path
Expand Down
126 changes: 0 additions & 126 deletions src/components/docs/sidebars/ContentSidebarLeft.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React from "react"
import PropTypes from "prop-types"
import Question from "../../../images/icons/question.svg"
import Tour from "../../../images/icons/tour.svg"
import Question from "../../../../images/icons/question.svg"
import Tour from "../../../../images/icons/tour.svg"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faGithub } from "@fortawesome/free-brands-svg-icons"
import { toast } from "react-toastify"
import Button from "../../buttons/Button"
import Button from "../../../buttons/Button"

function callIntercom(action, args = null) {
if (window && window.Intercom) {
// both of these are checked against as the first boolean in the conditional
// eslint-disable-next-line no-undef
if (typeof window !== "undefined" && window.Intercom) {
// eslint-disable-next-line no-undef
window.Intercom(action, args)
} else {
toast.error(
Expand All @@ -35,6 +38,22 @@ function playTour() {
}

function editOnGitHub(fileAbsolutePath) {
if (typeof window === "undefined") {
toast.error(
"Looks like Intercom isn't enabled in this environment! Please email us at support@stjude.cloud with this error so we can fix it!",
{
position: "top-center",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
}
)
return
}

const token = "/docs/"
if (!fileAbsolutePath.includes(token)) {
throw new Error(`File path not in docs?`)
Expand All @@ -46,6 +65,8 @@ function editOnGitHub(fileAbsolutePath) {
let url =
"https://github.com/stjudecloud/university/edit/master/docs/" +
relativeFilePath
// Handled cases where window is not defined at the beginning of this function
// eslint-disable-next-line no-undef
window.open(url)
}
}
Expand Down
64 changes: 64 additions & 0 deletions src/components/docs/sidebars/content-sidebar-left/chapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { useState } from "react"
import { Link } from "gatsby"
import Chevron from "../../../../images/icons/chevron.svg"

function renderPages(pages, currentPathBeingViewed) {
let renderedPages = []
let isCurrentPathInChapter = false

for (let i = 0; i < pages.length; i++) {
const page = pages[i]
if (page.path === currentPathBeingViewed) {
isCurrentPathInChapter = true
}

renderedPages.push(
<li
key={page.path}
className={
(currentPathBeingViewed === page.path ? "active " : "") + "page"
}
>
<Link to={page.path}>{page.title}</Link>
</li>
)
}
return { renderedPages, isCurrentPathInChapter }
}

const ChapterMenuItem = ({
chapter: { title, pages, collapsable },
currentPathBeingViewed,
}) => {
const { renderedPages, isCurrentPathInChapter } = renderPages(
pages,
currentPathBeingViewed
)
const [isCollapsableMenuOpen, setIsCollapsableMenuOpen] = useState(
isCurrentPathInChapter
)

return (
<ul className="chapter" key={title}>
<li
className={`title${collapsable ? " cursor-pointer" : ""}`}
onClick={() => {
setIsCollapsableMenuOpen(!isCollapsableMenuOpen)
}}
>
{title}
{collapsable && (
<Chevron
className="collapsable-menu-chevron"
height="12"
width="12"
style={isCollapsableMenuOpen ? { rotate: "90deg" } : null}
/>
)}
</li>
{(!collapsable || isCollapsableMenuOpen) && renderedPages}
</ul>
)
}

export default ChapterMenuItem
90 changes: 90 additions & 0 deletions src/components/docs/sidebars/content-sidebar-left/content-menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from "react"
import { Link } from "gatsby"
import CloseIcon from "../../../../images/icons/close.svg"
import Chevron from "../../../../images/icons/chevron.svg"
import ChapterMenuItem from "./chapter"

const ContentsMenu = ({
isMobileMenuOpen,
closeMobileMenu,
CurrentIconImported,
currentTitle,
currentChapters,
currentPathBeingViewed,
setIsModuleSelectorMousedOver,
}) => {
return (
<div
id="contents-sidebar-left"
className={
(isMobileMenuOpen ? "" : "invisible ") +
"xl:visible z-30 contents-sidebar fixed bg-coolGray-50 min-h-screen border-r border-coolGray-100 border-solid w-full xl:w-320"
}
>
<div id="mobile-menu-button" className="absolute inset-0">
<div
className="xl:hidden pointer-cursor my-4 mx-4"
onClick={closeMobileMenu}
>
<CloseIcon
width="24"
height="24"
className="fill-current text-coolGray-500 inline-block"
/>
<span className="ml-2">Close</span>
</div>
<div
id="module-selector"
className="h-28"
role="link"
tabIndex={0}
onMouseEnter={() => {
if (!isMobileMenuOpen) setIsModuleSelectorMousedOver(true)
}}
onMouseLeave={() => {
if (!isMobileMenuOpen) setIsModuleSelectorMousedOver(false)
}}
onClick={() => {
setIsModuleSelectorMousedOver(true)
}}
>
<div className="flex w-full items-center justify-center bg-coolGray-100 hover:bg-coolGray-200 h-28 px-4 cursor-pointer border-b border-coolGray-200">
<div className="w-full flex items-center justify-center">
<CurrentIconImported
className="mr-2"
width="40px"
height="40px"
/>
<span
className="font-semibold text-coolGray-700 whitespace-nowrap"
style={{ fontSize: "18px" }}
>
{currentTitle}
</span>
<Chevron
className="ml-2 fill-current text-coolGray-500"
width="16px"
height="16px"
/>
</div>
</div>
</div>
<div className="absolute inset-x-0">
<div className="h-screen overflow-y-scroll">
<div className="my-2 mx-3 pb-60">
{currentChapters.map(e => (
<ChapterMenuItem
key={e.title}
chapter={e}
currentPathBeingViewed={currentPathBeingViewed}
/>
))}
</div>
</div>
</div>
</div>
</div>
)
}

export default ContentsMenu

1 comment on commit 2f330e4

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.