feat: Documentation and API reference (#348)
Co-authored-by: Vadim Smirnov <smirnou.vadzim@gmail.com> Co-authored-by: zakariasaad <zakaria.elas@gmail.com> Co-authored-by: Vilfred Sikker <vilfredsikker@gmail.com> Co-authored-by: Kasper <kasper@medusa-commerce.com> Co-authored-by: Sebastian Rindom <skrindom@gmail.com> Co-authored-by: Kasper Fabricius Kristensen <45367945+kasperkristensen@users.noreply.github.com>
This commit is contained in:
co-authored by
Vadim Smirnov
zakariasaad
Vilfred Sikker
Kasper
Sebastian Rindom
Kasper Fabricius Kristensen
parent
5d63b0c8d2
commit
f76aa816a5
@@ -0,0 +1,111 @@
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { Flex, Image, Box } from "theme-ui"
|
||||
import styled from "@emotion/styled"
|
||||
import Logo from "../../assets/logo.svg"
|
||||
import LogoMuted from "../../assets/logo-muted.svg"
|
||||
import SideBarItem from "./sidebar-item"
|
||||
import SideBarSelector from "./sidebar-selector"
|
||||
import { navigate } from "gatsby"
|
||||
|
||||
const SideBarContainer = styled(Flex)`
|
||||
--side-bar-width: 220px;
|
||||
|
||||
@media screen and (min-width: 1680px) {
|
||||
--side-bar-width: 280px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 848px) {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
|
||||
const SideBarFade = styled(Box)`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: calc(var(--side-bar-width) - 1px);
|
||||
height: 50px;
|
||||
pointer-events: none;
|
||||
box-shadow: inset 0 50px 25px calc(-1 * 25px) white;
|
||||
`
|
||||
|
||||
const Sidebar = ({ data, api }) => {
|
||||
const [scrollPos, setScrollPos] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
const nav = document.querySelector("#nav")
|
||||
|
||||
const handleScroll = e => {
|
||||
const pos = e.srcElement.scrollTop / 50
|
||||
if (pos < 1) {
|
||||
setScrollPos(pos)
|
||||
}
|
||||
}
|
||||
nav.addEventListener("scroll", handleScroll)
|
||||
return () => nav.removeEventListener("scroll", handleScroll)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<SideBarContainer
|
||||
sx={{
|
||||
position: "sticky",
|
||||
top: "0",
|
||||
bottom: "0",
|
||||
height: "100vh",
|
||||
backgroundColor: "light",
|
||||
boxShadow: "sidebarShadow",
|
||||
minWidth: "var(--side-bar-width)",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
sx={{
|
||||
px: "4",
|
||||
pt: "3",
|
||||
background: "light",
|
||||
width: "calc(var(--side-bar-width) - 1px)",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Flex>
|
||||
<Image
|
||||
src={Logo}
|
||||
alt="Medusa logo"
|
||||
onClick={() => navigate("/")}
|
||||
sx={{
|
||||
height: "32px",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex py={4}>
|
||||
<SideBarSelector api={api} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex
|
||||
id="nav"
|
||||
sx={{
|
||||
flex: 1,
|
||||
position: "relative",
|
||||
px: "3",
|
||||
pb: "3",
|
||||
mr: "1px",
|
||||
flexDirection: "column",
|
||||
overflowY: "scroll",
|
||||
pr: "6px",
|
||||
scrollbarColor: "faded light",
|
||||
}}
|
||||
>
|
||||
<SideBarFade opacity={scrollPos} />
|
||||
{data.sections.map((s, i) => {
|
||||
return <SideBarItem item={s} key={i} />
|
||||
})}
|
||||
</Flex>
|
||||
<Flex sx={{ py: 4, px: 4, borderTop: "1px solid #efefef" }}>
|
||||
<Image src={LogoMuted} alt="Medusa Type" sx={{ height: "10px" }} />
|
||||
</Flex>
|
||||
</SideBarContainer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Sidebar
|
||||
@@ -0,0 +1,138 @@
|
||||
import React, { useContext } from "react"
|
||||
import Collapsible from "react-collapsible"
|
||||
import { Flex, Box, Text } from "theme-ui"
|
||||
import styled from "@emotion/styled"
|
||||
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
|
||||
import ChevronDown from "../icons/chevron-down"
|
||||
import NavigationContext from "../../context/navigation-context"
|
||||
|
||||
const StyledCollapsible = styled(Collapsible)`
|
||||
margin-bottom: 10px;
|
||||
`
|
||||
|
||||
const Container = styled(Box)`
|
||||
div.Collapsible span.Collapsible__trigger.is-open {
|
||||
svg {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const SideBarItem = ({ item }) => {
|
||||
const {
|
||||
openSection,
|
||||
openSections,
|
||||
currentHash,
|
||||
currentSection,
|
||||
goTo,
|
||||
} = useContext(NavigationContext)
|
||||
const { section } = item
|
||||
const subItems = section.paths
|
||||
.map(p => {
|
||||
return p.methods
|
||||
})
|
||||
.reduce((pre, cur) => {
|
||||
return pre.concat(cur)
|
||||
})
|
||||
.map(m => {
|
||||
return {
|
||||
title: m.summary,
|
||||
path: convertToKebabCase(m.summary),
|
||||
}
|
||||
})
|
||||
|
||||
const handleClick = () => {
|
||||
const id = convertToKebabCase(section.section_name)
|
||||
const element = document.querySelector(`#${id}`)
|
||||
if (element) {
|
||||
element.scrollIntoView()
|
||||
if (!openSections.includes(id)) {
|
||||
openSection(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubClick = path => {
|
||||
const id = convertToKebabCase(section.section_name)
|
||||
goTo({ section: id, method: path })
|
||||
}
|
||||
|
||||
return (
|
||||
<Container id={`nav-${convertToKebabCase(section.section_name)}`}>
|
||||
<StyledCollapsible
|
||||
trigger={
|
||||
<Flex
|
||||
sx={{
|
||||
fontSize: "1",
|
||||
pl: "16px",
|
||||
pr: "10px",
|
||||
alignItems: "center",
|
||||
borderRadius: "small",
|
||||
cursor: "pointer",
|
||||
mr: "4px",
|
||||
mb: "5px",
|
||||
height: "25px",
|
||||
justifyContent: "space-between",
|
||||
"&:hover, &.active": {
|
||||
backgroundColor: "faded",
|
||||
},
|
||||
}}
|
||||
className={
|
||||
currentSection === convertToKebabCase(section.section_name)
|
||||
? "active"
|
||||
: null
|
||||
}
|
||||
>
|
||||
{section.section_name} <ChevronDown />
|
||||
</Flex>
|
||||
}
|
||||
open={
|
||||
currentSection === convertToKebabCase(section.section_name) ||
|
||||
openSections.includes(convertToKebabCase(section.section_name))
|
||||
}
|
||||
onTriggerOpening={handleClick}
|
||||
transitionTime={1}
|
||||
>
|
||||
{subItems.map((si, i) => {
|
||||
const path = convertToKebabCase(si.path)
|
||||
return (
|
||||
<Flex
|
||||
key={i}
|
||||
className={currentHash === path ? "active" : null}
|
||||
onClick={() => handleSubClick(path)}
|
||||
id={`nav-${path}`}
|
||||
sx={{
|
||||
ml: "10px",
|
||||
pl: "10px",
|
||||
pr: "10px",
|
||||
alignItems: "center",
|
||||
borderRadius: "small",
|
||||
cursor: "pointer",
|
||||
mb: "8px",
|
||||
textDecoration: "none",
|
||||
color: "black",
|
||||
height: "25px",
|
||||
"&:hover": {
|
||||
backgroundColor: "faded",
|
||||
},
|
||||
"&.active": {
|
||||
backgroundColor: "faded",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
sx={{
|
||||
fontSize: "0",
|
||||
}}
|
||||
>
|
||||
{si.title}
|
||||
</Text>
|
||||
</Flex>
|
||||
)
|
||||
})}
|
||||
</StyledCollapsible>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default SideBarItem
|
||||
@@ -0,0 +1,56 @@
|
||||
import React, { useContext } from "react"
|
||||
import { Flex, Select } from "theme-ui"
|
||||
import { navigate } from "gatsby-link"
|
||||
import NavigationContext from "../../context/navigation-context"
|
||||
import ChevronDown from "../icons/chevron-down"
|
||||
|
||||
const SideBarSelector = ({ api }) => {
|
||||
const { reset } = useContext(NavigationContext)
|
||||
|
||||
const handleSelect = e => {
|
||||
reset()
|
||||
navigate(`/api/${e.target.value}`)
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
marginLeft: "-16px",
|
||||
marginRight: "-10px",
|
||||
width: "calc(100% + 26px)",
|
||||
"& div": {
|
||||
width: "100%",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
arrow={<ChevronDown fill={"dark"} styles={{ ml: "-28px" }} />}
|
||||
sx={{
|
||||
paddingLeft: "16px",
|
||||
marginRight: "-5px",
|
||||
borderRadius: "small",
|
||||
borderColor: "faded",
|
||||
width: "100%",
|
||||
fontSize: "1",
|
||||
fontFamily: "body",
|
||||
transition: "all .1s ease-in-out",
|
||||
"&:focus": {
|
||||
outline: "none !important",
|
||||
},
|
||||
boxShadow: "ctaBoxShadow",
|
||||
|
||||
"&:hover": {
|
||||
boxShadow: "buttonBoxShadowHover",
|
||||
},
|
||||
}}
|
||||
value={api}
|
||||
onChange={handleSelect}
|
||||
>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="store">Storefront</option>
|
||||
</Select>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
export default SideBarSelector
|
||||
Reference in New Issue
Block a user