feat: Update to API references look and feel (#343)

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: olivermrbl <oliver@mrbltech.com>
This commit is contained in:
Kasper Fabricius Kristensen
2021-08-20 10:26:29 +02:00
committed by GitHub
parent 40400b483c
commit 143f06aa39
85 changed files with 19022 additions and 7116 deletions
@@ -0,0 +1,109 @@
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"
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"
sx={{
height: "28px",
}}
/>
</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
@@ -0,0 +1,54 @@
import React from "react"
import { Flex, Box, Text } from "theme-ui"
const CodeBox = ({ header, children }) => {
return (
<Box
sx={{
background: "fadedContrast",
borderRadius: "small",
boxShadow: "0 0 0 1px rgb(0 0 0 / 7%)",
alignSelf: "flex-start",
marginLeft: "auto",
marginRight: "auto",
width: "100%",
mb: "4",
}}
>
<Box
sx={{
bg: "faded",
p: "8px 10px",
letterSpacing: "0.01em",
borderRadius: "8px 8px 0 0",
}}
>
<Text variant="small" sx={{ fontWeight: "400" }}>
{header}
</Text>
</Box>
<Box
sx={{
position: "relative",
boxSizing: "content-box",
maxHeight: "calc(90vh - 20px)",
minHeight: "10px",
}}
>
<Flex
sx={{
flexDirection: "column",
position: "relative",
minHeight: "inherit",
maxHeight: "inherit",
overflowY: "auto",
}}
>
{children}
</Flex>
</Box>
</Box>
)
}
export default CodeBox
@@ -0,0 +1,130 @@
import React, { useState } from "react"
import Collapsible from "react-collapsible"
import { Flex, Box, Text, Heading } from "theme-ui"
import Markdown from "react-markdown"
import Description from "./description"
const NestedCollapsible = ({ properties, title }) => {
const [isOpen, setIsOpen] = useState(false)
return (
<Box
mt={2}
sx={{
"& .child-attrs": {
cursor: "pointer",
fontSize: "12px",
p: "6px 10px",
boxSizing: "border-box",
width: "max-content",
borderRadius: "small",
border: "1px solid",
borderColor: "faded",
},
"& .child-attrs.is-open": {
width: "100%",
borderBottom: "none",
borderBottomLeftRadius: "0",
borderBottomRightRadius: "0",
},
}}
>
<Collapsible
transitionTime={50}
triggerClassName={"child-attrs"}
triggerOpenedClassName={"child-attrs"}
triggerTagName="div"
trigger={
<Flex
sx={{
alignItems: "baseline",
fontSize: "13px",
fontWeight: "400",
}}
>
<Box
mr={1}
className={isOpen ? "rotated" : null}
sx={{
userSelect: "none",
transition: "all 0.2s ease",
transform: "rotate(45deg)",
"&.rotated": {
transform: "rotate(0deg)",
},
}}
>
&times;
</Box>{" "}
<Text
sx={{ fontSize: "0", fontFamily: "body", userSelect: "none" }}
>{`${isOpen ? "Hide" : "Show"} child attributes`}</Text>
</Flex>
}
onTriggerOpening={() => setIsOpen(true)}
onTriggerClosing={() => setIsOpen(false)}
>
<Box
sx={{
padding: "2",
borderRadius: "small",
borderTopLeftRadius: 0,
borderTopRightRadius: 0,
border: "hairline",
borderColor: "faded",
}}
mb="2"
>
<Heading as="h3" p={2} sx={{ fontFamily: "body", fontWeight: "500" }}>
{title}
</Heading>
{properties.map((param, i) => {
return (
<Box
p={2}
sx={{
borderTop: "hairline",
}}
key={i}
>
<Flex
sx={{
fontSize: "0",
alignItems: "baseline",
pb: "1",
fontFamily: "monospace",
}}
>
<Box mr={2} fontSize={"12px"}>
{param.property}
</Box>
<Text color={"gray"} fontSize={"10px"}>
{param.type}
</Text>
{param.required && (
<Text ml={1} fontSize={"10px"} variant="labels.required">
required
</Text>
)}
</Flex>
<Description>
<Text
sx={{
fontSize: "0",
lineHeight: "26px",
fontFamily: "body",
}}
>
<Markdown>{param.description}</Markdown>
</Text>
</Description>
</Box>
)
})}
</Box>
</Collapsible>
</Box>
)
}
export default NestedCollapsible
@@ -0,0 +1,20 @@
import React from "react"
import { Box } from "theme-ui"
const Description = ({ children }) => {
return (
<Box
sx={{
code: {
backgroundColor: "faded",
borderRadius: "4px",
p: "3px",
},
}}
>
{children}
</Box>
)
}
export default Description
@@ -0,0 +1,45 @@
import React from "react"
import { Flex, Text } from "theme-ui"
import CodeBox from "./code-box"
const EndpointContainer = ({ endpoints }) => {
if (!endpoints) return null
return (
<CodeBox header="ENDPOINTS">
<Flex
py={2}
sx={{
flexDirection: "column",
}}
>
{endpoints.map((e, i) => {
const method = e.method.toUpperCase()
const endpoint = e.endpoint
return (
<Flex
key={i}
sx={{ fontSize: "0", fontFamily: "monospace", px: "3", py: "2" }}
>
<Text
variant={`labels.${method}`}
sx={{
width: "55px",
textAlign: "right",
}}
mr={2}
>
{method}
</Text>
<Text sx={{ color: "dark" }}>
{endpoint.replace(/{(.*?)}/g, ":$1")}
</Text>
</Flex>
)
})}
</Flex>
</CodeBox>
)
}
export default EndpointContainer
@@ -0,0 +1,31 @@
import React from "react"
import { Box, Flex } from "theme-ui"
import Topbar from "../topbar"
import Section from "./section"
const Content = ({ data, api }) => {
return (
<Flex
sx={{
flexDirection: "column",
}}
>
<Topbar data={data} api={api} />
<Box
sx={{
maxHeight: "calc(100vh - 50px)",
overflowY: "scroll",
"@media screen and (max-width: 848px)": {
mt: "50px",
},
}}
>
{data.sections.map((s, i) => {
return <Section key={i} data={s} />
})}
</Box>
</Flex>
)
}
export default Content
@@ -0,0 +1,31 @@
import React, { useRef, useEffect } from "react"
import { Box } from "theme-ui"
import "../../prism-medusa-theme/prism.css"
import Prism from "prismjs"
import "prismjs/components/prism-json"
import CodeBox from "./code-box"
const JsonContainer = ({ json, header }) => {
const jsonRef = useRef()
//INVESTIGATE: @theme-ui/prism might be a better solution
useEffect(() => {
if (jsonRef.current) {
Prism.highlightAllUnder(jsonRef.current)
}
}, [])
if (typeof json !== "string" || json === "{}") return null
return (
<Box ref={jsonRef} sx={{ position: "sticky", top: "20px" }}>
<CodeBox header={header}>
<pre>
<code className={"language-json"}>{json}</code>
</pre>
</CodeBox>
</Box>
)
}
export default JsonContainer
@@ -0,0 +1,110 @@
import React, { useContext, useEffect, useRef } from "react"
import Markdown from "react-markdown"
import { Flex, Text, Box, Heading } from "theme-ui"
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
import Parameters from "./parameters"
import Route from "./route"
import JsonContainer from "./json-container"
import Description from "./description"
import ResponsiveContainer from "./responsive-container"
import { formatMethodParams } from "../../utils/format-parameters"
import useInView from "../../hooks/use-in-view"
import NavigationContext from "../../context/navigation-context"
const Method = ({ data, section, pathname }) => {
const { parameters, requestBody, description, method, summary } = data
const jsonResponse = data.responses[0].content?.[0].json
const { updateHash, updateMetadata } = useContext(NavigationContext)
const methodRef = useRef(null)
const [containerRef, isInView] = useInView({
root: null,
rootMargin: "0px 0px -80% 0px",
threshold: 0,
})
useEffect(() => {
if (isInView) {
updateHash(section, convertToKebabCase(summary))
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isInView])
const handleMetaChange = () => {
updateMetadata({
title: summary,
description: description,
})
if (methodRef.current) {
methodRef.current.scrollIntoView({
behavior: "smooth",
})
}
}
return (
<Flex
py={"5vw"}
sx={{
borderTop: "hairline",
flexDirection: "column",
}}
id={convertToKebabCase(summary)}
ref={methodRef}
>
<Flex>
<Heading
as="h2"
mb={4}
sx={{
fontSize: "4",
fontWeight: "500",
cursor: "pointer",
}}
ref={containerRef}
onClick={() => handleMetaChange()}
>
{summary}
</Heading>
</Flex>
<ResponsiveContainer>
<Flex
className="info"
sx={{
flexDirection: "column",
pr: "5",
"@media screen and (max-width: 848px)": {
pr: "0",
},
}}
>
<Route path={pathname} method={method} />
<Description>
<Text
sx={{
lineHeight: "26px",
}}
mt={3}
>
<Markdown>{description}</Markdown>
</Text>
</Description>
<Box mt={4}>
<Parameters
params={formatMethodParams({ parameters, requestBody })}
/>
</Box>
</Flex>
<Box className="code">
<JsonContainer
json={jsonResponse}
header={"RESPONSE"}
method={convertToKebabCase(summary)}
/>
</Box>
</ResponsiveContainer>
</Flex>
)
}
export default Method
@@ -0,0 +1,68 @@
import React from "react"
import { Flex, Text, Box } from "theme-ui"
import Markdown from "react-markdown"
import NestedCollapsible from "./collapsible"
import Description from "./description"
const Parameters = ({ params, type }) => {
return (
<Flex
sx={{
flexDirection: "column",
}}
>
<Text pb="2">{type === "attr" ? "Attributes" : "Parameters"}</Text>
{params.properties.length > 0 ? (
params.properties.map((prop, i) => {
const nested = prop.nestedModel || prop.items?.properties || null
return (
<Box
py={2}
sx={{
borderTop: "hairline",
fontFamily: "monospace",
fontSize: "0",
}}
key={i}
>
<Flex sx={{ alignItems: "baseline", fontSize: "0" }}>
<Text mr={2}>{prop.property || prop.name}</Text>
<Text color={"gray"}>
{prop.type || prop.schema?.type || nested?.title}
</Text>
{prop.required ? (
<Text ml={1} variant="labels.required">
required
</Text>
) : null}
</Flex>
<Description>
<Text
sx={{
fontSize: "0",
lineHeight: "26px",
fontFamily: "body",
}}
>
<Markdown>{prop.description}</Markdown>
</Text>
</Description>
{nested?.properties && (
<NestedCollapsible
properties={nested.properties}
title={nested.title}
/>
)}
</Box>
)
})
) : (
<Text sx={{ fontSize: "0", py: "3", fontFamily: "monospace" }}>
No parameters
</Text>
)}
</Flex>
)
}
export default Parameters
@@ -0,0 +1,29 @@
import React from "react"
import styled from "@emotion/styled"
import { Flex } from "theme-ui"
const ResponsiveFlex = styled(Flex)`
.info {
width: 55%;
}
.code {
width: 45%;
}
@media screen and (max-width: 848px) {
flex-direction: column;
align-items: center;
.info,
.code {
width: 100%;
}
}
`
const ResponsiveContainer = ({ children }) => {
return <ResponsiveFlex>{children}</ResponsiveFlex>
}
export default ResponsiveContainer
@@ -0,0 +1,17 @@
import React from "react"
import { Flex, Text } from "theme-ui"
import { formatRoute } from "../../utils/format-route"
const Route = ({ method, path }) => {
const fixedMethod = method.toUpperCase()
return (
<Flex sx={{ fontFamily: "monospace" }}>
<Text variant={`labels.${fixedMethod}`} mr={1}>
{fixedMethod}
</Text>
<Text>{formatRoute(path)}</Text>
</Flex>
)
}
export default Route
@@ -0,0 +1,205 @@
import React, { useState, useRef, useEffect, useContext } from "react"
import { Flex, Box, Heading, Text, Button } from "theme-ui"
import Method from "./method"
import Parameters from "./parameters"
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
import EndpointContainer from "./endpoint-container"
import Markdown from "react-markdown"
import JsonContainer from "./json-container"
import ResponsiveContainer from "./responsive-container"
import Description from "./description"
import NavigationContext from "../../context/navigation-context"
import ChevronDown from "../icons/chevron-down"
import useInView from "../../hooks/use-in-view"
const Section = ({ data }) => {
const { section } = data
const [isExpanded, setIsExpanded] = useState(false)
const { openSections, updateSection, updateMetadata } = useContext(
NavigationContext
)
const endpoints = section.paths
.map(p => {
let path = p.name
let ep = []
p.methods.forEach(m => {
ep.push({ method: m.method, endpoint: path })
})
return ep
})
.flat()
const sectionRef = useRef(null)
const scrollIntoView = () => {
if (sectionRef.current) {
sectionRef.current.scrollIntoView({
behavior: "smooth",
})
}
}
const handleExpand = () => {
updateMetadata({
title: section.section_name,
description: section.schema?.description,
})
setIsExpanded(true)
scrollIntoView()
}
useEffect(() => {
if (isExpanded) {
scrollIntoView()
}
}, [isExpanded])
useEffect(() => {
const shouldOpen = openSections.includes(
convertToKebabCase(section.section_name)
)
if (shouldOpen) {
setIsExpanded(true)
}
}, [section.section_name, openSections, openSections.length])
const [containerRef, isInView] = useInView({
root: null,
rootMargin: "0px 0px -80% 0px",
threshold: 1.0,
})
useEffect(() => {
const handleInView = () => {
if (isInView) {
updateSection(convertToKebabCase(section.section_name))
}
}
handleInView()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isInView])
return (
<section ref={sectionRef} id={convertToKebabCase(section.section_name)}>
<Box
sx={{
borderBottom: "hairline",
padding: "5vw",
backgroundColor: isExpanded ? "transparent" : "fadedContrast",
}}
>
<Flex>
<Heading
as="h1"
sx={{
fontWeight: "500",
fontSize: "22",
mb: "3",
cursor: "pointer",
}}
ref={containerRef}
className={`header-${convertToKebabCase(section.section_name)}`}
onClick={handleExpand}
>
{section.section_name}
</Heading>
</Flex>
<Flex
sx={{
flexDirection: "column",
}}
>
<ResponsiveContainer>
<Flex
sx={{
flexDirection: "column",
lineHeight: "26px",
pr: "5",
"@media screen and (max-width: 848px)": {
pr: "0",
},
}}
className="info"
>
<Description>
<Text mb={4}>
<Markdown>{section.schema?.description}</Markdown>
</Text>
</Description>
{isExpanded && section.schema ? (
<Parameters params={section.schema} type={"attr"} />
) : null}
</Flex>
<Flex
className="code"
sx={{
flexDirection: "column",
}}
>
<EndpointContainer endpoints={endpoints} />
{isExpanded ? (
<JsonContainer
json={section.schema?.object}
header={`${section.section_name.toUpperCase()} OBJECT`}
/>
) : null}
</Flex>
</ResponsiveContainer>
{isExpanded ? (
<Box mt={4}>
{section.paths.map((p, i) => {
return (
<Flex
key={i}
sx={{
flexDirection: "column",
}}
>
{p.methods.map((m, i) => {
return (
<Method
key={i}
data={m}
section={convertToKebabCase(section.section_name)}
pathname={p.name}
/>
)
})}
</Flex>
)
})}
</Box>
) : (
<Flex
sx={{
justifyContent: "center",
alignItems: "center",
width: "100%",
}}
mt={4}
>
<Button
onClick={handleExpand}
sx={{
display: "flex",
alignItems: "center",
borderRadius: "24px",
bg: "light",
fontWeight: "500",
}}
>
SHOW <ChevronDown fill={"dark"} styles={{ mr: "-10px" }} />
</Button>
</Flex>
)}
</Flex>
</Box>
</section>
)
}
export default Section
@@ -0,0 +1,24 @@
import React from "react"
import { Box } from "theme-ui"
const ChevronDown = ({ fill = "darkContrast", styles }) => {
return (
<Box
as="svg"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
sx={{
...styles,
alignSelf: "center",
pointerEvents: "none",
fill: `${fill}`,
}}
>
<path d="M7.41 7.84l4.59 4.58 4.59-4.58 1.41 1.41-6 6-6-6z" />
</Box>
)
}
export default ChevronDown
@@ -0,0 +1,18 @@
import { Image } from "@theme-ui/components"
import React from "react"
import Logo from "../../assets/github.svg"
const GitHub = () => {
return (
<Image
src={Logo}
sx={{
height: "20px",
fill: "#000",
}}
/>
)
}
export default GitHub
+26
View File
@@ -0,0 +1,26 @@
import React from "react"
import { Flex, Box } from "theme-ui"
import Sidebar from "./sidebar"
const Layout = ({ data, api, children }) => {
return (
<Flex sx={{ p: "0", m: "0", overflow: "hidden" }}>
<Flex
sx={{
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
fontFamily: "body",
flexGrow: "1",
}}
>
<Sidebar data={data} api={api} />
<Box>{children}</Box>
</Flex>
</Flex>
)
}
export default Layout
+115
View File
@@ -0,0 +1,115 @@
import { Flex, Box, Link, Select } from "@theme-ui/components"
import React, { useContext } from "react"
import { navigate } from "gatsby-link"
import GitHub from "../components/icons/github"
import NavigationContext from "../context/navigation-context"
import { convertToKebabCase } from "../utils/convert-to-kebab-case"
import ChevronDown from "./icons/chevron-down"
const Topbar = ({ data, api }) => {
const { goTo, reset, currentSection } = useContext(NavigationContext)
const handleChange = e => {
const parts = e.target.value.split(" ")
if (parts[0] === api) {
goTo({ section: parts[1] })
} else {
reset()
navigate(`/api/${api === "admin" ? "store" : "admin"}`)
}
}
return (
<Flex
sx={{
justifyContent: "space-between",
alignItems: "center",
width: "100%",
px: "5vw",
height: "headerHeight",
boxShadow: "topbarShadow",
"@media screen and (max-width: 848px)": {
position: "fixed",
top: "0",
left: "0",
right: "0",
zIndex: "9999",
backgroundColor: "light",
},
}}
>
<Box>
<Box
sx={{
display: "none",
alignItems: "center",
"@media screen and (max-width: 848px)": {
display: "block",
},
}}
>
<Select
arrow={<ChevronDown fill={"dark"} />}
sx={{
border: "none",
width: "100%",
fontSize: "2",
fontFamily: "body",
fontWeight: "500",
flexGrow: "1",
px: "0",
transition: "all .1s ease-in-out",
"&:focus": {
outline: "none !important",
},
}}
onChange={handleChange}
value={`${api} ${currentSection}`}
>
<optgroup label={`${api.slice(0, 1).toUpperCase()}${api.slice(1)}`}>
{data.sections.map((s, i) => {
return (
<option
key={i}
value={`${api} ${convertToKebabCase(
s.section.section_name
)}`}
>
{s.section.section_name}
</option>
)
})}
</optgroup>
<optgroup label={api === "admin" ? "Store" : "Admin"}>
<option>{`Go to ${
api === "admin" ? "Storefront API" : "Admin API"
}`}</option>
</optgroup>
</Select>
</Box>
</Box>
<Flex
sx={{
alignItems: "center",
}}
>
<Link variant="topbar" mr={3} href="https://docs.medusa-commerce.com">
Docs
</Link>
<Link
sx={{
pt: "4px",
}}
variant="topbar"
href="https://github.com/medusajs/medusa"
>
<GitHub />
</Link>
</Flex>
</Flex>
)
}
export default Topbar