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,55 @@
|
||||
import React, { useEffect, useState } from "react"
|
||||
import CloseIcon from "../close-icon"
|
||||
import styles from "./banner.module.css"
|
||||
import clsx from "clsx"
|
||||
import useThemeContext from "@theme/hooks/useThemeContext"
|
||||
import ConfLogo from "../../../static/img/logo.svg"
|
||||
|
||||
const Banner = (props) => {
|
||||
const [isBannerVisible, setIsBannerVisible] = useState(true)
|
||||
const { isDarkTheme } = useThemeContext()
|
||||
|
||||
const handleDismissBanner = () => {
|
||||
setIsBannerVisible(false)
|
||||
if (localStorage) {
|
||||
localStorage.setItem("mc::banner", false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (localStorage) {
|
||||
const shouldShow = localStorage.getItem("mc::banner")
|
||||
if (!shouldShow) {
|
||||
setIsBannerVisible(true)
|
||||
}
|
||||
|
||||
if (shouldShow === "false") {
|
||||
setIsBannerVisible(false)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
isBannerVisible && (
|
||||
<div className={clsx(styles.bannerContainer, "margin-top--lg")}>
|
||||
<div
|
||||
className={clsx(styles.banner, "padding--sm", "padding-right--md")}
|
||||
>
|
||||
<div className="padding" sx={{ marginLeft: "10px" }}>
|
||||
<ConfLogo />
|
||||
<p className="padding-left--md">
|
||||
We are still working on building out our documentation and guides,
|
||||
but if you are interested in learning more please reach out - we
|
||||
would love to jump on a call with you and help you get set up!
|
||||
</p>
|
||||
</div>
|
||||
{/* <div style={{ cursor: "pointer" }} onClick={handleDismissBanner}>
|
||||
<CloseIcon fill={isDarkTheme ? "white" : "black"} />
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export default Banner
|
||||
@@ -0,0 +1,18 @@
|
||||
.bannerContainer {
|
||||
height: 100%;
|
||||
padding: 10px 0px;
|
||||
margin-bottom: 20px;
|
||||
background-color: var(--ifm-medusa-gray);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.bannerContainer svg {
|
||||
max-width: 100px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.banner {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Banner } from "./Banner"
|
||||
@@ -0,0 +1,50 @@
|
||||
import React from "react"
|
||||
import Link from "@docusaurus/Link"
|
||||
import CodeBlock from "@theme/CodeBlock"
|
||||
import styles from "./intro.module.css"
|
||||
|
||||
const Intro = ({ title, desc }) => {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="margin-bottom--xs margin-top--lg">Documentation</h1>
|
||||
<p className={styles.title}>{title}</p>
|
||||
<h2 className="margin-top--lg margin-bottom--sm">Quickstart</h2>
|
||||
<p className={styles.description}>{desc}</p>
|
||||
<CodeBlock>
|
||||
{`yarn global add @medusajs/medusa-cli
|
||||
medusa new my-awesome-store`}
|
||||
</CodeBlock>
|
||||
<div>
|
||||
<Link
|
||||
to="quickstart/quick-start"
|
||||
className="margin-top--md margin-bottom--sm button button--lg button--primary"
|
||||
>
|
||||
Quickstart Guide →
|
||||
</Link>
|
||||
</div>
|
||||
<div className={` margin-top--md`}>
|
||||
<Link
|
||||
to="tutorial/set-up-your-development-environment"
|
||||
className={`${styles.docsLink}`}
|
||||
>
|
||||
Set up your own local environment →
|
||||
</Link>
|
||||
</div>
|
||||
<div className={`margin-top--md`}>
|
||||
<Link
|
||||
to="tutorial/creating-your-medusa-server"
|
||||
className={`${styles.docsLink}`}
|
||||
>
|
||||
Create your very own Medusa server →
|
||||
</Link>
|
||||
</div>
|
||||
<div className={`margin-top--md margin-bottom--xl`}>
|
||||
<Link to="how-to/plugins" className={`${styles.docsLink}`}>
|
||||
Explore plugins →
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Intro
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Intro } from "./Intro"
|
||||
@@ -0,0 +1,17 @@
|
||||
.title {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.docsLink {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 966px) {
|
||||
.docsLink {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from "react"
|
||||
import RootLayout from "@theme/Layout"
|
||||
|
||||
const Layout = ({ children, ...props }) => {
|
||||
return (
|
||||
<RootLayout {...props}>
|
||||
<div className="container">{children}</div>
|
||||
</RootLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default Layout
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Layout } from "./Layout"
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from "react"
|
||||
import styles from "./tab.module.css"
|
||||
|
||||
const TabItem = ({ title, isOverviewCard, items }) => {
|
||||
const overviewModeList = () =>
|
||||
items.map((item) => <p className="margin-bottom--xs">{item.title}</p>)
|
||||
return (
|
||||
<div className="col col--4 padding-right--md padding-bottom--md">
|
||||
<div className={styles.card}>
|
||||
<div className={styles.cardContent}>
|
||||
<h3>{title}</h3>
|
||||
<div>{isOverviewCard && overviewModeList()}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TabItem
|
||||
@@ -0,0 +1 @@
|
||||
export { default as TabItem } from "./TabItem"
|
||||
@@ -0,0 +1,18 @@
|
||||
.card {
|
||||
background-color: var(--ifm-medusa-gray);
|
||||
min-height: 257px;
|
||||
border-radius: 5px;
|
||||
padding: 20px 13px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.cardContent {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.cardContent p {
|
||||
font-size: 18px;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import clsx from "clsx"
|
||||
import React, { useState } from "react"
|
||||
import { TabItem } from "./TabItem/"
|
||||
|
||||
const BUTTONS_DATA = [
|
||||
{ buttonTitle: "Overview", value: "overview" },
|
||||
{ buttonTitle: "Tutorial", value: "tutorial" },
|
||||
{ buttonTitle: "Guides", value: "guide" },
|
||||
{ buttonTitle: "Reference", value: "reference" },
|
||||
]
|
||||
|
||||
const OVERVIEW_DATA = ["Tutorial", "Guides", "Reference"]
|
||||
|
||||
const TabsPanel = ({ items }) => {
|
||||
const [sort, setSort] = useState("overview")
|
||||
|
||||
const buttons = BUTTONS_DATA.map((item) => (
|
||||
// <button
|
||||
// className={clsx(
|
||||
// { [styles.buttonActive]: sort === item.value },
|
||||
// styles.button
|
||||
// )}
|
||||
// onClick={() => setSort(item.value)}
|
||||
// >
|
||||
// {item.buttonTitle}
|
||||
// </button>
|
||||
<li
|
||||
className={clsx("tabs__item", {
|
||||
"tabs__item--active": sort === item.value,
|
||||
})}
|
||||
onClick={() => setSort(item.value)}
|
||||
>
|
||||
{item.buttonTitle}
|
||||
</li>
|
||||
))
|
||||
|
||||
const getOverviewCardItemsSet = (currentCard) =>
|
||||
items.filter((item) => item.key === currentCard.toLowerCase())
|
||||
|
||||
const overviewCardsSet = () =>
|
||||
OVERVIEW_DATA.map((item) => (
|
||||
<TabItem
|
||||
isOverviewCard
|
||||
title={item}
|
||||
items={getOverviewCardItemsSet(item)}
|
||||
/>
|
||||
))
|
||||
|
||||
const getSortedArray = () => {
|
||||
return items.filter((entry) => entry.type === sort)
|
||||
}
|
||||
|
||||
const renderTabItems = () => {
|
||||
if (sort === "overview") return overviewCardsSet()
|
||||
return getSortedArray().length > 0 ? (
|
||||
getSortedArray().map((item) => {
|
||||
return <TabItem title={item.title} />
|
||||
})
|
||||
) : (
|
||||
<p>hold tight! we are building these things</p>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="padding-bottom--xl">
|
||||
{/* <Box sx={{ borderBottom: "1px solid black", marginBottom: "50px" }}>
|
||||
{buttons}
|
||||
</Box> */}
|
||||
<ul class="tabs margin-bottom--lg">{buttons}</ul>
|
||||
<div className="container padding--none">
|
||||
<div className="row row--no-gutters">{renderTabItems()}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TabsPanel
|
||||
@@ -0,0 +1 @@
|
||||
export { default as TabsPanel } from "./TabsPanel"
|
||||
@@ -0,0 +1,15 @@
|
||||
.button {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
height: 30px;
|
||||
font-size: 16px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.buttonActive {
|
||||
color: var(--ifm-color-primary);
|
||||
border-bottom: 3px solid var(--ifm-color-primary) !important;
|
||||
font-weight: 500;
|
||||
transition: ;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react"
|
||||
|
||||
const CloseIcon = ({ fill = "black" }) => (
|
||||
<svg
|
||||
width="15"
|
||||
height="15"
|
||||
viewBox="0 0 9 8"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1.05 7.76L0.51 7.22L3.79 3.92L0.51 0.62L1.05 0.0799997L4.33 3.38L7.59 0.0799997L8.13 0.62L4.85 3.92L8.13 7.22L7.59 7.76L4.33 4.48L1.05 7.76Z"
|
||||
fill={fill}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default CloseIcon
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from "react"
|
||||
|
||||
const ConfLogo = ({ fill }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 371.2226 96">
|
||||
<title>medusa-logo-one-colour-rgb</title>
|
||||
<g id="black-rgb">
|
||||
<path
|
||||
id="logoMark"
|
||||
d="M77.8271,15.6225,56.08,3.0664a22.8877,22.8877,0,0,0-22.8877,0L11.4438,15.6225A22.8877,22.8877,0,0,0,0,35.4438V60.5562A22.8877,22.8877,0,0,0,11.4438,80.3775L33.1919,92.9336a22.8877,22.8877,0,0,0,22.8877,0L77.8271,80.3775A22.8876,22.8876,0,0,0,89.271,60.5562V35.4438A22.8876,22.8876,0,0,0,77.8271,15.6225ZM44.6357,70.3178A22.3178,22.3178,0,1,1,66.9531,48,22.3176,22.3176,0,0,1,44.6357,70.3178Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<g id="type">
|
||||
<path
|
||||
id="type_CompoundPathItem_"
|
||||
d="M163.5361,22.6571h14.1416V71.662H169.206V30.078L155.625,71.662h-8.8907l-13.581-41.0948V71.662h-8.4707V22.6571h14.2109l12.3906,39.2734Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_2"
|
||||
d="M220.4453,60.6c-2.03,7.3516-8.2608,12.042-17.0118,12.042-10.9209,0-17.8525-7.3515-17.8525-18.4824s7.001-18.4814,18.0625-18.4814c12.3213,0,18.6914,9.24,15.332,20.7216H194.0517c.7012,5.8106,3.9209,9.2413,9.5215,9.2413,3.92,0,7.001-1.82,8.1914-5.0411Zm-26.253-9.871H211.414c.49-5.04-2.38-8.33-7.9111-8.33C198.2529,42.3993,195.0322,45.34,194.1923,50.7294Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_3"
|
||||
d="M252.5742,22.6571h7.9814V71.662h-7.9814V66.4813a13.8489,13.8489,0,0,1-11.9014,6.1611c-9.24,0-15.752-7.3515-15.752-18.4824,0-11.06,6.4415-18.4814,15.752-18.4814a13.85,13.85,0,0,1,11.9014,6.16Zm.3506,31.5029c0-6.9306-3.9209-11.4814-9.8018-11.4814-5.95,0-9.87,4.5508-9.87,11.4814s3.92,11.4815,9.87,11.4815C249.0039,65.6415,252.9248,61.0907,252.9248,54.16Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_4"
|
||||
d="M290.2333,36.6581h7.9805V71.662h-7.9805V65.3612c-2.4511,4.69-6.4414,7.1406-11.3417,7.1406-9.7305,0-11.2715-9.6611-11.2715-15.8916V36.6581h7.98V56.5409c0,4.62,1.0508,9.03,6.0918,9.03,5.18,0,8.541-4.62,8.541-11.0605Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_5"
|
||||
d="M304.0888,59.1307H311.79c-.49,4.3408,2.7305,7.07,8.1914,7.07,4.2695,0,7.1406-1.68,7.1406-4.2,0-7.0009-22.5429-1.96-22.5429-15.0517,0-7,6.5107-11.27,14.9824-11.27,9.3808,0,16.1709,5.25,14.7011,13.1611h-7.7714c.98-3.99-2.17-6.7207-7-6.7207-4.0606,0-6.7207,1.82-6.7207,4.34,0,7.0713,22.6123,1.6807,22.6123,14.9825,0,7.07-6.3711,11.2011-15.4717,11.2011C310.04,72.6424,303.5292,67.6014,304.0888,59.1307Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
<path
|
||||
id="type_CompoundPathItem_6"
|
||||
d="M371.2226,51.78V71.662H363.872V65.5711a13.7856,13.7856,0,0,1-12.6015,7.0713c-7.42,0-12.0411-4.3408-12.0411-10.4316,0-7.07,6.16-11.3408,16.0313-11.3408a36.6377,36.6377,0,0,1,7.9814.91c0-5.3213-1.8906-9.1709-7.4912-9.1709-4.2,0-6.791,2.1-5.95,6.02H341.749c-1.89-7.77,4.9707-12.9511,14.0722-12.9511C366.0419,35.6786,371.2226,42.0487,371.2226,51.78Zm-7.7,6.0909a25.2,25.2,0,0,0-7.6308-1.19c-5.7413,0-8.5411,2.1006-8.5411,5.32,0,2.8008,2.1,4.27,5.53,4.27A10.8339,10.8339,0,0,0,363.5224,57.871Z"
|
||||
style="fill: #0a3149"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default ConfLogo
|
||||
@@ -0,0 +1,190 @@
|
||||
/* stylelint-disable docusaurus/copyright-header */
|
||||
/**
|
||||
* Any CSS included here will be global. The classic template
|
||||
* bundles Infima by default. Infima is a CSS framework designed to
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap");
|
||||
|
||||
:root {
|
||||
/* Colors */
|
||||
--ifm-color-primary: #0a3149;
|
||||
--ifm-color-primary-dark: #0a3149;
|
||||
--ifm-color-primary-darker: #0a3149;
|
||||
--ifm-color-primary-darkest: #0a3149;
|
||||
--ifm-color-primary-light: #0a3149;
|
||||
--ifm-color-primary-lighter: #0a3149;
|
||||
--ifm-color-primary-lightest: #0a3149;
|
||||
--ifm-medusa-gray: #f0f0f0;
|
||||
|
||||
/* Fonts */
|
||||
--ifm-code-font-size: 90%;
|
||||
--ifm-font-family-base: "Open Sans";
|
||||
|
||||
/* Sidebar */
|
||||
--doc-sidebar-width: 350px !important;
|
||||
|
||||
/* Docs Page */
|
||||
--ifm-docs-page-max-width: 700px;
|
||||
|
||||
/* Toc */
|
||||
--ifm-toc-border-color: #f0f0f0;
|
||||
--ifm-toc-link-color: #a6acb5;
|
||||
--ifm-toc-padding-horizontal: 9px;
|
||||
|
||||
/* Navbar */
|
||||
--ifm-navbar-shadow: 0px 1px 0px 0px #a6acb5;
|
||||
}
|
||||
|
||||
html[data-theme="dark"] {
|
||||
--ifm-color-primary-dark: #ff4848;
|
||||
--ifm-color-primary: #ff4242;
|
||||
--ifm-background-color: #1f1f1f;
|
||||
--ifm-background-surface-color: #1f1f1f;
|
||||
--ifm-medusa-gray: #292929;
|
||||
--ifm-menu-color: #fff;
|
||||
--ifm-toc-border-color: #333;
|
||||
}
|
||||
|
||||
/* DocSearch */
|
||||
|
||||
html[data-theme="light"] .DocSearch-Button {
|
||||
--docsearch-searchbox-background: #fff;
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .DocSearch-Button {
|
||||
--docsearch-searchbox-background: #1f1f1f;
|
||||
}
|
||||
|
||||
span.DocSearch-Button-Key {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Navbar */
|
||||
|
||||
html[data-theme="dark"] .navbar-github-link:before {
|
||||
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
|
||||
no-repeat;
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .docusaurus-highlight-code-line {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.navbar-github-link:before {
|
||||
content: "";
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
|
||||
no-repeat;
|
||||
}
|
||||
|
||||
.navbar__link svg {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* DocsPage */
|
||||
|
||||
article {
|
||||
max-width: var(--ifm-docs-page-max-width);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.docusaurus-highlight-code-line {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
display: block;
|
||||
margin: 0 calc(-1 * var(--ifm-pre-padding));
|
||||
padding: 0 var(--ifm-pre-padding);
|
||||
}
|
||||
|
||||
/* TOC */
|
||||
|
||||
.table-of-contents {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.table-of-contents::before {
|
||||
content: "ON THIS PAGE";
|
||||
display: inline-block;
|
||||
font-size: 0.85rem;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.table-of-contents .table-of-contents__link--active {
|
||||
border-left: 3px solid var(--ifm-link-color);
|
||||
color: var(--ifm-color-primary);
|
||||
font-weight: 500;
|
||||
margin-left: -14px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
|
||||
.main-wrapper aside {
|
||||
z-index: var(--ifm-z-index-fixed);
|
||||
}
|
||||
|
||||
.sidebar-bg {
|
||||
background: var(--ifm-medusa-gray);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.padding-top--md {
|
||||
padding-top: 2rem !important;
|
||||
}
|
||||
|
||||
a.menu__link.menu__link--active.active {
|
||||
border-left: 4px solid var(--ifm-color-primary);
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
/* Pagination */
|
||||
|
||||
.pagination-nav {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: var(--ifm-docs-page-max-width);
|
||||
}
|
||||
|
||||
.navbar {
|
||||
padding-left: 32px;
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
|
||||
footer .footer__items svg {
|
||||
display: none;
|
||||
}
|
||||
|
||||
footer .footer__item a:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 966px) {
|
||||
footer .footer__col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
footer .footer__items li {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
footer .footer__title {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.footer--dark {
|
||||
--ifm-footer-background-color: #333;
|
||||
}
|
||||
|
||||
.react-toggle {
|
||||
display: none;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from "react"
|
||||
import { Banner } from "../components/Banner/"
|
||||
import { Intro } from "../components/Intro/"
|
||||
import { Layout } from "../components/Layout/"
|
||||
import styles from "./index.module.css"
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<Layout title={`Docs`} description="some description...">
|
||||
<div className={styles.container}>
|
||||
<Banner />
|
||||
<Intro
|
||||
title="Explore and learn how to use Medusa."
|
||||
desc="Get up and running within 5 minutes."
|
||||
/>
|
||||
{/* <TabsPanel items={CARDS_DATA} /> */}
|
||||
</div>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/* stylelint-disable docusaurus/copyright-header */
|
||||
|
||||
/**
|
||||
* CSS files with the .module.css suffix will be treated as CSS modules
|
||||
* and scoped locally.
|
||||
*/
|
||||
|
||||
.heroBanner {
|
||||
padding: 4rem 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 966px) {
|
||||
.heroBanner {
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 966px) {
|
||||
.container {
|
||||
max-width: 850px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import OriginalDocSidebar from "@theme-original/DocSidebar"
|
||||
import React from "react"
|
||||
|
||||
const DocSidebar = (props) => {
|
||||
return (
|
||||
<div className="sidebar-bg">
|
||||
<OriginalDocSidebar {...props} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DocSidebar
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
:root {
|
||||
--collapse-button-bg-color-dark: #2e333a;
|
||||
}
|
||||
|
||||
@media (min-width: 997px) {
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 100vh;
|
||||
height: 100%;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
padding-top: var(--ifm-navbar-height);
|
||||
width: var(--doc-sidebar-width);
|
||||
transition: opacity 50ms ease;
|
||||
}
|
||||
|
||||
.sidebarWithHideableNavbar {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.sidebarHidden {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.sidebarLogo {
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
margin: 0 var(--ifm-navbar-padding-horizontal);
|
||||
min-height: var(--ifm-navbar-height);
|
||||
max-height: var(--ifm-navbar-height);
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.sidebarLogo img {
|
||||
margin-right: 0.5rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.menu {
|
||||
flex-grow: 1;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.menuLinkText {
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
.menuLinkText:hover {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.menuWithAnnouncementBar {
|
||||
margin-bottom: var(--docusaurus-announcement-bar-height);
|
||||
}
|
||||
|
||||
.collapseSidebarButton {
|
||||
display: block !important;
|
||||
background-color: var(--ifm-button-background-color);
|
||||
height: 40px;
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
border-radius: 0;
|
||||
border: 1px solid var(--ifm-toc-border-color);
|
||||
}
|
||||
|
||||
.collapseSidebarButtonIcon {
|
||||
transform: rotate(180deg);
|
||||
margin-top: 4px;
|
||||
}
|
||||
html[dir="rtl"] .collapseSidebarButtonIcon {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .collapseSidebarButton {
|
||||
background-color: var(--collapse-button-bg-color-dark);
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .collapseSidebarButton:hover,
|
||||
html[data-theme="dark"] .collapseSidebarButton:focus {
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebarLogo,
|
||||
.collapseSidebarButton {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebarMenuIcon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.sidebarMenuCloseIcon {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 24px;
|
||||
font-size: 1.5rem;
|
||||
font-weight: var(--ifm-font-weight-bold);
|
||||
line-height: 0.9;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
:global(.menu__list) :global(.menu__list) {
|
||||
overflow-y: hidden;
|
||||
will-change: height;
|
||||
transition: height var(--ifm-transition-fast) linear;
|
||||
}
|
||||
|
||||
:global(.menu__list-item--collapsed) :global(.menu__list) {
|
||||
height: 0 !important;
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React, { useState, useRef, useCallback, useMemo } from "react"
|
||||
import { createPortal } from "react-dom"
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext"
|
||||
import { useHistory } from "@docusaurus/router"
|
||||
import { useBaseUrlUtils } from "@docusaurus/useBaseUrl"
|
||||
import Link from "@docusaurus/Link"
|
||||
import Head from "@docusaurus/Head"
|
||||
import useSearchQuery from "@theme/hooks/useSearchQuery"
|
||||
import { DocSearchButton, useDocSearchKeyboardEvents } from "@docsearch/react"
|
||||
import useAlgoliaContextualFacetFilters from "@theme/hooks/useAlgoliaContextualFacetFilters"
|
||||
import { translate } from "@docusaurus/Translate"
|
||||
import styles from "./styles.module.css"
|
||||
|
||||
let DocSearchModal = null
|
||||
|
||||
function Hit({ hit, children }) {
|
||||
return <Link to={hit.url}>{children}</Link>
|
||||
}
|
||||
|
||||
function ResultsFooter({ state, onClose }) {
|
||||
const { generateSearchPageLink } = useSearchQuery()
|
||||
|
||||
return (
|
||||
<Link to={generateSearchPageLink(state.query)} onClick={onClose}>
|
||||
See all {state.context.nbHits} results
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
function DocSearch({ contextualSearch, ...props }) {
|
||||
const { siteMetadata } = useDocusaurusContext()
|
||||
|
||||
const contextualSearchFacetFilters = useAlgoliaContextualFacetFilters()
|
||||
|
||||
const configFacetFilters = props.searchParameters?.facetFilters ?? []
|
||||
|
||||
const facetFilters = contextualSearch
|
||||
? // Merge contextual search filters with config filters
|
||||
[...contextualSearchFacetFilters, ...configFacetFilters]
|
||||
: // ... or use config facetFilters
|
||||
configFacetFilters
|
||||
|
||||
// we let user override default searchParameters if he wants to
|
||||
const searchParameters = {
|
||||
...props.searchParameters,
|
||||
facetFilters,
|
||||
}
|
||||
|
||||
const { withBaseUrl } = useBaseUrlUtils()
|
||||
const history = useHistory()
|
||||
const searchContainer = useRef(null)
|
||||
const searchButtonRef = useRef(null)
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const [initialQuery, setInitialQuery] = useState(null)
|
||||
|
||||
const importDocSearchModalIfNeeded = useCallback(() => {
|
||||
if (DocSearchModal) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
import("@docsearch/react/modal"),
|
||||
import("@docsearch/react/style"),
|
||||
import("./styles.css"),
|
||||
]).then(([{ DocSearchModal: Modal }]) => {
|
||||
DocSearchModal = Modal
|
||||
})
|
||||
}, [])
|
||||
|
||||
const onOpen = useCallback(() => {
|
||||
importDocSearchModalIfNeeded().then(() => {
|
||||
searchContainer.current = document.createElement("div")
|
||||
document.body.insertBefore(
|
||||
searchContainer.current,
|
||||
document.body.firstChild
|
||||
)
|
||||
setIsOpen(true)
|
||||
})
|
||||
}, [importDocSearchModalIfNeeded, setIsOpen])
|
||||
|
||||
const onClose = useCallback(() => {
|
||||
setIsOpen(false)
|
||||
searchContainer.current.remove()
|
||||
}, [setIsOpen])
|
||||
|
||||
const onInput = useCallback(
|
||||
(event) => {
|
||||
importDocSearchModalIfNeeded().then(() => {
|
||||
setIsOpen(true)
|
||||
setInitialQuery(event.key)
|
||||
})
|
||||
},
|
||||
[importDocSearchModalIfNeeded, setIsOpen, setInitialQuery]
|
||||
)
|
||||
|
||||
const navigator = useRef({
|
||||
navigate({ itemUrl }) {
|
||||
history.push(itemUrl)
|
||||
},
|
||||
}).current
|
||||
|
||||
const transformItems = useRef((items) => {
|
||||
return items.map((item) => {
|
||||
// We transform the absolute URL into a relative URL.
|
||||
// Alternatively, we can use `new URL(item.url)` but it's not
|
||||
// supported in IE.
|
||||
const a = document.createElement("a")
|
||||
a.href = item.url
|
||||
|
||||
return {
|
||||
...item,
|
||||
url: withBaseUrl(`${a.pathname}${a.hash}`),
|
||||
}
|
||||
})
|
||||
}).current
|
||||
|
||||
const resultsFooterComponent = useMemo(
|
||||
() => (footerProps) => <ResultsFooter {...footerProps} onClose={onClose} />,
|
||||
[onClose]
|
||||
)
|
||||
|
||||
const transformSearchClient = useCallback(
|
||||
(searchClient) => {
|
||||
searchClient.addAlgoliaAgent("docusaurus", siteMetadata.docusaurusVersion)
|
||||
|
||||
return searchClient
|
||||
},
|
||||
[siteMetadata.docusaurusVersion]
|
||||
)
|
||||
|
||||
useDocSearchKeyboardEvents({
|
||||
isOpen,
|
||||
onOpen,
|
||||
onClose,
|
||||
onInput,
|
||||
searchButtonRef,
|
||||
})
|
||||
|
||||
const translatedSearchLabel = translate({
|
||||
id: "theme.SearchBar.label",
|
||||
message: "Search",
|
||||
description: "The ARIA label and placeholder for search button",
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
{/* This hints the browser that the website will load data from Algolia,
|
||||
and allows it to preconnect to the DocSearch cluster. It makes the first
|
||||
query faster, especially on mobile. */}
|
||||
<link
|
||||
rel="preconnect"
|
||||
href={`https://${props.appId}-dsn.algolia.net`}
|
||||
crossOrigin="anonymous"
|
||||
/>
|
||||
</Head>
|
||||
|
||||
<div className={styles.searchBox}>
|
||||
<DocSearchButton
|
||||
onTouchStart={importDocSearchModalIfNeeded}
|
||||
onFocus={importDocSearchModalIfNeeded}
|
||||
onMouseOver={importDocSearchModalIfNeeded}
|
||||
onClick={onOpen}
|
||||
ref={searchButtonRef}
|
||||
translations={{
|
||||
buttonText: translatedSearchLabel,
|
||||
buttonAriaLabel: translatedSearchLabel,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{isOpen &&
|
||||
createPortal(
|
||||
<DocSearchModal
|
||||
onClose={onClose}
|
||||
initialScrollY={window.scrollY}
|
||||
initialQuery={initialQuery}
|
||||
navigator={navigator}
|
||||
transformItems={transformItems}
|
||||
hitComponent={Hit}
|
||||
resultsFooterComponent={resultsFooterComponent}
|
||||
transformSearchClient={transformSearchClient}
|
||||
{...props}
|
||||
searchParameters={searchParameters}
|
||||
/>,
|
||||
searchContainer.current
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function SearchBar() {
|
||||
const { siteConfig } = useDocusaurusContext()
|
||||
return <DocSearch {...siteConfig.themeConfig.algolia} />
|
||||
}
|
||||
|
||||
export default SearchBar
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
:root {
|
||||
--docsearch-primary-color: var(--ifm-color-primary);
|
||||
--docsearch-text-color: var(--ifm-font-color-base);
|
||||
}
|
||||
|
||||
.DocSearch-Button {
|
||||
margin: 0;
|
||||
transition: all var(--ifm-transition-fast)
|
||||
var(--ifm-transition-timing-default);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.DocSearch-Container {
|
||||
z-index: calc(var(--ifm-z-index-fixed) + 1);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
@media (max-width: 996px) {
|
||||
.searchBox {
|
||||
position: absolute;
|
||||
right: var(--ifm-navbar-padding-horizontal);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 997px) {
|
||||
.searchBox {
|
||||
padding: var(--ifm-navbar-item-padding-vertical)
|
||||
var(--ifm-navbar-item-padding-horizontal);
|
||||
flex: 1;
|
||||
margin-left: 200px;
|
||||
padding-right: 100px;
|
||||
}
|
||||
|
||||
.searchBox button {
|
||||
border: 1px solid var(--ifm-medusa-gray);
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user