diff --git a/www/apps/api-reference/app/admin/page.tsx b/www/apps/api-reference/app/admin/page.tsx index 0449685f2c..6cfa7b6d8d 100644 --- a/www/apps/api-reference/app/admin/page.tsx +++ b/www/apps/api-reference/app/admin/page.tsx @@ -15,7 +15,7 @@ const ReferencePage = async () => { +

Medusa V2 Admin API Reference

diff --git a/www/apps/api-reference/app/layout.tsx b/www/apps/api-reference/app/layout.tsx index 3994c92fbb..0cb2f90475 100644 --- a/www/apps/api-reference/app/layout.tsx +++ b/www/apps/api-reference/app/layout.tsx @@ -1,5 +1,4 @@ import "./globals.css" -import Navbar from "@/components/Navbar" import Providers from "../providers" import { WideLayout } from "docs-ui" import { Inter, Roboto_Mono } from "next/font/google" @@ -29,8 +28,12 @@ export default function RootLayout({ return ( {children} diff --git a/www/apps/api-reference/app/store/page.tsx b/www/apps/api-reference/app/store/page.tsx index be7e8e8119..4a2ba33eb9 100644 --- a/www/apps/api-reference/app/store/page.tsx +++ b/www/apps/api-reference/app/store/page.tsx @@ -15,7 +15,7 @@ const ReferencePage = async () => { +

Medusa V2 Store API Reference

diff --git a/www/apps/api-reference/components/MDXComponents/H2/index.tsx b/www/apps/api-reference/components/MDXComponents/H2/index.tsx index 002814272d..0f74773514 100644 --- a/www/apps/api-reference/components/MDXComponents/H2/index.tsx +++ b/www/apps/api-reference/components/MDXComponents/H2/index.tsx @@ -1,73 +1,47 @@ "use client" -import { InView } from "react-intersection-observer" -import { isElmWindow, useScrollController, useSidebar } from "docs-ui" -import checkElementInViewport from "../../../utils/check-element-in-viewport" -import { useEffect, useMemo } from "react" +import { useScrollController, useSidebar } from "docs-ui" +import { useEffect, useMemo, useRef, useState } from "react" import getSectionId from "../../../utils/get-section-id" -type H2Props = { - addToSidebar?: boolean -} & React.HTMLAttributes +type H2Props = React.HTMLAttributes -const H2 = ({ addToSidebar = true, children, ...props }: H2Props) => { - const { activePath, setActivePath, addItems } = useSidebar() - const { getScrolledTop, scrollableElement } = useScrollController() +const H2 = ({ children, ...props }: H2Props) => { + const headingRef = useRef(null) + const { activePath, addItems } = useSidebar() + const { scrollableElement, scrollToElement } = useScrollController() + const [scrolledFirstTime, setScrolledFirstTime] = useState(false) - const handleViewChange = ( - inView: boolean, - entry: IntersectionObserverEntry - ) => { - if (!addToSidebar) { - return - } - const heading = entry.target - if ( - (inView || - checkElementInViewport(heading.parentElement || heading, 40)) && - getScrolledTop() !== 0 && - activePath !== heading.id - ) { - // can't use next router as it doesn't support - // changing url without scrolling - history.pushState({}, "", `#${heading.id}`) - setActivePath(heading.id) - } - } - const id = getSectionId([children as string]) + const id = useMemo(() => getSectionId([children as string]), [children]) useEffect(() => { - if (id === (activePath || location.hash.replace("#", ""))) { - const elm = document.getElementById(id) - elm?.scrollIntoView() + if (!scrollableElement || !headingRef.current || scrolledFirstTime) { + return } + if (id === (activePath || location.hash.replace("#", ""))) { + scrollToElement( + (headingRef.current.offsetParent as HTMLElement) || headingRef.current + ) + } + setScrolledFirstTime(scrolledFirstTime) + }, [scrollableElement, headingRef, id]) + + useEffect(() => { addItems([ { + type: "link", path: `${id}`, title: children as string, loaded: true, }, ]) - }, []) - - const root = useMemo(() => { - return isElmWindow(scrollableElement) ? document.body : scrollableElement - }, [scrollableElement]) + }, [id]) return ( - +

{children} - +

) } diff --git a/www/apps/api-reference/components/MDXComponents/index.tsx b/www/apps/api-reference/components/MDXComponents/index.tsx index d87c69f10c..501fe51716 100644 --- a/www/apps/api-reference/components/MDXComponents/index.tsx +++ b/www/apps/api-reference/components/MDXComponents/index.tsx @@ -14,9 +14,7 @@ const getCustomComponents = (scope?: ScopeType): MDXComponents => { ...UiMDXComponents, Security: () => , a: Link, - h2: (props: React.HTMLAttributes) => ( -

- ), + h2: (props: React.HTMLAttributes) =>

, } } diff --git a/www/apps/api-reference/components/Navbar/FeedbackModal/index.tsx b/www/apps/api-reference/components/Navbar/FeedbackModal/index.tsx deleted file mode 100644 index b0204dc4f7..0000000000 --- a/www/apps/api-reference/components/Navbar/FeedbackModal/index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -"use client" - -import { Button, useModal, usePageLoading } from "docs-ui" -import DetailedFeedback from "../../DetailedFeedback" - -const FeedbackModal = () => { - const { setModalProps } = useModal() - const { isLoading } = usePageLoading() - - const openModal = () => { - if (isLoading) { - return - } - setModalProps({ - title: "Send your Feedback", - children: , - contentClassName: "lg:!min-h-auto !p-0", - }) - } - - return ( - - ) -} - -export default FeedbackModal diff --git a/www/apps/api-reference/components/Navbar/index.tsx b/www/apps/api-reference/components/Navbar/index.tsx deleted file mode 100644 index ec4d881eb3..0000000000 --- a/www/apps/api-reference/components/Navbar/index.tsx +++ /dev/null @@ -1,50 +0,0 @@ -"use client" - -import { - Navbar as UiNavbar, - getNavbarItems, - usePageLoading, - useSidebar, -} from "docs-ui" -import FeedbackModal from "./FeedbackModal" -import { useMemo } from "react" -import { config } from "../../config" -import { usePathname } from "next/navigation" -import VersionSwitcher from "../VersionSwitcher" -import basePathUrl from "../../utils/base-path-url" - -const Navbar = () => { - const { setMobileSidebarOpen, mobileSidebarOpen } = useSidebar() - const pathname = usePathname() - const { isLoading } = usePageLoading() - - const navbarItems = useMemo( - () => - getNavbarItems({ - basePath: config.baseUrl, - activePath: basePathUrl(pathname), - version: "v2", - }), - [pathname] - ) - - return ( - } - additionalActionsAfter={} - showSearchOpener - isLoading={isLoading} - /> - ) -} - -export default Navbar diff --git a/www/apps/api-reference/components/Section/index.tsx b/www/apps/api-reference/components/Section/index.tsx index c5904b6d71..3965279bc2 100644 --- a/www/apps/api-reference/components/Section/index.tsx +++ b/www/apps/api-reference/components/Section/index.tsx @@ -1,14 +1,25 @@ "use client" import clsx from "clsx" +import { useActiveOnScroll, useSidebar } from "docs-ui" import { useEffect, useRef } from "react" export type SectionProps = { - addToSidebar?: boolean + checkActiveOnScroll?: boolean } & React.AllHTMLAttributes -const Section = ({ children, className }: SectionProps) => { +const Section = ({ + children, + className, + checkActiveOnScroll = false, +}: SectionProps) => { const sectionRef = useRef(null) + const { activeItemId } = useActiveOnScroll({ + rootElm: sectionRef.current || undefined, + enable: checkActiveOnScroll, + useDefaultIfNoActive: false, + }) + const { setActivePath } = useSidebar() useEffect(() => { if ("scrollRestoration" in history) { @@ -17,6 +28,13 @@ const Section = ({ children, className }: SectionProps) => { } }, []) + useEffect(() => { + if (activeItemId.length) { + history.pushState({}, "", `#${activeItemId}`) + setActivePath(activeItemId) + } + }, [activeItemId]) + return (
( async () => import("./CodeSection") @@ -40,7 +41,7 @@ const TagOperation = ({ ) const nodeRef = useRef(null) const { loading, removeLoading } = useLoading() - const { scrollableElement } = useScrollController() + const { scrollableElement, scrollToTop } = useScrollController() const root = useMemo(() => { return isElmWindow(scrollableElement) ? document.body : scrollableElement }, [scrollableElement]) @@ -75,24 +76,28 @@ const TagOperation = ({ [ref] ) - useEffect(() => { - const enableShow = () => { - setShow(true) + const scrollIntoView = useCallback(() => { + if (nodeRef.current && !checkElementInViewport(nodeRef.current, 10)) { + const elm = nodeRef.current as HTMLElement + scrollToTop( + elm.offsetTop + (elm.offsetParent as HTMLElement)?.offsetTop, + 0 + ) } + setShow(true) + }, [scrollToTop, nodeRef]) + useEffect(() => { if (nodeRef && nodeRef.current) { removeLoading() const currentHash = location.hash.replace("#", "") if (currentHash === path) { - setTimeout(() => { - nodeRef.current?.scrollIntoView() - enableShow() - }, 100) + setTimeout(scrollIntoView, 100) } else if (currentHash.split("_")[0] === path.split("_")[0]) { - enableShow() + setShow(true) } } - }, [nodeRef, path]) + }, [nodeRef, path, scrollIntoView]) return (
( @@ -56,16 +56,17 @@ const TagPaths = ({ tag, className }: TagPathsProps) => { useEffect(() => { if (paths) { const parentItem = findItemInSection( - items[SidebarItemSections.BOTTOM], - { path: tagSlugName }, + items[SidebarItemSections.DEFAULT], + { title: tag.name }, false - ) - const pathItems: SidebarItemType[] = getTagChildSidebarItems(paths) + ) as SidebarItemCategory + const pathItems: SidebarItem[] = getTagChildSidebarItems(paths) if ((parentItem?.children?.length || 0) < pathItems.length) { addItems(pathItems, { - section: SidebarItemSections.BOTTOM, + section: SidebarItemSections.DEFAULT, parent: { - path: tagSlugName, + title: tag.name, + path: "", changeLoaded: true, }, }) diff --git a/www/apps/api-reference/components/Tags/Section/Schema/index.tsx b/www/apps/api-reference/components/Tags/Section/Schema/index.tsx index 5f0b3173a9..cd2415341d 100644 --- a/www/apps/api-reference/components/Tags/Section/Schema/index.tsx +++ b/www/apps/api-reference/components/Tags/Section/Schema/index.tsx @@ -40,7 +40,7 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => { }, }) - const { scrollableElement } = useScrollController() + const { scrollableElement, scrollToElement } = useScrollController() const root = useMemo(() => { return isElmWindow(scrollableElement) ? document.body : scrollableElement }, [scrollableElement]) @@ -49,6 +49,7 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => { addItems( [ { + type: "link", path: schemaSlug, title: `${formattedName} Object`, additionalElms: Schema, @@ -56,8 +57,9 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => { }, ], { - section: SidebarItemSections.BOTTOM, + section: SidebarItemSections.DEFAULT, parent: { + title: tagName, path: tagSlugName, changeLoaded: true, }, @@ -69,12 +71,12 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => { useEffect(() => { if (schemaSlug === (activePath || location.hash.replace("#", ""))) { - const elm = document.getElementById(schemaSlug) - elm?.scrollIntoView({ - block: "center", - }) + const elm = document.getElementById(schemaSlug) as HTMLElement + if (!checkElementInViewport(elm, 40)) { + scrollToElement(elm) + } } - }, []) + }, [activePath, schemaSlug]) const handleViewChange = ( inView: boolean, diff --git a/www/apps/api-reference/components/Tags/Section/index.tsx b/www/apps/api-reference/components/Tags/Section/index.tsx index e11d160efc..2df1740673 100644 --- a/www/apps/api-reference/components/Tags/Section/index.tsx +++ b/www/apps/api-reference/components/Tags/Section/index.tsx @@ -26,6 +26,7 @@ import { SchemaObject, TagObject } from "@/types/openapi" import useSWR from "swr" import { TagSectionSchemaProps } from "./Schema" import basePathUrl from "../../../utils/base-path-url" +import checkElementInViewport from "../../../utils/check-element-in-viewport" export type TagSectionProps = { tag: TagObject @@ -52,7 +53,7 @@ const TagSection = ({ tag }: TagSectionProps) => { const slugTagName = useMemo(() => getSectionId([tag.name]), [tag]) const { area } = useArea() const pathname = usePathname() - const { scrollableElement } = useScrollController() + const { scrollableElement, scrollToElement } = useScrollController() const { data } = useSWR<{ schema: SchemaObject }>( @@ -96,8 +97,10 @@ const TagSection = ({ tag }: TagSectionProps) => { if (activePath && activePath.includes(slugTagName)) { const tagName = activePath.split("_") if (tagName.length === 1 && tagName[0] === slugTagName) { - const elm = document.getElementById(tagName[0]) as Element - elm?.scrollIntoView() + const elm = document.getElementById(tagName[0]) + if (elm && !checkElementInViewport(elm, 10)) { + scrollToElement(elm) + } } else if (tagName.length > 1 && tagName[0] === slugTagName) { setLoadPaths(true) } diff --git a/www/apps/api-reference/components/Tags/index.tsx b/www/apps/api-reference/components/Tags/index.tsx index f07a46b1fa..bdb2a8aa86 100644 --- a/www/apps/api-reference/components/Tags/index.tsx +++ b/www/apps/api-reference/components/Tags/index.tsx @@ -11,7 +11,7 @@ import { swrFetcher, useSidebar } from "docs-ui" import getSectionId from "@/utils/get-section-id" import { ExpandedDocument } from "@/types/openapi" import getTagChildSidebarItems from "@/utils/get-tag-child-sidebar-items" -import { SidebarItemSections } from "types" +import { SidebarItem, SidebarItemSections } from "types" import basePathUrl from "../../utils/base-path-url" const TagSection = dynamic( @@ -31,7 +31,7 @@ const Tags = () => { const [loadData, setLoadData] = useState(false) const [expand, setExpand] = useState("") const { baseSpecs, setBaseSpecs } = useBaseSpecs() - const { addItems } = useSidebar() + const { addItems, setActivePath } = useSidebar() const { area, prevArea } = useArea() const { data } = useSWR( @@ -65,30 +65,42 @@ const Tags = () => { if (baseSpecs) { if (prevArea !== area) { setBaseSpecs(null) + setLoadData(true) return } - addItems( - baseSpecs.tags?.map((tag) => { + const itemsToAdd: SidebarItem[] = [ + { + type: "separator", + }, + ] + + if (baseSpecs.tags) { + baseSpecs.tags.forEach((tag) => { const tagPathName = getSectionId([tag.name.toLowerCase()]) const childItems = baseSpecs.expandedTags && Object.hasOwn(baseSpecs.expandedTags, tagPathName) ? getTagChildSidebarItems(baseSpecs.expandedTags[tagPathName]) : [] - return { - path: tagPathName, + itemsToAdd.push({ + type: "category", title: tag.name, children: childItems, loaded: childItems.length > 0, - } - }) || [], - { - section: SidebarItemSections.BOTTOM, - } - ) + onOpen: () => { + history.pushState({}, "", `#${tagPathName}`) + setActivePath(tagPathName) + }, + }) + }) + } + + addItems(itemsToAdd, { + section: SidebarItemSections.DEFAULT, + }) } - }, [baseSpecs, addItems]) + }, [baseSpecs, prevArea, area]) return ( <> diff --git a/www/apps/api-reference/config/index.ts b/www/apps/api-reference/config/index.ts index ee1e190655..344c5c3384 100644 --- a/www/apps/api-reference/config/index.ts +++ b/www/apps/api-reference/config/index.ts @@ -8,14 +8,14 @@ export const config: DocsConfig = { basePath: process.env.NEXT_PUBLIC_BASE_PATH, // sidebar is auto generated sidebar: { - top: [ + default: [ { + type: "link", title: "Introduction", path: "", loaded: true, }, ], - bottom: [], mobile: getMobileSidebarItems({ baseUrl, version: "v2", diff --git a/www/apps/api-reference/providers/index.tsx b/www/apps/api-reference/providers/index.tsx index 48c160d131..d93af89dc4 100644 --- a/www/apps/api-reference/providers/index.tsx +++ b/www/apps/api-reference/providers/index.tsx @@ -13,6 +13,7 @@ import BaseSpecsProvider from "./base-specs" import SidebarProvider from "./sidebar" import SearchProvider from "./search" import { config } from "../config" +import { MainNavProvider } from "./main-nav" type ProvidersProps = { children?: React.ReactNode @@ -28,9 +29,11 @@ const Providers = ({ children }: ProvidersProps) => { - - {children} - + + + {children} + + diff --git a/www/apps/api-reference/providers/main-nav.tsx b/www/apps/api-reference/providers/main-nav.tsx new file mode 100644 index 0000000000..a4bff7d19a --- /dev/null +++ b/www/apps/api-reference/providers/main-nav.tsx @@ -0,0 +1,48 @@ +"use client" + +import { + formatReportLink, + getNavDropdownItems, + MainNavProvider as UiMainNavProvider, + useIsBrowser, +} from "docs-ui" +import { useMemo } from "react" +import { config } from "../config" +import { usePathname } from "next/navigation" +import basePathUrl from "../utils/base-path-url" + +type MainNavProviderProps = { + children?: React.ReactNode +} + +export const MainNavProvider = ({ children }: MainNavProviderProps) => { + const isBrowser = useIsBrowser() + const pathname = usePathname() + const navigationDropdownItems = useMemo( + () => + getNavDropdownItems({ + basePath: config.baseUrl, + activePath: basePathUrl(pathname), + version: "v2", + }), + [pathname] + ) + + const reportLink = useMemo( + () => + formatReportLink( + config.titleSuffix || "", + isBrowser ? document.title : "" + ), + [isBrowser] + ) + + return ( + + {children} + + ) +} diff --git a/www/apps/api-reference/providers/page-title.tsx b/www/apps/api-reference/providers/page-title.tsx index cbe2a97312..2bf3876857 100644 --- a/www/apps/api-reference/providers/page-title.tsx +++ b/www/apps/api-reference/providers/page-title.tsx @@ -3,6 +3,7 @@ import { createContext, useEffect } from "react" import { capitalize, useSidebar } from "docs-ui" import { useArea } from "./area" +import { SidebarItemLink } from "types" const PageTitleContext = createContext(null) @@ -25,7 +26,9 @@ const PageTitleProvider = ({ children }: PageTitleProviderProps) => { document.title = `${activeItem?.title} - ${titleSuffix}` } else { // find the child that matches the active path - const item = activeItem?.children?.find((i) => i.path === activePath) + const item = activeItem?.children?.find( + (i) => i.type === "link" && i.path === activePath + ) as SidebarItemLink if (item) { document.title = `${item.title} - ${titleSuffix}` } diff --git a/www/apps/api-reference/providers/sidebar.tsx b/www/apps/api-reference/providers/sidebar.tsx index f361463ccb..3e550ff822 100644 --- a/www/apps/api-reference/providers/sidebar.tsx +++ b/www/apps/api-reference/providers/sidebar.tsx @@ -1,4 +1,5 @@ "use client" + import { SidebarProvider as UiSidebarProvider, usePageLoading, @@ -6,8 +7,8 @@ import { useScrollController, } from "docs-ui" import { config } from "../config" -import { usePathname } from "next/navigation" import { useCallback } from "react" +import { usePathname } from "next/navigation" type SidebarProviderProps = { children?: React.ReactNode @@ -17,11 +18,11 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => { const { isLoading, setIsLoading } = usePageLoading() const { scrollableElement } = useScrollController() const pathname = usePathname() - const prevPathname = usePrevious(pathname) + const prevPathName = usePrevious(pathname) const resetOnCondition = useCallback( - () => prevPathname !== undefined && prevPathname !== pathname, - [pathname, prevPathname] + () => prevPathName !== undefined && pathname !== prevPathName, + [pathname, prevPathName] ) return ( diff --git a/www/apps/api-reference/utils/base-path-url.ts b/www/apps/api-reference/utils/base-path-url.ts index c9215b4c46..0756899d79 100644 --- a/www/apps/api-reference/utils/base-path-url.ts +++ b/www/apps/api-reference/utils/base-path-url.ts @@ -1,5 +1,5 @@ import { getLinkWithBasePath } from "docs-ui" -export default function basePathUrl(path: string) { +export default function basePathUrl(path = "") { return getLinkWithBasePath(path, process.env.NEXT_PUBLIC_BASE_PATH) } diff --git a/www/apps/api-reference/utils/check-element-in-viewport.ts b/www/apps/api-reference/utils/check-element-in-viewport.ts index 2a2a762dcd..4f7a1cdaf7 100644 --- a/www/apps/api-reference/utils/check-element-in-viewport.ts +++ b/www/apps/api-reference/utils/check-element-in-viewport.ts @@ -4,7 +4,7 @@ export default function checkElementInViewport( height?: number ) { const rect = element.getBoundingClientRect() - const windowHeight = + const windowHeight: number | undefined = height || window.innerHeight || document.documentElement.clientHeight return !( diff --git a/www/apps/api-reference/utils/get-tag-child-sidebar-items.tsx b/www/apps/api-reference/utils/get-tag-child-sidebar-items.tsx index 68945b7179..b19f7570d5 100644 --- a/www/apps/api-reference/utils/get-tag-child-sidebar-items.tsx +++ b/www/apps/api-reference/utils/get-tag-child-sidebar-items.tsx @@ -1,4 +1,4 @@ -import type { SidebarItemType } from "types" +import type { SidebarItem } from "types" import type { Operation, PathsObject } from "@/types/openapi" import type { OpenAPIV3 } from "openapi-types" import dynamic from "next/dynamic" @@ -11,13 +11,14 @@ const MethodLabel = dynamic( export default function getTagChildSidebarItems( paths: PathsObject -): SidebarItemType[] { - const items: SidebarItemType[] = [] +): SidebarItem[] { + const items: SidebarItem[] = [] Object.entries(paths).forEach(([, operations]) => { Object.entries(operations).map(([method, operation]) => { const definedOperation = operation as Operation const definedMethod = method as OpenAPIV3.HttpMethods items.push({ + type: "link", path: getSectionId([ ...(definedOperation.tags || []), definedOperation.operationId, diff --git a/www/apps/book/app/layout.tsx b/www/apps/book/app/layout.tsx index 1dfd2ea4b2..e8ffa61972 100644 --- a/www/apps/book/app/layout.tsx +++ b/www/apps/book/app/layout.tsx @@ -1,10 +1,8 @@ import type { Metadata } from "next" import { Inter, Roboto_Mono } from "next/font/google" - -import Navbar from "@/components/Navbar" import Providers from "@/providers" import "./globals.css" -import { Bannerv2, TightLayout } from "docs-ui" +import { TightLayout } from "docs-ui" import { config } from "@/config" import clsx from "clsx" import Feedback from "@/components/Feedback" @@ -40,10 +38,8 @@ export default function RootLayout({ return ( , }} showPagination={true} bodyClassName={clsx(inter.variable, robotoMono.variable)} diff --git a/www/apps/book/components/Navbar/index.tsx b/www/apps/book/components/Navbar/index.tsx deleted file mode 100644 index 7dd1b52d29..0000000000 --- a/www/apps/book/components/Navbar/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -"use client" - -import { Navbar as UiNavbar, getNavbarItems } from "docs-ui" -import { useSidebar } from "docs-ui" -import { useMemo } from "react" -import { config } from "../../config" -import { basePathUrl } from "../../utils/base-path-url" - -const Navbar = () => { - const { setMobileSidebarOpen, mobileSidebarOpen } = useSidebar() - - const navbarItems = useMemo( - () => - getNavbarItems({ - basePath: config.baseUrl, - activePath: basePathUrl(), - version: "v2", - }), - [] - ) - - return ( - - ) -} - -export default Navbar diff --git a/www/apps/book/config/sidebar.tsx b/www/apps/book/config/sidebar.tsx index 836a964ea5..c43accc36b 100644 --- a/www/apps/book/config/sidebar.tsx +++ b/www/apps/book/config/sidebar.tsx @@ -1,17 +1,20 @@ import { Badge, getMobileSidebarItems } from "docs-ui" -import type { SidebarConfig, SidebarItemType } from "@/types" +import type { SidebarConfig, SidebarItem } from "@/types" import { sidebar } from "../sidebar.mjs" const soonBadge = Soon -const normalizeSidebarItems = (items: SidebarItemType[]) => +const normalizeSidebarItems = (items: SidebarItem[]) => items.map((item) => { + if (item.type === "separator") { + return item + } if (item.isSoon) { item.additionalElms = soonBadge } if (item.children) { - item.children = normalizeSidebarItems(item.children as SidebarItemType[]) + item.children = normalizeSidebarItems(item.children as SidebarItem[]) } return item @@ -19,8 +22,7 @@ const normalizeSidebarItems = (items: SidebarItemType[]) => export const sidebarConfig = (baseUrl: string): SidebarConfig => { return { - top: normalizeSidebarItems(sidebar), - bottom: [], + default: normalizeSidebarItems(sidebar), mobile: getMobileSidebarItems({ baseUrl, version: "v2", diff --git a/www/apps/book/providers/index.tsx b/www/apps/book/providers/index.tsx index 6315181f14..8853af0657 100644 --- a/www/apps/book/providers/index.tsx +++ b/www/apps/book/providers/index.tsx @@ -16,6 +16,7 @@ import { import SidebarProvider from "./sidebar" import SearchProvider from "./search" import { config } from "../config" +import { MainNavProvider } from "./main-nav" type ProvidersProps = { children?: React.ReactNode @@ -33,16 +34,18 @@ const Providers = ({ children }: ProvidersProps) => { - - - {children} - - + + + + {children} + + + diff --git a/www/apps/book/providers/main-nav.tsx b/www/apps/book/providers/main-nav.tsx new file mode 100644 index 0000000000..9bd9970e2d --- /dev/null +++ b/www/apps/book/providers/main-nav.tsx @@ -0,0 +1,46 @@ +"use client" + +import { + formatReportLink, + getNavDropdownItems, + MainNavProvider as UiMainNavProvider, + useIsBrowser, +} from "docs-ui" +import { useMemo } from "react" +import { config } from "../config" +import { basePathUrl } from "../utils/base-path-url" + +type MainNavProviderProps = { + children?: React.ReactNode +} + +export const MainNavProvider = ({ children }: MainNavProviderProps) => { + const isBrowser = useIsBrowser() + const navigationDropdownItems = useMemo( + () => + getNavDropdownItems({ + basePath: config.baseUrl, + activePath: basePathUrl(), + version: "v2", + }), + [] + ) + + const reportLink = useMemo( + () => + formatReportLink( + config.titleSuffix || "", + isBrowser ? document.title : "" + ), + [isBrowser] + ) + + return ( + + {children} + + ) +} diff --git a/www/apps/book/providers/sidebar.tsx b/www/apps/book/providers/sidebar.tsx index 5c8ce3c927..c98ba6cb5f 100644 --- a/www/apps/book/providers/sidebar.tsx +++ b/www/apps/book/providers/sidebar.tsx @@ -1,4 +1,5 @@ "use client" + import { SidebarProvider as UiSidebarProvider, useScrollController, @@ -20,7 +21,6 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => { initialItems={config.sidebar} staticSidebarItems={true} disableActiveTransition={true} - noTitleStyling={true} > {children} diff --git a/www/apps/book/sidebar.mjs b/www/apps/book/sidebar.mjs index 291fdf9216..1411e1c4c8 100644 --- a/www/apps/book/sidebar.mjs +++ b/www/apps/book/sidebar.mjs @@ -1,183 +1,226 @@ import numberSidebarItems from "./utils/number-sidebar-items.mjs" import { sidebarAttachHrefCommonOptions } from "./utils/sidebar-attach-common-options.mjs" -/** @type {import('@/types').SidebarItemType[]} */ -export const sidebar = sidebarAttachHrefCommonOptions( - numberSidebarItems([ +/** @type {import('@/types').SidebarItem[]} */ +export const sidebar = numberSidebarItems( + sidebarAttachHrefCommonOptions([ { + type: "link", path: "/", title: "Introduction", }, { + type: "link", path: "/first-customizations", title: "Your First Customizations", }, { + type: "link", path: "/basics", title: "The Basics", children: [ { + type: "link", path: "/basics/project-directories-files", title: "Project Directories and Files", }, { + type: "link", path: "/basics/medusa-container", title: "Medusa Container", }, { + type: "link", path: "/basics/api-routes", title: "API Routes", }, { + type: "link", path: "/basics/modules-and-services", title: "Modules and Services", }, { + type: "link", path: "/basics/commerce-modules", title: "Commerce Modules", }, { + type: "link", path: "/basics/modules-directory-structure", title: "Modules Directory Structure", }, { + type: "link", path: "/basics/data-models", title: "Data Models", }, { + type: "link", path: "/basics/loaders", title: "Loaders", }, { + type: "link", path: "/basics/events-and-subscribers", title: "Events and Subscribers", }, { + type: "link", path: "/basics/scheduled-jobs", title: "Scheduled Jobs", }, { + type: "link", path: "/basics/workflows", title: "Workflows", }, { + type: "link", path: "/basics/admin-customizations", title: "Admin Customizations", }, ], }, { + type: "link", path: "/advanced-development", title: "Advanced Development", children: [ { + type: "sub-category", title: "API Routes", children: [ { + type: "link", path: "/advanced-development/api-routes/http-methods", title: "HTTP Methods", }, { + type: "link", path: "/advanced-development/api-routes/parameters", title: "Parameters", }, { + type: "link", path: "/advanced-development/api-routes/middlewares", title: "Middlewares", }, { + type: "link", path: "/advanced-development/api-routes/protected-routes", title: "Protected Routes", }, { + type: "link", path: "/advanced-development/api-routes/cors", title: "Handling CORS", }, ], }, { + type: "sub-category", title: "Modules", children: [ { + type: "link", path: "/advanced-development/modules/container", title: "Module's Container", }, { + type: "link", path: "/advanced-development/modules/service-factory", title: "Service Factory", }, { + type: "link", path: "/advanced-development/modules/isolation", title: "Module Isolation", }, { + type: "link", path: "/advanced-development/modules/module-links", title: "Module Links", }, { + type: "link", path: "/advanced-development/modules/module-link-directions", title: "Module Link Direction", }, { + type: "link", path: "/advanced-development/modules/remote-link", title: "Remote Link", }, { + type: "link", path: "/advanced-development/modules/remote-query", title: "Remote Query", }, { + type: "link", path: "/advanced-development/modules/options", title: "Module Options", }, ], }, { + type: "link", path: "/advanced-development/data-models", title: "Data Models", children: [ { + type: "link", path: "/advanced-development/data-models/property-types", title: "Property Types", }, { + type: "link", path: "/advanced-development/data-models/primary-key", title: "Primary Key", }, { + type: "link", path: "/advanced-development/data-models/default-properties", title: "Default Properties", }, { + type: "link", path: "/advanced-development/data-models/configure-properties", title: "Configure Properties", }, { + type: "link", path: "/advanced-development/data-models/relationships", title: "Relationships", }, { + type: "link", path: "/advanced-development/data-models/manage-relationships", title: "Manage Relationships", }, { + type: "link", path: "/advanced-development/data-models/index", title: "Index", }, { + type: "link", path: "/advanced-development/data-models/searchable-property", title: "Searchable Property", }, { + type: "link", path: "/advanced-development/data-models/write-migration", title: "Write Migration", }, ], }, { + type: "sub-category", title: "Events and Subscribers", children: [ { + type: "link", path: "/advanced-development/events-and-subscribers/data-payload", title: "Events Data Payload", }, @@ -188,84 +231,104 @@ export const sidebar = sidebarAttachHrefCommonOptions( ], }, { + type: "sub-category", title: "Scheduled Jobs", children: [ { + type: "link", path: "/advanced-development/scheduled-jobs/execution-number", title: "Execution Number", }, ], }, { + type: "sub-category", title: "Workflows", children: [ { + type: "link", path: "/advanced-development/workflows/constructor-constraints", title: "Workflow Constraints", }, { + type: "link", path: "/advanced-development/workflows/conditions", title: "Conditions in Workflows", }, { + type: "link", path: "/advanced-development/workflows/compensation-function", title: "Compensation Function", }, { + type: "link", path: "/advanced-development/workflows/workflow-hooks", title: "Workflow Hooks", }, { + type: "link", path: "/advanced-development/workflows/add-workflow-hook", title: "Expose a Hook", }, { + type: "link", path: "/advanced-development/workflows/access-workflow-errors", title: "Access Workflow Errors", }, { + type: "link", path: "/advanced-development/workflows/retry-failed-steps", title: "Retry Failed Steps", }, { + type: "link", path: "/advanced-development/workflows/parallel-steps", title: "Run Steps in Parallel", }, { + type: "link", path: "/advanced-development/workflows/workflow-timeout", title: "Workflow Timeout", }, { + type: "link", path: "/advanced-development/workflows/long-running-workflow", title: "Long-Running Workflow", }, { + type: "link", path: "/advanced-development/workflows/execute-another-workflow", title: "Execute Another Workflow", }, { + type: "link", path: "/advanced-development/workflows/advanced-example", title: "Example: Advanced Workflow", }, ], }, { + type: "link", path: "/advanced-development/custom-cli-scripts", title: "Custom CLI Scripts", }, { + type: "link", path: "/advanced-development/admin", title: "Admin Development", children: [ { + type: "link", path: "/advanced-development/admin/widgets", title: "Admin Widgets", }, { + type: "link", path: "/advanced-development/admin/ui-routes", title: "Admin UI Routes", }, { + type: "link", path: "/advanced-development/admin/tips", title: "Tips", }, @@ -274,42 +337,51 @@ export const sidebar = sidebarAttachHrefCommonOptions( ], }, { + type: "link", path: "/storefront-development", title: "Storefront Development", children: [ { + type: "link", path: "/storefront-development/nextjs-starter", title: "Next.js Starter", }, ], }, { + type: "link", path: "/architectural-modules", title: "Architectural Modules", }, { + type: "link", path: "/debugging-and-testing", title: "Debugging and Testing", children: [ { + type: "link", path: "/debugging-and-testing/logging", title: "Logging", }, { + type: "link", path: "/debugging-and-testing/tools", title: "Tools", }, ], }, { + type: "link", path: "/deployment", title: "Deployment", }, { + type: "link", path: "/more-resources", title: "More Resources", }, { + type: "link", path: "/cheatsheet", title: "Cheat Sheet", }, diff --git a/www/apps/book/types/index.d.ts b/www/apps/book/types/index.d.ts index e7594b456c..3934655afd 100644 --- a/www/apps/book/types/index.d.ts +++ b/www/apps/book/types/index.d.ts @@ -1,11 +1,8 @@ -import { - SidebarSectionItemsType, - SidebarItemType as UiSidebarItemType, -} from "docs-ui" +import { SidebarSectionItems, SidebarItem as SidebarItemType } from "types" -export declare type SidebarItemType = UiSidebarItemType & { +export declare type SidebarItem = SidebarItemType & { isSoon: boolean number?: string } -export declare type SidebarConfig = SidebarSectionItemsType +export declare type SidebarConfig = SidebarSectionItems diff --git a/www/apps/book/utils/number-sidebar-items.mjs b/www/apps/book/utils/number-sidebar-items.mjs index c1a2fcf902..9bb1a3d35e 100644 --- a/www/apps/book/utils/number-sidebar-items.mjs +++ b/www/apps/book/utils/number-sidebar-items.mjs @@ -1,14 +1,34 @@ /** * - * @param {import("@/types").SidebarItemType[]} sidebarItems - The items to add numbers to their titles + * @param {import("@/types").SidebarItem[]} sidebarItems - The items to add numbers to their titles * @param {number[]} numbering - The current numbering level - * @returns {import("@/types").SidebarItemType[]} The modified sidebar items + * @returns {import("@/types").SidebarItem[]} The modified sidebar items */ export default function numberSidebarItems(sidebarItems, numbering = [1]) { + // TODO generate chapter titles if (!numbering.length) { numbering.push(1) } + const isTopItems = numbering.length === 1 + /** @type {import("@/types").SidebarItem[]} */ + const numberedItems = [] + /** @type {import("@/types").SidebarItem | undefined} */ + let parentItem sidebarItems.forEach((item) => { + if (item.type === "separator") { + ;(parentItem?.children || numberedItems).push(item) + } + if (isTopItems) { + // Add chapter category + numberedItems.push({ + type: "category", + title: `Chapter ${padNumber(numbering[0])}`, + children: [], + loaded: true, + }) + + parentItem = numberedItems[numberedItems.length - 1] + } // append current number to the item's title item.number = `${numbering.join(".")}.` item.title = `${item.number} ${item.title.trim()}` @@ -17,8 +37,19 @@ export default function numberSidebarItems(sidebarItems, numbering = [1]) { item.children = numberSidebarItems(item.children, [...numbering, 1]) } + ;(parentItem?.children || numberedItems).push(item) + numbering[numbering.length - 1]++ }) - return sidebarItems + return numberedItems +} + +function padNumber(number) { + number = number.toString() + if (number.length < 2) { + number = `0` + number + } + + return number } diff --git a/www/apps/book/utils/sidebar-attach-common-options.mjs b/www/apps/book/utils/sidebar-attach-common-options.mjs index e40b6dee0e..350a3f07bb 100644 --- a/www/apps/book/utils/sidebar-attach-common-options.mjs +++ b/www/apps/book/utils/sidebar-attach-common-options.mjs @@ -1,4 +1,4 @@ -/** @type {Partial} */ +/** @type {Partial} */ const commonOptions = { loaded: true, isPathHref: true, @@ -6,13 +6,26 @@ const commonOptions = { /** * - * @param {import("../providers").SidebarItemType[]} sidebar - * @returns {import("../providers").SidebarItemType[]} + * @param {import("@/types").SidebarItem[]} sidebar + * @param {boolean} nested + * @returns {import("@/types").SidebarItem[]} */ -export function sidebarAttachHrefCommonOptions(sidebar) { - return sidebar.map((item) => ({ - ...commonOptions, - ...item, - children: sidebarAttachHrefCommonOptions(item.children || []), - })) +export function sidebarAttachHrefCommonOptions(sidebar, nested = false) { + return sidebar.map((item) => { + if (item.type === "separator") { + return item + } + + const updatedItem = { + ...commonOptions, + ...item, + children: sidebarAttachHrefCommonOptions(item.children || [], true), + } + + if (updatedItem.type !== "category" && !nested) { + updatedItem.childrenSameLevel = true + } + + return updatedItem + }) } diff --git a/www/apps/resources/app/layout.tsx b/www/apps/resources/app/layout.tsx index cbc36af4ae..3147e4e014 100644 --- a/www/apps/resources/app/layout.tsx +++ b/www/apps/resources/app/layout.tsx @@ -1,10 +1,8 @@ import type { Metadata } from "next" import { Inter, Roboto_Mono } from "next/font/google" - -import Navbar from "@/components/Navbar" import Providers from "@/providers" import "./globals.css" -import { Bannerv2, Breadcrumbs, TightLayout } from "docs-ui" +import { Breadcrumbs, TightLayout } from "docs-ui" import { config } from "@/config" import clsx from "clsx" import { Feedback } from "@/components/Feedback" @@ -41,14 +39,11 @@ export default function RootLayout({ return ( , }} bodyClassName={clsx(inter.variable, robotoMono.variable)} > - {children} diff --git a/www/apps/resources/app/medusa-workflows-reference/page.mdx b/www/apps/resources/app/medusa-workflows-reference/page.mdx index 0b282d532b..e520bc590c 100644 --- a/www/apps/resources/app/medusa-workflows-reference/page.mdx +++ b/www/apps/resources/app/medusa-workflows-reference/page.mdx @@ -10,4 +10,4 @@ This section of the documentation provides a reference to the workflows created You can use these workflows in your customizations as well. They're available in the `@medusajs/core-flows` package. - \ No newline at end of file + \ No newline at end of file diff --git a/www/apps/resources/components/Navbar/index.tsx b/www/apps/resources/components/Navbar/index.tsx deleted file mode 100644 index d25830efab..0000000000 --- a/www/apps/resources/components/Navbar/index.tsx +++ /dev/null @@ -1,38 +0,0 @@ -"use client" - -import { Navbar as UiNavbar, getNavbarItems } from "docs-ui" -import { useSidebar } from "docs-ui" -import { basePathUrl } from "../../utils/base-path-url" -import { useMemo } from "react" -import { config } from "../../config" - -const Navbar = () => { - const { setMobileSidebarOpen, mobileSidebarOpen } = useSidebar() - const navbarItems = useMemo( - () => - getNavbarItems({ - basePath: config.baseUrl, - activePath: basePathUrl(""), - version: "v2", - }), - [] - ) - - return ( - - ) -} - -export default Navbar diff --git a/www/apps/resources/config/index.ts b/www/apps/resources/config/index.ts index 5aa1b772fc..c9b7c3748a 100644 --- a/www/apps/resources/config/index.ts +++ b/www/apps/resources/config/index.ts @@ -1,4 +1,4 @@ -import { DocsConfig } from "types" +import { DocsConfig, SidebarItem } from "types" import { getMobileSidebarItems } from "docs-ui" import { generatedSidebar } from "../generated/sidebar.mjs" @@ -9,8 +9,7 @@ export const config: DocsConfig = { baseUrl, basePath: process.env.NEXT_PUBLIC_BASE_PATH, sidebar: { - top: generatedSidebar, - bottom: [], + default: generatedSidebar as SidebarItem[], mobile: getMobileSidebarItems({ baseUrl, version: "v2", diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs index f3312ecc56..a0de2985a1 100644 --- a/www/apps/resources/generated/sidebar.mjs +++ b/www/apps/resources/generated/sidebar.mjs @@ -2,29 +2,37 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/", "title": "Overview", - "hasTitleStyling": true, "children": [] }, { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules", "title": "Commerce Modules", "isChildSidebar": true, - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/api-key", + "type": "category", "title": "API Key Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/api-key", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/api-key/examples", "title": "Examples", "children": [] @@ -32,11 +40,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/api-key/concepts", "title": "API Key Concepts", "children": [] @@ -44,6 +54,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/api-key/relations-to-other-modules", "title": "Relation to Modules", "children": [] @@ -53,11 +64,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/api-key", "title": "Main Service Reference", "isChildSidebar": true, @@ -66,6 +79,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", "hasTitleStyling": true, "autogenerate_path": "/references/api_key/IApiKeyModuleService/methods", @@ -149,6 +163,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/api-key/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -157,6 +172,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", "hasTitleStyling": true, "autogenerate_path": "/references/api_key_models/classes", @@ -180,13 +196,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/auth", + "type": "category", "title": "Auth Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/api-key", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/auth/module-options", "title": "Module Options", "children": [] @@ -194,6 +218,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/auth/examples", "title": "Examples", "children": [] @@ -201,11 +226,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/auth/auth-identity-and-actor-types", "title": "Identity and Actor Types", "children": [] @@ -213,12 +240,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/auth/auth-providers", "title": "Auth Providers", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/auth/auth-providers/emailpass", "title": "Emailpass Auth Provider Module", "children": [] @@ -228,6 +257,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/auth/authentication-route", "title": "Authentication Route", "children": [] @@ -235,6 +265,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/auth/auth-flows", "title": "Auth Flows", "children": [] @@ -244,11 +275,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Guides", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/auth/create-actor-type", "title": "Create an Actor Type", "children": [] @@ -258,11 +291,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/auth/provider", "title": "Create Auth Provider Module", "children": [] @@ -270,6 +305,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/auth", "title": "Main Service Reference", "isChildSidebar": true, @@ -278,8 +314,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/auth/IAuthModuleService/methods", "children": [ { @@ -353,6 +389,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/auth/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -361,8 +398,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/auth_models/classes", "children": [ { @@ -392,13 +429,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/cart", + "type": "category", "title": "Cart Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/cart", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/cart/examples", "title": "Examples", "children": [] @@ -406,11 +451,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/cart/concepts", "title": "Cart Concepts", "children": [] @@ -418,6 +465,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/cart/promotions", "title": "Promotion Adjustments", "children": [] @@ -425,6 +473,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/cart/tax-lines", "title": "Tax Lines", "children": [] @@ -432,6 +481,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/cart/relations-to-other-modules", "title": "Relations to Other Modules", "children": [] @@ -441,11 +491,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/cart", "title": "Main Service Reference", "isChildSidebar": true, @@ -454,8 +506,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/cart/ICartModuleService/methods", "children": [ { @@ -865,6 +917,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/cart/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -873,8 +926,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/cart_models/classes", "children": [ { @@ -952,13 +1005,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/currency", - "title": "Currency Module", - "hasTitleStyling": true, + "type": "category", + "title": "Currency", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/currency", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/currency/examples", "title": "Examples", "children": [] @@ -966,11 +1027,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/currency/relations-to-other-modules", "title": "Relation to Modules", "children": [] @@ -980,11 +1043,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/currency", "title": "Main Service Reference", "isChildSidebar": true, @@ -993,8 +1058,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/currency/ICurrencyModuleService/methods", "children": [ { @@ -1028,6 +1093,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/currency/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -1036,8 +1102,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/currency_models/variables", "children": [ { @@ -1059,13 +1125,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/customer", - "title": "Customer Module", - "hasTitleStyling": true, + "type": "category", + "title": "Customer", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/customer", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/customer/examples", "title": "Examples", "children": [] @@ -1073,11 +1147,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/customer/customer-accounts", "title": "Customer Accounts", "children": [] @@ -1085,6 +1161,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/customer/relations-to-other-modules", "title": "Relations to Other Modules", "children": [] @@ -1094,11 +1171,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/customer", "title": "Main Service Reference", "isChildSidebar": true, @@ -1107,8 +1186,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/customer/ICustomerModuleService/methods", "children": [ { @@ -1310,6 +1389,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/customer/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -1318,8 +1398,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/customer_models/classes", "children": [ { @@ -1365,13 +1445,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/fulfillment", + "type": "category", "title": "Fulfillment Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/fulfillment", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/fulfillment/module-options", "title": "Module Options", "children": [] @@ -1379,11 +1467,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/fulfillment/concepts", "title": "Fulfillment Concepts", "children": [] @@ -1391,6 +1481,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/fulfillment/fulfillment-provider", "title": "Fulfillment Provider", "children": [] @@ -1398,6 +1489,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/fulfillment/shipping-option", "title": "Shipping Option", "children": [] @@ -1405,6 +1497,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/fulfillment/item-fulfillment", "title": "Item Fulfillment", "children": [] @@ -1412,6 +1505,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/fulfillment/relations-to-other-modules", "title": "Relations to Other Modules", "children": [] @@ -1421,11 +1515,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/fulfillment/provider", "title": "Create Fulfillment Provider Module", "children": [] @@ -1433,6 +1529,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/fulfillment", "title": "Main Service Reference", "isChildSidebar": true, @@ -1441,8 +1538,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/fulfillment/IFulfillmentModuleService/methods", "children": [ { @@ -1972,6 +2069,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/fulfillment/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -1980,6 +2078,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", "hasTitleStyling": true, "autogenerate_path": "/references/fulfillment_models/classes", @@ -2091,13 +2190,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/inventory", + "type": "category", "title": "Inventory Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/inventory", + "title": "Inventory Module", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/inventory/examples", "title": "Examples", "children": [] @@ -2105,11 +2212,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/inventory/concepts", "title": "Inventory Concepts", "children": [] @@ -2117,6 +2226,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/inventory/inventory-in-flows", "title": "Inventory in Flows", "children": [] @@ -2124,6 +2234,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/inventory/relations-to-other-modules", "title": "Relation to Modules", "children": [] @@ -2133,11 +2244,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/inventory_next", "title": "Main Service Reference", "isChildSidebar": true, @@ -2146,8 +2259,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/inventory_next/IInventoryService/methods", "children": [ { @@ -2437,6 +2550,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/inventory_next/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -2445,8 +2559,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/inventory_next_models/classes", "children": [ { @@ -2484,18 +2598,27 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/order", + "type": "category", "title": "Order Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/order", + "title": "Order Module", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/order/concepts", "title": "Order Concepts", "children": [] @@ -2503,6 +2626,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/order/promotion-adjustments", "title": "Promotions Adjustments", "children": [] @@ -2510,6 +2634,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/order/tax-lines", "title": "Tax Lines", "children": [] @@ -2517,6 +2642,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/order/transactions", "title": "Transactions", "children": [] @@ -2524,6 +2650,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/order/order-versioning", "title": "Order Versioning", "children": [] @@ -2531,6 +2658,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/order/return", "title": "Return", "children": [] @@ -2538,6 +2666,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/order/exchange", "title": "Exchange", "children": [] @@ -2545,6 +2674,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/order/claim", "title": "Claim", "children": [] @@ -2552,6 +2682,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/order/relations-to-other-modules", "title": "Relations to Other Modules", "children": [] @@ -2561,11 +2692,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/order", "title": "Main Service Reference", "isChildSidebar": true, @@ -2574,8 +2707,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/order/IOrderModuleService/methods", "children": [ { @@ -3609,6 +3742,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/order/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -3617,6 +3751,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", "hasTitleStyling": true, "autogenerate_path": "/references/order_models/classes", @@ -3808,13 +3943,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/payment", + "type": "category", "title": "Payment Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/payment", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/module-options", "title": "Module Options", "children": [] @@ -3822,6 +3965,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/examples", "title": "Examples", "children": [] @@ -3829,11 +3973,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/payment-collection", "title": "Payment Collections", "children": [] @@ -3841,6 +3987,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/payment-session", "title": "Payment Session", "children": [] @@ -3848,6 +3995,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/payment", "title": "Payment", "children": [] @@ -3855,12 +4003,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/payment-provider", "title": "Payment Provider Module", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/payment-provider/stripe", "title": "Stripe", "children": [] @@ -3870,6 +4020,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/webhook-events", "title": "Webhook Events", "children": [] @@ -3877,6 +4028,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/relation-to-other-modules", "title": "Relations to Other Modules", "children": [] @@ -3886,11 +4038,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Guides", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/payment-flow", "title": "Accept Payment Flow", "children": [] @@ -3900,11 +4054,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/payment/provider", "title": "Payment Provider Reference", "children": [] @@ -3912,6 +4068,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/payment", "title": "Main Service Reference", "isChildSidebar": true, @@ -3920,8 +4077,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/payment/IPaymentModuleService/methods", "children": [ { @@ -4171,6 +4328,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/payment/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -4179,8 +4337,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/payment_models/classes", "children": [ { @@ -4258,13 +4416,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/pricing", + "type": "category", "title": "Pricing Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/pricing", + "title": "Pricing Module", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/pricing/examples", "title": "Examples", "children": [] @@ -4272,11 +4438,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/pricing/concepts", "title": "Pricing Concepts", "children": [] @@ -4284,6 +4452,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/pricing/price-rules", "title": "Price Rules", "children": [] @@ -4291,6 +4460,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/pricing/price-calculation", "title": "Prices Calculation", "children": [] @@ -4298,6 +4468,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/pricing/tax-inclusive-pricing", "title": "Tax-Inclusive Pricing", "children": [] @@ -4305,6 +4476,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/pricing/relations-to-other-modules", "title": "Relation to Modules", "children": [] @@ -4314,11 +4486,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/pricing", "title": "Main Service Reference", "isChildSidebar": true, @@ -4327,8 +4501,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/pricing/IPricingModuleService/methods", "children": [ { @@ -4690,6 +4864,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/pricing/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -4698,6 +4873,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", "hasTitleStyling": true, "autogenerate_path": "/references/pricing_models/classes", @@ -4761,13 +4937,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/product", + "type": "category", "title": "Product Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/product", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/product/examples", "title": "Examples", "children": [] @@ -4775,11 +4959,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/product/relations-to-other-modules", "title": "Relation to Modules", "children": [] @@ -4789,6 +4975,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Guides", "autogenerate_path": "/commerce-modules/product/guides", "children": [ @@ -4813,11 +5000,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/product", "title": "Main Service Reference", "isChildSidebar": true, @@ -4826,8 +5015,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/product/IProductModuleService/methods", "children": [ { @@ -5341,6 +5530,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/product/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -5349,6 +5539,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", "hasTitleStyling": true, "autogenerate_path": "/references/product_models/classes", @@ -5436,13 +5627,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/promotion", + "type": "category", "title": "Promotion Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/promotion", + "title": "Promotion Module", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/promotion/examples", "title": "Examples", "children": [] @@ -5450,11 +5649,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/promotion/concepts", "title": "Promotion", "children": [] @@ -5462,6 +5663,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/promotion/application-method", "title": "Application Method", "children": [] @@ -5469,6 +5671,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/promotion/campaign", "title": "Campaign", "children": [] @@ -5476,6 +5679,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/promotion/actions", "title": "Promotion Actions", "children": [] @@ -5483,6 +5687,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/promotion/relations-to-other-modules", "title": "Relation to Modules", "children": [] @@ -5492,11 +5697,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/promotion", "title": "Main Service Reference", "isChildSidebar": true, @@ -5505,6 +5712,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", "hasTitleStyling": true, "autogenerate_path": "/references/promotion/IPromotionModuleService/methods", @@ -5740,6 +5948,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/promotion/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -5748,6 +5957,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", "hasTitleStyling": true, "autogenerate_path": "/references/promotion_models/classes", @@ -5811,13 +6021,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/region", + "type": "category", "title": "Region Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/region", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/region/examples", "title": "Examples", "children": [] @@ -5825,11 +6043,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/region/relations-to-other-modules", "title": "Relations to Other Modules", "children": [] @@ -5839,11 +6059,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/region", "title": "Main Service Reference", "isChildSidebar": true, @@ -5852,8 +6074,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/region/IRegionModuleService/methods", "children": [ { @@ -5959,6 +6181,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/region/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -5967,8 +6190,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/region_models/variables", "children": [ { @@ -5998,13 +6221,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/sales-channel", + "type": "category", "title": "Sales Channel Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/sales-channel", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/sales-channel/examples", "title": "Examples", "children": [] @@ -6012,11 +6243,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/sales-channel/publishable-api-keys", "title": "Publishable API Keys", "children": [] @@ -6024,6 +6257,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/sales-channel/relations-to-other-modules", "title": "Relation to Modules", "children": [] @@ -6033,11 +6267,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/sales-channel", "title": "Main Service Reference", "isChildSidebar": true, @@ -6046,8 +6282,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/sales_channel/ISalesChannelModuleService/methods", "children": [ { @@ -6129,6 +6365,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/sales-channel/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -6137,8 +6374,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/sales_channel_models/classes", "children": [ { @@ -6160,13 +6397,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/stock-location", + "type": "category", "title": "Stock Location Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/stock-location", + "title": "Stock Location Module", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/stock-location/examples", "title": "Examples", "children": [] @@ -6174,11 +6419,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/stock-location/concepts", "title": "Stock Location Concepts", "children": [] @@ -6186,6 +6433,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/stock-location/relations-to-other-modules", "title": "Relation to Modules", "children": [] @@ -6195,11 +6443,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/stock-location", "title": "Main Service Reference", "isChildSidebar": true, @@ -6208,8 +6458,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/stock_location_next/IStockLocationService/methods", "children": [ { @@ -6291,6 +6541,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/stock-location/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -6299,8 +6550,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/stock_location_next_models/classes", "children": [ { @@ -6330,13 +6581,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/store", + "type": "category", "title": "Store Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/store", + "title": "Store Module", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/store/examples", "title": "Examples", "children": [] @@ -6344,11 +6603,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/store/relations-to-other-modules", "title": "Relation to Modules", "children": [] @@ -6358,11 +6619,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/store", "title": "Main Service Reference", "isChildSidebar": true, @@ -6371,8 +6634,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/store/IStoreModuleService/methods", "children": [ { @@ -6454,6 +6717,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/store/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -6462,8 +6726,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/store_models/classes", "children": [ { @@ -6493,13 +6757,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/tax", + "type": "category", "title": "Tax Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/tax", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/tax/module-options", "title": "Module Options", "children": [] @@ -6507,6 +6779,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/tax/examples", "title": "Examples", "children": [] @@ -6514,11 +6787,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/tax/tax-region", "title": "Tax Region", "children": [] @@ -6526,6 +6801,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/tax/tax-rates-and-rules", "title": "Tax Rates and Rules", "children": [] @@ -6533,6 +6809,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/tax/tax-calculation-with-provider", "title": "Tax Calculation and Providers", "children": [] @@ -6542,11 +6819,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/tax/provider", "title": "Tax Provider Reference", "children": [] @@ -6554,6 +6833,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/tax", "title": "Main Service Reference", "isChildSidebar": true, @@ -6562,8 +6842,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/tax/ITaxModuleService/methods", "children": [ { @@ -6733,6 +7013,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/tax/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -6741,8 +7022,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", - "hasTitleStyling": true, "autogenerate_path": "/references/tax_models/classes", "children": [ { @@ -6788,13 +7069,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/commerce-modules/user", + "type": "category", "title": "User Module", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/commerce-modules/user", + "title": "User Module", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/commerce-modules/user/module-options", "title": "Module Options", "children": [] @@ -6802,6 +7091,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/user/examples", "title": "Examples", "children": [] @@ -6809,11 +7099,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Concepts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/user/user-creation-flows", "title": "User Creation Flows", "children": [] @@ -6823,11 +7115,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "References", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/user", "title": "Main Service Reference", "isChildSidebar": true, @@ -6836,8 +7130,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/user/IUserModuleService/methods", "children": [ { @@ -6991,6 +7285,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/user/models", "title": "Data Models Reference", "isChildSidebar": true, @@ -6999,6 +7294,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Data Models", "hasTitleStyling": true, "autogenerate_path": "/references/user_models/classes", @@ -7032,20 +7328,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/integrations", "title": "Integrations", "isChildSidebar": true, - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "File", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/file/s3", "title": "AWS S3 (and Compatible APIs)", "children": [] @@ -7055,12 +7352,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Notification", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/notification/sendgrid", "title": "SendGrid", "children": [] @@ -7070,12 +7368,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Payment", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/commerce-modules/payment/payment-provider/stripe", "title": "Stripe", "children": [] @@ -7087,20 +7386,22 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes", "title": "Recipes", - "hasTitleStyling": true, "isChildSidebar": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/marketplace", "title": "Marketplace", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/marketplace/examples/vendors", "title": "Example: Vendors", "children": [] @@ -7110,12 +7411,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/subscriptions", "title": "Subscriptions", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/subscriptions/examples/standard", "title": "Example", "children": [] @@ -7125,12 +7428,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/digital-products", "title": "Digital Products", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/digital-products/examples/standard", "title": "Example", "children": [] @@ -7140,6 +7445,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/b2b", "title": "B2B", "children": [] @@ -7147,6 +7453,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/commerce-automation", "title": "Commerce Automation", "children": [] @@ -7154,6 +7461,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/ecommerce", "title": "Ecommerce", "children": [] @@ -7161,6 +7469,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/integrate-ecommerce-stack", "title": "Integrate Ecommerce Stack", "children": [] @@ -7168,6 +7477,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/multi-region-store", "title": "Multi-Region Store", "children": [] @@ -7175,6 +7485,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/omnichannel", "title": "Omnichannel Store", "children": [] @@ -7182,6 +7493,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/oms", "title": "OMS", "children": [] @@ -7189,6 +7501,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/personalized-products", "title": "Personalized Products", "children": [] @@ -7196,21 +7509,26 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/recipes/pos", "title": "POS", "children": [] } ] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, + "type": "category", "title": "SDKs and Tools", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/create-medusa-app", "title": "create-medusa-app", "children": [] @@ -7218,6 +7536,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/medusa-cli", "title": "Medusa CLI", "children": [] @@ -7225,6 +7544,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/nextjs-starter", "title": "Next.js Starter", "children": [] @@ -7234,21 +7554,29 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules", "title": "Architectural Modules", "isChildSidebar": true, - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, - "path": "/architectural-modules/cache", + "type": "category", "title": "Cache Modules", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/architectural-modules/cache", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/architectural-modules/cache/in-memory", "title": "In-Memory", "children": [] @@ -7256,6 +7584,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/cache/redis", "title": "Redis", "children": [] @@ -7263,11 +7592,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Guides", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/cache/create", "title": "Create Cache Module", "children": [] @@ -7279,13 +7610,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/architectural-modules/event", + "type": "category", "title": "Event Modules", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/architectural-modules/event", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/architectural-modules/event/local", "title": "Local", "children": [] @@ -7293,6 +7632,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/event/redis", "title": "Redis", "children": [] @@ -7300,11 +7640,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Guides", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/event/create", "title": "Create Event Module", "children": [] @@ -7316,13 +7658,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/architectural-modules/file", + "type": "category", "title": "File Provider Modules", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/architectural-modules/file", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/architectural-modules/file/local", "title": "Local", "children": [] @@ -7330,6 +7680,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/file/s3", "title": "AWS S3 (and Compatible APIs)", "children": [] @@ -7337,11 +7688,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Guides", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/file-provider-module", "title": "Create File Provider", "children": [] @@ -7353,13 +7706,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/architectural-modules/notification", + "type": "category", "title": "Notification Provider Modules", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/architectural-modules/notification", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/architectural-modules/notification/local", "title": "Local", "children": [] @@ -7367,6 +7728,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/notification/sendgrid", "title": "SendGrid", "children": [] @@ -7374,11 +7736,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Guides", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/notification/send-notification", "title": "Send Notification", "children": [] @@ -7386,6 +7750,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/notification-provider-module", "title": "Create Notification Provider", "children": [] @@ -7397,13 +7762,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/architectural-modules/workflow-engine", + "type": "category", "title": "Workflow Engine Modules", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/architectural-modules/workflow-engine", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/architectural-modules/workflow-engine/in-memory", "title": "In-Memory", "children": [] @@ -7411,6 +7784,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/architectural-modules/workflow-engine/redis", "title": "Redis", "children": [] @@ -7422,27 +7796,40 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development", "title": "Storefront Development", - "hasTitleStyling": true, "isChildSidebar": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/tips", "title": "Tips", "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, - "path": "/storefront-development/regions", + "type": "category", "title": "Regions", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/storefront-development/regions", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/storefront-development/regions/list", "title": "List Regions", "children": [] @@ -7450,6 +7837,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/regions/store-retrieve-region", "title": "Store and Retrieve Regions", "children": [] @@ -7457,6 +7845,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/regions/context", "title": "Region React Context", "children": [] @@ -7466,12 +7855,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/storefront-development/products", + "type": "category", "title": "Products", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/storefront-development/products", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/storefront-development/products/list", "title": "List Products", "children": [] @@ -7479,6 +7877,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/retrieve", "title": "Retrieve a Product", "children": [] @@ -7486,6 +7885,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/variants", "title": "Select a Variant", "children": [] @@ -7493,6 +7893,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/price", "title": "Retrieve Variant Prices", "autogenerate_path": "storefront-development/products/price/examples", @@ -7526,12 +7927,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/categories", "title": "Categories", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/categories/list", "title": "List Categories", "children": [] @@ -7539,6 +7942,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/categories/retrieve", "title": "Retrieve a Category", "children": [] @@ -7546,6 +7950,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/categories/products", "title": "Retrieve a Category's Products", "children": [] @@ -7553,6 +7958,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/categories/nested-categories", "title": "Retrieve Nested Categories", "children": [] @@ -7562,12 +7968,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/collections", "title": "Collections", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/collections/list", "title": "List Collections", "children": [] @@ -7575,6 +7983,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/collections/retrieve", "title": "Retrieve a Collection", "children": [] @@ -7582,6 +7991,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/products/collections/products", "title": "Retrieve a Collection's Products", "children": [] @@ -7593,12 +8003,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/storefront-development/cart", + "type": "category", "title": "Carts", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/storefront-development/cart", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/storefront-development/cart/create", "title": "Create Cart", "children": [] @@ -7606,6 +8025,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/cart/retrieve", "title": "Retrieve Cart", "children": [] @@ -7613,6 +8033,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/cart/context", "title": "Cart React Context", "children": [] @@ -7620,6 +8041,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/cart/update", "title": "Update Cart", "children": [] @@ -7627,6 +8049,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/cart/manage-items", "title": "Manage Line Items", "children": [] @@ -7636,12 +8059,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/storefront-development/checkout", + "type": "category", "title": "Checkout", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/storefront-development/checkout", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/storefront-development/checkout/email", "title": "1. Enter Email", "children": [] @@ -7649,6 +8081,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/checkout/address", "title": "2. Enter Address", "children": [] @@ -7656,6 +8089,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/checkout/shipping", "title": "3. Choose Shipping Method", "children": [] @@ -7663,12 +8097,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/checkout/payment", "title": "4. Choose Payment Provider", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/checkout/payment/stripe", "title": "Example: Stripe", "children": [] @@ -7678,6 +8114,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/checkout/complete-cart", "title": "5. Complete Cart", "children": [] @@ -7687,12 +8124,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/storefront-development/customers", + "type": "category", "title": "Customers", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", + "path": "/storefront-development/customers", + "title": "Overview", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", "path": "/storefront-development/customers/register", "title": "Register Customer", "children": [] @@ -7700,6 +8146,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/customers/login", "title": "Login Customer", "children": [] @@ -7707,6 +8154,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/customers/retrieve", "title": "Retrieve Customer", "children": [] @@ -7714,6 +8162,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/customers/context", "title": "Customer React Context", "children": [] @@ -7721,6 +8170,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/customers/profile", "title": "Edit Customer Profile", "children": [] @@ -7728,6 +8178,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/customers/addresses", "title": "Manage Customer Addresses", "children": [] @@ -7735,6 +8186,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/storefront-development/customers/log-out", "title": "Log-out Customer", "children": [] @@ -7746,20 +8198,24 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/medusa-config", "title": "Medusa Configurations", - "hasTitleStyling": true, "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, + "type": "category", "title": "General", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/upgrade-guides", "title": "Upgrade Guides", "children": [] @@ -7767,6 +8223,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/deployment", "title": "Deployment Guides", "isChildSidebar": true, @@ -7774,8 +8231,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Medusa Application", - "hasTitleStyling": true, "autogenerate_path": "/deployment/medusa-application", "children": [ { @@ -7791,8 +8248,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Medusa Admin", - "hasTitleStyling": true, "autogenerate_path": "/deployment/admin", "children": [ { @@ -7808,8 +8265,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Next.js Starter", - "hasTitleStyling": true, "autogenerate_path": "/deployment/storefront", "children": [ { @@ -7827,6 +8284,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting", "title": "Troubleshooting Guides", "isChildSidebar": true, @@ -7834,12 +8292,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Installation", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting/create-medusa-app-errors", "title": "Create Medusa App Errors", "children": [] @@ -7847,6 +8306,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting/errors-installing-cli", "title": "Errors Installing CLI", "children": [] @@ -7854,6 +8314,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting/pnpm-errors", "title": "pnpm Errors", "children": [] @@ -7861,6 +8322,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting/general-errors", "title": "General Errors", "children": [] @@ -7870,12 +8332,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Medusa Application", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting/eaddrinuse", "title": "EADDRINUSE Error", "children": [] @@ -7883,6 +8346,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting/database-errors", "title": "Database Errors", "children": [] @@ -7892,12 +8356,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Upgrade", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting/errors-after-upgrading", "title": "Errors After Upgrading", "children": [] @@ -7907,12 +8372,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Frontend", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting/cors-errors", "title": "CORS Errors", "children": [] @@ -7922,12 +8388,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Integrations", "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/troubleshooting/s3", "title": "S3 Module Provider Errors", "children": [] @@ -7941,12 +8409,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Lists", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/medusa-container-resources", "title": "Medusa Container Resources", "children": [] @@ -7954,6 +8423,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/admin-widget-injection-zones", "title": "Admin Widget Injection Zones", "children": [] @@ -7963,12 +8433,13 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "References", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/workflows", "title": "Workflow API", "isChildSidebar": true, @@ -7976,8 +8447,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Functions", - "hasTitleStyling": true, "autogenerate_path": "/references/workflows/functions", "children": [ { @@ -8035,6 +8506,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/data-model", "title": "Data Model API", "childSidebarTitle": "Data Model API Reference", @@ -8043,17 +8515,19 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/data-model/define", "title": "Define Method", - "hasTitleStyling": true, "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, - "path": "/references/data-model/property-types", + "type": "category", "title": "Property Types", - "hasTitleStyling": true, "autogenerate_path": "/references/dml/Property_Types/methods", "children": [ { @@ -8133,9 +8607,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/references/data-model/relationship-methods", + "type": "category", "title": "Relationship Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/dml/Relationship_Methods/methods", "children": [ { @@ -8175,9 +8648,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/references/data-model/model-methods", + "type": "category", "title": "Model Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/dml/Model_Methods/methods", "children": [ { @@ -8201,9 +8673,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, - "path": "/references/data-model/property-configuration", + "type": "category", "title": "Property Configuration Methods", - "hasTitleStyling": true, "autogenerate_path": "/references/dml/Property_Configuration_Methods/methods", "children": [ { @@ -8245,6 +8716,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/service-factory-reference", "title": "Service Factory Reference", "isChildSidebar": true, @@ -8252,8 +8724,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Methods", - "hasTitleStyling": true, "autogenerate_path": "/service-factory-reference/methods", "children": [ { @@ -8325,8 +8797,8 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Tips", - "hasTitleStyling": true, "autogenerate_path": "/service-factory-reference/tips", "children": [ { @@ -8344,6 +8816,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/references/helper-steps", "title": "Helper Steps Reference", "isChildSidebar": true, @@ -8402,11 +8875,22 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "title": "Medusa Workflows Reference", "path": "/medusa-workflows-reference", "isChildSidebar": true, "custom_autogenerate": "core-flows", "children": [ + { + "type": "link", + "title": "Overview", + "path": "/medusa-workflows-reference", + "loaded": true, + "isPathHref": true + }, + { + "type": "separator" + }, { "type": "category", "title": "Api Key", @@ -8455,7 +8939,8 @@ export const generatedSidebar = [ "title": "updateApiKeysWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -8509,9 +8994,12 @@ export const generatedSidebar = [ "title": "validateSalesChannelsExistStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -8529,9 +9017,12 @@ export const generatedSidebar = [ "title": "setAuthAppMetadataStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -8573,7 +9064,8 @@ export const generatedSidebar = [ "title": "updateLinksWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -8627,9 +9119,12 @@ export const generatedSidebar = [ "title": "useRemoteQueryStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -8695,7 +9190,8 @@ export const generatedSidebar = [ "title": "updateCustomersWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -8765,9 +9261,12 @@ export const generatedSidebar = [ "title": "updateCustomersStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -8809,7 +9308,8 @@ export const generatedSidebar = [ "title": "updateCustomerGroupsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -8847,9 +9347,12 @@ export const generatedSidebar = [ "title": "updateCustomerGroupsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -8867,7 +9370,8 @@ export const generatedSidebar = [ "title": "createDefaultsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -8881,9 +9385,12 @@ export const generatedSidebar = [ "title": "createDefaultStoreStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -8997,7 +9504,8 @@ export const generatedSidebar = [ "title": "updateTaxLinesWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -9283,9 +9791,12 @@ export const generatedSidebar = [ "title": "validateVariantPricesStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -9311,7 +9822,8 @@ export const generatedSidebar = [ "title": "uploadFilesWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -9333,9 +9845,12 @@ export const generatedSidebar = [ "title": "uploadFilesStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -9465,7 +9980,8 @@ export const generatedSidebar = [ "title": "updateShippingProfilesWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -9607,9 +10123,12 @@ export const generatedSidebar = [ "title": "validateShipmentStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -9675,7 +10194,8 @@ export const generatedSidebar = [ "title": "updateInventoryLevelsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -9769,9 +10289,12 @@ export const generatedSidebar = [ "title": "validateInventoryLocationsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -9813,7 +10336,8 @@ export const generatedSidebar = [ "title": "refreshInviteTokensWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -9851,9 +10375,12 @@ export const generatedSidebar = [ "title": "validateTokenStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -10367,7 +10894,8 @@ export const generatedSidebar = [ "title": "updateReturnWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -11061,9 +11589,12 @@ export const generatedSidebar = [ "title": "updateReturnsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -11089,7 +11620,8 @@ export const generatedSidebar = [ "title": "refundPaymentWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -11127,9 +11659,12 @@ export const generatedSidebar = [ "title": "refundPaymentStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -11171,7 +11706,8 @@ export const generatedSidebar = [ "title": "updateRefundReasonsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -11233,9 +11769,12 @@ export const generatedSidebar = [ "title": "validateDeletedPaymentSessionsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -11301,7 +11840,8 @@ export const generatedSidebar = [ "title": "updatePriceListsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -11379,9 +11919,12 @@ export const generatedSidebar = [ "title": "validateVariantPriceLinksStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -11415,7 +11958,8 @@ export const generatedSidebar = [ "title": "updatePricePreferencesWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -11469,9 +12013,12 @@ export const generatedSidebar = [ "title": "updatePriceSetsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -11681,7 +12228,8 @@ export const generatedSidebar = [ "title": "upsertVariantPricesWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -11895,9 +12443,12 @@ export const generatedSidebar = [ "title": "waitConfirmationProductImportStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -11931,7 +12482,8 @@ export const generatedSidebar = [ "title": "updateProductCategoriesWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -11961,9 +12513,12 @@ export const generatedSidebar = [ "title": "updateProductCategoriesStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12061,7 +12616,8 @@ export const generatedSidebar = [ "title": "updatePromotionsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12155,9 +12711,12 @@ export const generatedSidebar = [ "title": "updatePromotionsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12191,7 +12750,8 @@ export const generatedSidebar = [ "title": "updateRegionsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12221,9 +12781,12 @@ export const generatedSidebar = [ "title": "updateRegionsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12265,7 +12828,8 @@ export const generatedSidebar = [ "title": "updateReservationsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12303,9 +12867,12 @@ export const generatedSidebar = [ "title": "updateReservationsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12339,7 +12906,8 @@ export const generatedSidebar = [ "title": "updateReturnReasonsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12369,9 +12937,12 @@ export const generatedSidebar = [ "title": "updateReturnReasonsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12413,7 +12984,8 @@ export const generatedSidebar = [ "title": "updateSalesChannelsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12483,9 +13055,12 @@ export const generatedSidebar = [ "title": "updateSalesChannelsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12503,9 +13078,12 @@ export const generatedSidebar = [ "title": "listShippingOptionsForContextStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12523,7 +13101,8 @@ export const generatedSidebar = [ "title": "deleteShippingProfileWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12537,9 +13116,12 @@ export const generatedSidebar = [ "title": "deleteShippingProfilesStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12589,7 +13171,8 @@ export const generatedSidebar = [ "title": "updateStockLocationsWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12619,9 +13202,12 @@ export const generatedSidebar = [ "title": "updateStockLocationsStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12655,7 +13241,8 @@ export const generatedSidebar = [ "title": "updateStoresWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12685,9 +13272,12 @@ export const generatedSidebar = [ "title": "updateStoresStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12761,7 +13351,8 @@ export const generatedSidebar = [ "title": "updateTaxRatesWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12847,9 +13438,12 @@ export const generatedSidebar = [ "title": "updateTaxRatesStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false }, { "type": "category", @@ -12891,7 +13485,8 @@ export const generatedSidebar = [ "title": "updateUsersWorkflow", "children": [] } - ] + ], + "loaded": true }, { "type": "sub-category", @@ -12921,9 +13516,12 @@ export const generatedSidebar = [ "title": "updateUsersStep", "children": [] } - ] + ], + "loaded": true } - ] + ], + "loaded": true, + "initialOpen": false } ] } @@ -12932,17 +13530,19 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "title": "Other", - "hasTitleStyling": true, "children": [ { "loaded": true, "isPathHref": true, + "type": "sub-category", "title": "Contribution Guidelines", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/contribution-guidelines/docs", "title": "Docs", "children": [] @@ -12952,6 +13552,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/usage", "title": "Usage", "children": [] diff --git a/www/apps/resources/providers/index.tsx b/www/apps/resources/providers/index.tsx index c10f756a6d..b7c29a53d3 100644 --- a/www/apps/resources/providers/index.tsx +++ b/www/apps/resources/providers/index.tsx @@ -16,6 +16,7 @@ import { import SidebarProvider from "./sidebar" import SearchProvider from "./search" import { config } from "../config" +import { MainNavProvider } from "./main-nav" type ProvidersProps = { children?: React.ReactNode @@ -35,16 +36,18 @@ const Providers = ({ children }: ProvidersProps) => { - - - {children} - - + + + + {children} + + + diff --git a/www/apps/resources/providers/main-nav.tsx b/www/apps/resources/providers/main-nav.tsx new file mode 100644 index 0000000000..9bd9970e2d --- /dev/null +++ b/www/apps/resources/providers/main-nav.tsx @@ -0,0 +1,46 @@ +"use client" + +import { + formatReportLink, + getNavDropdownItems, + MainNavProvider as UiMainNavProvider, + useIsBrowser, +} from "docs-ui" +import { useMemo } from "react" +import { config } from "../config" +import { basePathUrl } from "../utils/base-path-url" + +type MainNavProviderProps = { + children?: React.ReactNode +} + +export const MainNavProvider = ({ children }: MainNavProviderProps) => { + const isBrowser = useIsBrowser() + const navigationDropdownItems = useMemo( + () => + getNavDropdownItems({ + basePath: config.baseUrl, + activePath: basePathUrl(), + version: "v2", + }), + [] + ) + + const reportLink = useMemo( + () => + formatReportLink( + config.titleSuffix || "", + isBrowser ? document.title : "" + ), + [isBrowser] + ) + + return ( + + {children} + + ) +} diff --git a/www/apps/resources/providers/sidebar.tsx b/www/apps/resources/providers/sidebar.tsx index 5c8ce3c927..4562e1fc8c 100644 --- a/www/apps/resources/providers/sidebar.tsx +++ b/www/apps/resources/providers/sidebar.tsx @@ -20,7 +20,6 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => { initialItems={config.sidebar} staticSidebarItems={true} disableActiveTransition={true} - noTitleStyling={true} > {children} diff --git a/www/apps/resources/sidebar.mjs b/www/apps/resources/sidebar.mjs index c3d1b56ef4..775af4541a 100644 --- a/www/apps/resources/sidebar.mjs +++ b/www/apps/resources/sidebar.mjs @@ -1,50 +1,61 @@ import { sidebarAttachHrefCommonOptions } from "./utils/sidebar-attach-common-options.mjs" -/** @type {import('types').RawSidebarItemType[]} */ +/** @type {import('types').RawSidebarItem[]} */ export const sidebar = sidebarAttachHrefCommonOptions([ { + type: "link", path: "/", title: "Overview", - hasTitleStyling: true, }, { + type: "link", path: "/commerce-modules", title: "Commerce Modules", isChildSidebar: true, - hasTitleStyling: true, children: [ { - path: "/commerce-modules/api-key", + type: "category", title: "API Key Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/api-key", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/api-key/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/api-key/concepts", title: "API Key Concepts", }, { + type: "link", path: "/commerce-modules/api-key/relations-to-other-modules", title: "Relation to Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/api-key", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "API Key Module's Main Service Reference", children: [ { + type: "category", title: "Methods", hasTitleStyling: true, autogenerate_path: @@ -53,12 +64,14 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { + type: "link", path: "/references/api-key/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "API Key Module Data Models Reference", children: [ { + type: "category", title: "Data Models", hasTitleStyling: true, autogenerate_path: "/references/api_key_models/classes", @@ -74,84 +87,102 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/auth", + type: "category", title: "Auth Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/api-key", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/auth/module-options", title: "Module Options", }, { + type: "link", path: "/commerce-modules/auth/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/auth/auth-identity-and-actor-types", title: "Identity and Actor Types", }, { + type: "link", path: "/commerce-modules/auth/auth-providers", title: "Auth Providers", children: [ { + type: "link", path: "/commerce-modules/auth/auth-providers/emailpass", title: "Emailpass Auth Provider Module", }, ], }, { + type: "link", path: "/commerce-modules/auth/authentication-route", title: "Authentication Route", }, { + type: "link", path: "/commerce-modules/auth/auth-flows", title: "Auth Flows", }, ], }, { + type: "sub-category", title: "Guides", children: [ { + type: "link", path: "/commerce-modules/auth/create-actor-type", title: "Create an Actor Type", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/auth/provider", title: "Create Auth Provider Module", }, { + type: "link", path: "/references/auth", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Auth Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/auth/IAuthModuleService/methods", }, ], }, { + type: "link", path: "/references/auth/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Auth Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/auth_models/classes", }, ], @@ -165,61 +196,74 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/cart", + type: "category", title: "Cart Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/cart", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/cart/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/cart/concepts", title: "Cart Concepts", }, { + type: "link", path: "/commerce-modules/cart/promotions", title: "Promotion Adjustments", }, { + type: "link", path: "/commerce-modules/cart/tax-lines", title: "Tax Lines", }, { + type: "link", path: "/commerce-modules/cart/relations-to-other-modules", title: "Relations to Other Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/cart", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Cart Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/cart/ICartModuleService/methods", }, ], }, { + type: "link", path: "/references/cart/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Cart Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/cart_models/classes", }, ], @@ -233,49 +277,59 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/currency", - title: "Currency Module", - hasTitleStyling: true, + type: "category", + title: "Currency", children: [ { + type: "link", + path: "/commerce-modules/currency", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/currency/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/currency/relations-to-other-modules", title: "Relation to Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/currency", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Cart Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/currency/ICurrencyModuleService/methods", }, ], }, { + type: "link", path: "/references/currency/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Currency Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/currency_models/variables", }, ], @@ -289,53 +343,64 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/customer", - title: "Customer Module", - hasTitleStyling: true, + type: "category", + title: "Customer", children: [ { + type: "link", + path: "/commerce-modules/customer", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/customer/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/customer/customer-accounts", title: "Customer Accounts", }, { + type: "link", path: "/commerce-modules/customer/relations-to-other-modules", title: "Relations to Other Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/customer", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Customer Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/customer/ICustomerModuleService/methods", }, ], }, { + type: "link", path: "/references/customer/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Customer Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/customer_models/classes", }, ], @@ -349,47 +414,61 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/fulfillment", + type: "category", title: "Fulfillment Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/fulfillment", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/fulfillment/module-options", title: "Module Options", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/fulfillment/concepts", title: "Fulfillment Concepts", }, { + type: "link", path: "/commerce-modules/fulfillment/fulfillment-provider", title: "Fulfillment Provider", }, { + type: "link", path: "/commerce-modules/fulfillment/shipping-option", title: "Shipping Option", }, { + type: "link", path: "/commerce-modules/fulfillment/item-fulfillment", title: "Item Fulfillment", }, { + type: "link", path: "/commerce-modules/fulfillment/relations-to-other-modules", title: "Relations to Other Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/fulfillment/provider", title: "Create Fulfillment Provider Module", }, { + type: "link", path: "/references/fulfillment", title: "Main Service Reference", isChildSidebar: true, @@ -397,20 +476,22 @@ export const sidebar = sidebarAttachHrefCommonOptions([ "Fulfillment Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/fulfillment/IFulfillmentModuleService/methods", }, ], }, { + type: "link", path: "/references/fulfillment/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Fulfillment Module Data Models Reference", children: [ { + type: "category", title: "Data Models", hasTitleStyling: true, autogenerate_path: "/references/fulfillment_models/classes", @@ -426,57 +507,69 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/inventory", + type: "category", title: "Inventory Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/inventory", + title: "Inventory Module", + }, + { + type: "link", path: "/commerce-modules/inventory/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/inventory/concepts", title: "Inventory Concepts", }, { + type: "link", path: "/commerce-modules/inventory/inventory-in-flows", title: "Inventory in Flows", }, { + type: "link", path: "/commerce-modules/inventory/relations-to-other-modules", title: "Relation to Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/inventory_next", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Inventory Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/inventory_next/IInventoryService/methods", }, ], }, { + type: "link", path: "/references/inventory_next/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Inventory Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/inventory_next_models/classes", }, @@ -491,75 +584,93 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/order", + type: "category", title: "Order Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/order", + title: "Order Module", + }, + { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/order/concepts", title: "Order Concepts", }, { + type: "link", path: "/commerce-modules/order/promotion-adjustments", title: "Promotions Adjustments", }, { + type: "link", path: "/commerce-modules/order/tax-lines", title: "Tax Lines", }, { + type: "link", path: "/commerce-modules/order/transactions", title: "Transactions", }, { + type: "link", path: "/commerce-modules/order/order-versioning", title: "Order Versioning", }, { + type: "link", path: "/commerce-modules/order/return", title: "Return", }, { + type: "link", path: "/commerce-modules/order/exchange", title: "Exchange", }, { + type: "link", path: "/commerce-modules/order/claim", title: "Claim", }, { + type: "link", path: "/commerce-modules/order/relations-to-other-modules", title: "Relations to Other Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/order", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Order Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/order/IOrderModuleService/methods", }, ], }, { + type: "link", path: "/references/order/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Order Module Data Models Reference", children: [ { + type: "category", title: "Data Models", hasTitleStyling: true, autogenerate_path: "/references/order_models/classes", @@ -575,92 +686,112 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/payment", + type: "category", title: "Payment Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/payment", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/payment/module-options", title: "Module Options", }, { + type: "link", path: "/commerce-modules/payment/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/payment/payment-collection", title: "Payment Collections", }, { + type: "link", path: "/commerce-modules/payment/payment-session", title: "Payment Session", }, { + type: "link", path: "/commerce-modules/payment/payment", title: "Payment", }, { + type: "link", path: "/commerce-modules/payment/payment-provider", title: "Payment Provider Module", children: [ { + type: "link", path: "/commerce-modules/payment/payment-provider/stripe", title: "Stripe", }, ], }, { + type: "link", path: "/commerce-modules/payment/webhook-events", title: "Webhook Events", }, { + type: "link", path: "/commerce-modules/payment/relation-to-other-modules", title: "Relations to Other Modules", }, ], }, { + type: "sub-category", title: "Guides", children: [ { + type: "link", path: "/commerce-modules/payment/payment-flow", title: "Accept Payment Flow", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/payment/provider", title: "Payment Provider Reference", }, { + type: "link", path: "/references/payment", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Payment Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/payment/IPaymentModuleService/methods", }, ], }, { + type: "link", path: "/references/payment/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Payment Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/payment_models/classes", }, ], @@ -674,63 +805,78 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/pricing", + type: "category", title: "Pricing Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/pricing", + title: "Pricing Module", + }, + { + type: "link", path: "/commerce-modules/pricing/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/pricing/concepts", title: "Pricing Concepts", }, { + type: "link", path: "/commerce-modules/pricing/price-rules", title: "Price Rules", }, { + type: "link", path: "/commerce-modules/pricing/price-calculation", title: "Prices Calculation", }, { + type: "link", path: "/commerce-modules/pricing/tax-inclusive-pricing", title: "Tax-Inclusive Pricing", }, { + type: "link", path: "/commerce-modules/pricing/relations-to-other-modules", title: "Relation to Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/pricing", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Pricing Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/pricing/IPricingModuleService/methods", }, ], }, { + type: "link", path: "/references/pricing/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Pricing Module Data Models Reference", children: [ { + type: "category", title: "Data Models", hasTitleStyling: true, autogenerate_path: "/references/pricing_models/classes", @@ -746,51 +892,63 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/product", + type: "category", title: "Product Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/product", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/product/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/product/relations-to-other-modules", title: "Relation to Modules", }, ], }, { + type: "sub-category", title: "Guides", autogenerate_path: "/commerce-modules/product/guides", }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/product", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Product Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/product/IProductModuleService/methods", }, ], }, { + type: "link", path: "/references/product/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Product Module Data Models Reference", children: [ { + type: "category", title: "Data Models", hasTitleStyling: true, autogenerate_path: "/references/product_models/classes", @@ -806,49 +964,63 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/promotion", + type: "category", title: "Promotion Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/promotion", + title: "Promotion Module", + }, + { + type: "link", path: "/commerce-modules/promotion/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/promotion/concepts", title: "Promotion", }, { + type: "link", path: "/commerce-modules/promotion/application-method", title: "Application Method", }, { + type: "link", path: "/commerce-modules/promotion/campaign", title: "Campaign", }, { + type: "link", path: "/commerce-modules/promotion/actions", title: "Promotion Actions", }, { + type: "link", path: "/commerce-modules/promotion/relations-to-other-modules", title: "Relation to Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/promotion", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Promotion Module's Main Service Reference", children: [ { + type: "category", title: "Methods", hasTitleStyling: true, autogenerate_path: @@ -857,12 +1029,14 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { + type: "link", path: "/references/promotion/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Promotion Module Data Models Reference", children: [ { + type: "category", title: "Data Models", hasTitleStyling: true, autogenerate_path: "/references/promotion_models/classes", @@ -878,49 +1052,59 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/region", + type: "category", title: "Region Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/region", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/region/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/region/relations-to-other-modules", title: "Relations to Other Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/region", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Region Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/region/IRegionModuleService/methods", }, ], }, { + type: "link", path: "/references/region/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Region Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/region_models/variables", }, ], @@ -934,31 +1118,41 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/sales-channel", + type: "category", title: "Sales Channel Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/sales-channel", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/sales-channel/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/sales-channel/publishable-api-keys", title: "Publishable API Keys", }, { + type: "link", path: "/commerce-modules/sales-channel/relations-to-other-modules", title: "Relation to Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/sales-channel", title: "Main Service Reference", isChildSidebar: true, @@ -966,22 +1160,23 @@ export const sidebar = sidebarAttachHrefCommonOptions([ "Sales Channel Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/sales_channel/ISalesChannelModuleService/methods", }, ], }, { + type: "link", path: "/references/sales-channel/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Sales Channel Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/sales_channel_models/classes", }, @@ -996,31 +1191,41 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/stock-location", + type: "category", title: "Stock Location Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/stock-location", + title: "Stock Location Module", + }, + { + type: "link", path: "/commerce-modules/stock-location/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/stock-location/concepts", title: "Stock Location Concepts", }, { + type: "link", path: "/commerce-modules/stock-location/relations-to-other-modules", title: "Relation to Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/stock-location", title: "Main Service Reference", isChildSidebar: true, @@ -1028,14 +1233,15 @@ export const sidebar = sidebarAttachHrefCommonOptions([ "Stock Location Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/stock_location_next/IStockLocationService/methods", }, ], }, { + type: "link", path: "/references/stock-location/models", title: "Data Models Reference", isChildSidebar: true, @@ -1043,8 +1249,8 @@ export const sidebar = sidebarAttachHrefCommonOptions([ "Stock Location Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/stock_location_next_models/classes", }, @@ -1059,49 +1265,59 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/store", + type: "category", title: "Store Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/store", + title: "Store Module", + }, + { + type: "link", path: "/commerce-modules/store/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/store/relations-to-other-modules", title: "Relation to Modules", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/store", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Store Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/store/IStoreModuleService/methods", }, ], }, { + type: "link", path: "/references/store/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Store Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/store_models/classes", }, ], @@ -1115,65 +1331,79 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/tax", + type: "category", title: "Tax Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/tax", + title: "Overview", + }, + { + type: "link", path: "/commerce-modules/tax/module-options", title: "Module Options", }, { + type: "link", path: "/commerce-modules/tax/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/tax/tax-region", title: "Tax Region", }, { + type: "link", path: "/commerce-modules/tax/tax-rates-and-rules", title: "Tax Rates and Rules", }, { + type: "link", path: "/commerce-modules/tax/tax-calculation-with-provider", title: "Tax Calculation and Providers", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/tax/provider", title: "Tax Provider Reference", }, { + type: "link", path: "/references/tax", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "Tax Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/tax/ITaxModuleService/methods", }, ], }, { + type: "link", path: "/references/tax/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "Tax Module Data Models Reference", children: [ { + type: "category", title: "Data Models", - hasTitleStyling: true, autogenerate_path: "/references/tax_models/classes", }, ], @@ -1187,51 +1417,63 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/commerce-modules/user", + type: "category", title: "User Module", - hasTitleStyling: true, children: [ { + type: "link", + path: "/commerce-modules/user", + title: "User Module", + }, + { + type: "link", path: "/commerce-modules/user/module-options", title: "Module Options", }, { + type: "link", path: "/commerce-modules/user/examples", title: "Examples", }, { + type: "sub-category", title: "Concepts", children: [ { + type: "link", path: "/commerce-modules/user/user-creation-flows", title: "User Creation Flows", }, ], }, { + type: "sub-category", title: "References", children: [ { + type: "link", path: "/references/user", title: "Main Service Reference", isChildSidebar: true, childSidebarTitle: "User Module's Main Service Reference", children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/references/user/IUserModuleService/methods", }, ], }, { + type: "link", path: "/references/user/models", title: "Data Models Reference", isChildSidebar: true, childSidebarTitle: "User Module Data Models Reference", children: [ { + type: "category", title: "Data Models", hasTitleStyling: true, autogenerate_path: "/references/user_models/classes", @@ -1249,36 +1491,39 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { + type: "link", path: "/integrations", title: "Integrations", isChildSidebar: true, - hasTitleStyling: true, children: [ { + type: "category", title: "File", - hasTitleStyling: true, children: [ { + type: "link", path: "/architectural-modules/file/s3", title: "AWS S3 (and Compatible APIs)", }, ], }, { + type: "category", title: "Notification", - hasTitleStyling: true, children: [ { + type: "link", path: "/architectural-modules/notification/sendgrid", title: "SendGrid", }, ], }, { + type: "category", title: "Payment", - hasTitleStyling: true, children: [ { + type: "link", path: "/commerce-modules/payment/payment-provider/stripe", title: "Stripe", }, @@ -1286,122 +1531,150 @@ export const sidebar = sidebarAttachHrefCommonOptions([ }, ], }, - { + type: "link", path: "/recipes", title: "Recipes", - hasTitleStyling: true, isChildSidebar: true, children: [ { + type: "link", path: "/recipes/marketplace", title: "Marketplace", children: [ { + type: "link", path: "/recipes/marketplace/examples/vendors", title: "Example: Vendors", }, ], }, { + type: "link", path: "/recipes/subscriptions", title: "Subscriptions", children: [ { + type: "link", path: "/recipes/subscriptions/examples/standard", title: "Example", }, ], }, { + type: "link", path: "/recipes/digital-products", title: "Digital Products", children: [ { + type: "link", path: "/recipes/digital-products/examples/standard", title: "Example", }, ], }, { + type: "link", path: "/recipes/b2b", title: "B2B", }, { + type: "link", path: "/recipes/commerce-automation", title: "Commerce Automation", }, { + type: "link", path: "/recipes/ecommerce", title: "Ecommerce", }, { + type: "link", path: "/recipes/integrate-ecommerce-stack", title: "Integrate Ecommerce Stack", }, { + type: "link", path: "/recipes/multi-region-store", title: "Multi-Region Store", }, { + type: "link", path: "/recipes/omnichannel", title: "Omnichannel Store", }, { + type: "link", path: "/recipes/oms", title: "OMS", }, { + type: "link", path: "/recipes/personalized-products", title: "Personalized Products", }, { + type: "link", path: "/recipes/pos", title: "POS", }, ], }, { + type: "separator", + }, + { + type: "category", title: "SDKs and Tools", - hasTitleStyling: true, children: [ { + type: "link", path: "/create-medusa-app", title: "create-medusa-app", }, { + type: "link", path: "/medusa-cli", title: "Medusa CLI", }, { + type: "link", path: "/nextjs-starter", title: "Next.js Starter", }, ], }, { + type: "link", path: "/architectural-modules", title: "Architectural Modules", isChildSidebar: true, - hasTitleStyling: true, children: [ { - path: "/architectural-modules/cache", + type: "category", title: "Cache Modules", - hasTitleStyling: true, children: [ { + type: "link", + path: "/architectural-modules/cache", + title: "Overview", + }, + { + type: "link", path: "/architectural-modules/cache/in-memory", title: "In-Memory", }, { + type: "link", path: "/architectural-modules/cache/redis", title: "Redis", }, { + type: "sub-category", title: "Guides", children: [ { + type: "link", path: "/architectural-modules/cache/create", title: "Create Cache Module", }, @@ -1410,22 +1683,30 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/architectural-modules/event", + type: "category", title: "Event Modules", - hasTitleStyling: true, children: [ { + type: "link", + path: "/architectural-modules/event", + title: "Overview", + }, + { + type: "link", path: "/architectural-modules/event/local", title: "Local", }, { + type: "link", path: "/architectural-modules/event/redis", title: "Redis", }, { + type: "sub-category", title: "Guides", children: [ { + type: "link", path: "/architectural-modules/event/create", title: "Create Event Module", }, @@ -1434,22 +1715,30 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/architectural-modules/file", + type: "category", title: "File Provider Modules", - hasTitleStyling: true, children: [ { + type: "link", + path: "/architectural-modules/file", + title: "Overview", + }, + { + type: "link", path: "/architectural-modules/file/local", title: "Local", }, { + type: "link", path: "/architectural-modules/file/s3", title: "AWS S3 (and Compatible APIs)", }, { + type: "sub-category", title: "Guides", children: [ { + type: "link", path: "/references/file-provider-module", title: "Create File Provider", }, @@ -1458,26 +1747,35 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/architectural-modules/notification", + type: "category", title: "Notification Provider Modules", - hasTitleStyling: true, children: [ { + type: "link", + path: "/architectural-modules/notification", + title: "Overview", + }, + { + type: "link", path: "/architectural-modules/notification/local", title: "Local", }, { + type: "link", path: "/architectural-modules/notification/sendgrid", title: "SendGrid", }, { + type: "sub-category", title: "Guides", children: [ { + type: "link", path: "/architectural-modules/notification/send-notification", title: "Send Notification", }, { + type: "link", path: "/references/notification-provider-module", title: "Create Notification Provider", }, @@ -1486,15 +1784,21 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/architectural-modules/workflow-engine", + type: "category", title: "Workflow Engine Modules", - hasTitleStyling: true, children: [ { + type: "link", + path: "/architectural-modules/workflow-engine", + title: "Overview", + }, + { + type: "link", path: "/architectural-modules/workflow-engine/in-memory", title: "In-Memory", }, { + type: "link", path: "/architectural-modules/workflow-engine/redis", title: "Redis", }, @@ -1503,89 +1807,119 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { + type: "link", path: "/storefront-development", title: "Storefront Development", - hasTitleStyling: true, isChildSidebar: true, children: [ { + type: "link", path: "/storefront-development/tips", title: "Tips", }, { - path: "/storefront-development/regions", + type: "separator", + }, + { + type: "category", title: "Regions", children: [ { + type: "link", + path: "/storefront-development/regions", + title: "Overview", + }, + { + type: "link", path: "/storefront-development/regions/list", title: "List Regions", }, { + type: "link", path: "/storefront-development/regions/store-retrieve-region", title: "Store and Retrieve Regions", }, { + type: "link", path: "/storefront-development/regions/context", title: "Region React Context", }, ], }, { - path: "/storefront-development/products", + type: "category", title: "Products", children: [ { + type: "link", + path: "/storefront-development/products", + title: "Overview", + }, + { + type: "link", path: "/storefront-development/products/list", title: "List Products", }, { + type: "link", path: "/storefront-development/products/retrieve", title: "Retrieve a Product", }, { + type: "link", path: "/storefront-development/products/variants", title: "Select a Variant", }, { + type: "link", path: "/storefront-development/products/price", title: "Retrieve Variant Prices", autogenerate_path: "storefront-development/products/price/examples", }, { + type: "link", path: "/storefront-development/products/categories", title: "Categories", children: [ { + type: "link", path: "/storefront-development/products/categories/list", title: "List Categories", }, { + type: "link", path: "/storefront-development/products/categories/retrieve", title: "Retrieve a Category", }, { + type: "link", path: "/storefront-development/products/categories/products", title: "Retrieve a Category's Products", }, { + type: "link", path: "/storefront-development/products/categories/nested-categories", title: "Retrieve Nested Categories", }, ], }, { + type: "link", path: "/storefront-development/products/collections", title: "Collections", children: [ { + type: "link", path: "/storefront-development/products/collections/list", title: "List Collections", }, { + type: "link", path: "/storefront-development/products/collections/retrieve", title: "Retrieve a Collection", }, { + type: "link", path: "/storefront-development/products/collections/products", title: "Retrieve a Collection's Products", }, @@ -1594,92 +1928,125 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { - path: "/storefront-development/cart", + type: "category", title: "Carts", children: [ { + type: "link", + path: "/storefront-development/cart", + title: "Overview", + }, + { + type: "link", path: "/storefront-development/cart/create", title: "Create Cart", }, { + type: "link", path: "/storefront-development/cart/retrieve", title: "Retrieve Cart", }, { + type: "link", path: "/storefront-development/cart/context", title: "Cart React Context", }, { + type: "link", path: "/storefront-development/cart/update", title: "Update Cart", }, { + type: "link", path: "/storefront-development/cart/manage-items", title: "Manage Line Items", }, ], }, { - path: "/storefront-development/checkout", + type: "category", title: "Checkout", children: [ { + type: "link", + path: "/storefront-development/checkout", + title: "Overview", + }, + { + type: "link", path: "/storefront-development/checkout/email", title: "1. Enter Email", }, { + type: "link", path: "/storefront-development/checkout/address", title: "2. Enter Address", }, { + type: "link", path: "/storefront-development/checkout/shipping", title: "3. Choose Shipping Method", }, { + type: "link", path: "/storefront-development/checkout/payment", title: "4. Choose Payment Provider", children: [ { + type: "link", path: "/storefront-development/checkout/payment/stripe", title: "Example: Stripe", }, ], }, { + type: "link", path: "/storefront-development/checkout/complete-cart", title: "5. Complete Cart", }, ], }, { - path: "/storefront-development/customers", + type: "category", title: "Customers", children: [ { + type: "link", + path: "/storefront-development/customers", + title: "Overview", + }, + { + type: "link", path: "/storefront-development/customers/register", title: "Register Customer", }, { + type: "link", path: "/storefront-development/customers/login", title: "Login Customer", }, { + type: "link", path: "/storefront-development/customers/retrieve", title: "Retrieve Customer", }, { + type: "link", path: "/storefront-development/customers/context", title: "Customer React Context", }, { + type: "link", path: "/storefront-development/customers/profile", title: "Edit Customer Profile", }, { + type: "link", path: "/storefront-development/customers/addresses", title: "Manage Customer Addresses", }, { + type: "link", path: "/storefront-development/customers/log-out", title: "Log-out Customer", }, @@ -1688,106 +2055,122 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { + type: "link", path: "/references/medusa-config", title: "Medusa Configurations", - hasTitleStyling: true, }, { + type: "separator", + }, + { + type: "category", title: "General", - hasTitleStyling: true, children: [ { + type: "link", path: "/upgrade-guides", title: "Upgrade Guides", }, { + type: "link", path: "/deployment", title: "Deployment Guides", isChildSidebar: true, children: [ { + type: "category", title: "Medusa Application", - hasTitleStyling: true, autogenerate_path: "/deployment/medusa-application", }, { + type: "category", title: "Medusa Admin", - hasTitleStyling: true, autogenerate_path: "/deployment/admin", }, { + type: "category", title: "Next.js Starter", - hasTitleStyling: true, autogenerate_path: "/deployment/storefront", }, ], }, { + type: "link", path: "/troubleshooting", title: "Troubleshooting Guides", isChildSidebar: true, children: [ { + type: "category", title: "Installation", - hasTitleStyling: true, children: [ { + type: "link", path: "/troubleshooting/create-medusa-app-errors", title: "Create Medusa App Errors", }, { + type: "link", path: "/troubleshooting/errors-installing-cli", title: "Errors Installing CLI", }, { + type: "link", path: "/troubleshooting/pnpm-errors", title: "pnpm Errors", }, { + type: "link", path: "/troubleshooting/general-errors", title: "General Errors", }, ], }, { + type: "category", title: "Medusa Application", - hasTitleStyling: true, children: [ { + type: "link", path: "/troubleshooting/eaddrinuse", title: "EADDRINUSE Error", }, { + type: "link", path: "/troubleshooting/database-errors", title: "Database Errors", }, ], }, { + type: "category", title: "Upgrade", - hasTitleStyling: true, children: [ { + type: "link", path: "/troubleshooting/errors-after-upgrading", title: "Errors After Upgrading", }, ], }, { + type: "category", title: "Frontend", - hasTitleStyling: true, children: [ { + type: "link", path: "/troubleshooting/cors-errors", title: "CORS Errors", }, ], }, { + type: "category", title: "Integrations", hasTitleStyling: true, children: [ { + type: "link", path: "/troubleshooting/s3", title: "S3 Module Provider Errors", }, @@ -1798,10 +2181,11 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { + type: "category", title: "Lists", - hasTitleStyling: true, children: [ { + type: "link", path: "/medusa-container-resources", title: "Medusa Container Resources", }, @@ -1810,89 +2194,94 @@ export const sidebar = sidebarAttachHrefCommonOptions([ // title: "Events", // }, { + type: "link", path: "/admin-widget-injection-zones", title: "Admin Widget Injection Zones", }, ], }, { + type: "category", title: "References", - hasTitleStyling: true, children: [ { + type: "link", path: "/references/workflows", title: "Workflow API", isChildSidebar: true, children: [ { + type: "category", title: "Functions", - hasTitleStyling: true, autogenerate_path: "/references/workflows/functions", }, ], }, { + type: "link", path: "/references/data-model", title: "Data Model API", childSidebarTitle: "Data Model API Reference", isChildSidebar: true, children: [ { + type: "link", path: "/references/data-model/define", title: "Define Method", - hasTitleStyling: true, }, { - path: "/references/data-model/property-types", + type: "separator", + }, + { + type: "category", title: "Property Types", - hasTitleStyling: true, autogenerate_path: "/references/dml/Property_Types/methods", }, { - path: "/references/data-model/relationship-methods", + type: "category", title: "Relationship Methods", - hasTitleStyling: true, autogenerate_path: "/references/dml/Relationship_Methods/methods", }, { - path: "/references/data-model/model-methods", + type: "category", title: "Model Methods", - hasTitleStyling: true, autogenerate_path: "/references/dml/Model_Methods/methods", }, { - path: "/references/data-model/property-configuration", + type: "category", title: "Property Configuration Methods", - hasTitleStyling: true, autogenerate_path: "/references/dml/Property_Configuration_Methods/methods", }, ], }, { + type: "link", path: "/service-factory-reference", title: "Service Factory Reference", isChildSidebar: true, children: [ { + type: "category", title: "Methods", - hasTitleStyling: true, autogenerate_path: "/service-factory-reference/methods", }, { + type: "category", title: "Tips", - hasTitleStyling: true, autogenerate_path: "/service-factory-reference/tips", }, ], }, { + type: "link", path: "/references/helper-steps", title: "Helper Steps Reference", isChildSidebar: true, autogenerate_path: "/references/helper_steps/functions", }, { + type: "link", title: "Medusa Workflows Reference", path: "/medusa-workflows-reference", isChildSidebar: true, @@ -1901,13 +2290,15 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { + type: "category", title: "Other", - hasTitleStyling: true, children: [ { + type: "sub-category", title: "Contribution Guidelines", children: [ { + type: "link", path: "/contribution-guidelines/docs", title: "Docs", }, @@ -1918,6 +2309,7 @@ export const sidebar = sidebarAttachHrefCommonOptions([ ], }, { + type: "link", path: "/usage", title: "Usage", }, diff --git a/www/apps/resources/utils/sidebar-attach-common-options.mjs b/www/apps/resources/utils/sidebar-attach-common-options.mjs index 1166bcdf7f..4ec44f7dd8 100644 --- a/www/apps/resources/utils/sidebar-attach-common-options.mjs +++ b/www/apps/resources/utils/sidebar-attach-common-options.mjs @@ -1,4 +1,4 @@ -/** @type {Partial} */ +/** @type {Partial} */ const commonOptions = { loaded: true, isPathHref: true, @@ -6,13 +6,19 @@ const commonOptions = { /** * - * @param {import("types").SidebarItemType[]} sidebar - * @returns {import("types").SidebarItemType[]} + * @param {import("types").RawSidebarItem[]} sidebar + * @returns {import("types").RawSidebarItem[]} */ export function sidebarAttachHrefCommonOptions(sidebar) { - return sidebar.map((item) => ({ - ...commonOptions, - ...item, - children: sidebarAttachHrefCommonOptions(item.children || []), - })) + return sidebar.map((item) => { + if (item.type === "separator") { + return item + } + + return { + ...commonOptions, + ...item, + children: sidebarAttachHrefCommonOptions(item.children || []), + } + }) } diff --git a/www/apps/ui/contentlayer.config.ts b/www/apps/ui/contentlayer.config.ts index a50815cd05..191a89015e 100644 --- a/www/apps/ui/contentlayer.config.ts +++ b/www/apps/ui/contentlayer.config.ts @@ -1,5 +1,6 @@ import { defineDocumentType, makeSource } from "contentlayer/source-files" import { rehypeComponent } from "./src/lib/rehype-component" +import rehypeSlug from "rehype-slug" export const Doc = defineDocumentType(() => ({ name: "Doc", @@ -26,6 +27,6 @@ export default makeSource({ contentDirPath: "./src/content", documentTypes: [Doc], mdx: { - rehypePlugins: [rehypeComponent], + rehypePlugins: [[rehypeComponent], [rehypeSlug]], }, }) diff --git a/www/apps/ui/package.json b/www/apps/ui/package.json index e8852969a1..402c521230 100644 --- a/www/apps/ui/package.json +++ b/www/apps/ui/package.json @@ -37,6 +37,7 @@ "react": "18.2.0", "react-day-picker": "^8.10.0", "react-dom": "18.2.0", + "rehype-slug": "^6.0.0", "remark": "^14.0.3", "tailwind": "*", "tailwindcss": "3.3.3", diff --git a/www/apps/ui/src/app/assets/sitemap.ts b/www/apps/ui/src/app/assets/sitemap.ts index edcfdf88f5..2145d92d8d 100644 --- a/www/apps/ui/src/app/assets/sitemap.ts +++ b/www/apps/ui/src/app/assets/sitemap.ts @@ -2,7 +2,7 @@ import { MetadataRoute } from "next" import { docsConfig } from "@/config/docs" import { absoluteUrl } from "@/lib/absolute-url" -import { SidebarItemType } from "types" +import { SidebarItem } from "types" export default function sitemap(): MetadataRoute.Sitemap { const now = new Date() @@ -12,23 +12,24 @@ export default function sitemap(): MetadataRoute.Sitemap { lastModified?: string | Date }> = [] - function pushItems(newItems: SidebarItemType[]) { + function pushItems(newItems: SidebarItem[]) { newItems.forEach((item) => { - if (item.path) { - items.push({ - url: absoluteUrl(item.path), - lastModified: now, - }) + if (item.type !== "link") { + return } + items.push({ + url: absoluteUrl(item.path), + lastModified: now, + }) + if (item.children) { pushItems(item.children) } }) } - pushItems(docsConfig.sidebar.top) - pushItems(docsConfig.sidebar.bottom) + pushItems(docsConfig.sidebar.default) return items } diff --git a/www/apps/ui/src/app/layout.tsx b/www/apps/ui/src/app/layout.tsx index c1c162c518..7066dcb65f 100644 --- a/www/apps/ui/src/app/layout.tsx +++ b/www/apps/ui/src/app/layout.tsx @@ -1,6 +1,5 @@ import type { Metadata } from "next" -import { Navbar } from "@/components/navbar" import { Providers } from "@/providers" import { siteConfig } from "@/config/site" @@ -36,11 +35,11 @@ export default function RootLayout({ return ( {children} diff --git a/www/apps/ui/src/components/navbar.tsx b/www/apps/ui/src/components/navbar.tsx deleted file mode 100644 index 15d773856f..0000000000 --- a/www/apps/ui/src/components/navbar.tsx +++ /dev/null @@ -1,25 +0,0 @@ -"use client" - -import { docsConfig } from "@/config/docs" -import { basePathUrl } from "@/lib/base-path-url" -import { Navbar as UiNavbar, useSidebar } from "docs-ui" - -const Navbar = () => { - const { mobileSidebarOpen, setMobileSidebarOpen } = useSidebar() - - return ( - - ) -} - -export { Navbar } diff --git a/www/apps/ui/src/config/docs.tsx b/www/apps/ui/src/config/docs.tsx index eeff671044..162796d23a 100644 --- a/www/apps/ui/src/config/docs.tsx +++ b/www/apps/ui/src/config/docs.tsx @@ -1,281 +1,360 @@ -import { ArrowUpRightOnBox } from "@medusajs/icons" -import { NavbarItem, getMobileSidebarItems, getNavbarItems } from "docs-ui" -import { SidebarSectionItemsType } from "types" +import { getMobileSidebarItems } from "docs-ui" +import { SidebarSectionItems } from "types" import { siteConfig } from "./site" type DocsConfig = { - mainNav: NavbarItem[] - sidebar: SidebarSectionItemsType + sidebar: SidebarSectionItems } export const docsConfig: DocsConfig = { - mainNav: getNavbarItems({ - basePath: siteConfig.baseUrl, - activePath: process.env.NEXT_PUBLIC_BASE_PATH || "/ui", - version: "v1", - }), sidebar: { - top: [ + default: [ { - title: "Getting Started", - children: [ - { - title: "Introduction", - path: "/", - loaded: true, - isPathHref: true, - }, - ], + type: "link", + title: "Introduction", + path: "/", + loaded: true, + isPathHref: true, }, { + type: "separator", + }, + { + type: "category", title: "Installation", + loaded: true, children: [ { + type: "link", title: "Medusa Admin Extension", path: "/installation/medusa-admin-extension", isPathHref: true, + loaded: true, }, { + type: "link", title: "Standalone Project", path: "/installation/standalone-project", isPathHref: true, + loaded: true, }, { + type: "link", title: "Upgrade Guides", path: `${process.env.NEXT_PUBLIC_DOCS_URL}/upgrade-guides/medusa-ui`, isPathHref: true, - additionalElms: , - linkProps: { - target: "_blank", - rel: "noreferrer", - }, + loaded: true, }, ], }, - ], - bottom: [ { + type: "category", title: "Colors", + loaded: true, children: [ { + type: "link", title: "Overview", path: "/colors/overview", isPathHref: true, + loaded: true, }, ], }, { + type: "link", title: "Icons", - children: [ - { - title: "Overview", - path: "/icons/overview", - isPathHref: true, - }, - ], + path: "/icons/overview", + isPathHref: true, + loaded: true, }, { + type: "separator", + }, + { + type: "category", title: "Components", + loaded: true, children: [ { + type: "link", title: "Alert", path: "/components/alert", isPathHref: true, + loaded: true, }, { + type: "link", title: "Avatar", path: "/components/avatar", isPathHref: true, + loaded: true, }, { + type: "link", title: "Badge", path: "/components/badge", isPathHref: true, + loaded: true, }, { + type: "link", title: "Button", path: "/components/button", isPathHref: true, + loaded: true, }, { + type: "link", title: "Calendar", path: "/components/calendar", isPathHref: true, + loaded: true, }, { + type: "link", title: "Checkbox", path: "/components/checkbox", isPathHref: true, + loaded: true, }, { + type: "link", title: "Code Block", path: "/components/code-block", isPathHref: true, + loaded: true, }, { + type: "link", title: "Command", path: "/components/command", isPathHref: true, + loaded: true, }, { + type: "link", title: "Command Bar", path: "/components/command-bar", isPathHref: true, + loaded: true, }, { + type: "link", title: "Container", path: "/components/container", isPathHref: true, + loaded: true, }, { + type: "link", title: "Copy", path: "/components/copy", isPathHref: true, + loaded: true, }, { + type: "link", title: "Currency Input", path: "/components/currency-input", isPathHref: true, + loaded: true, }, { + type: "link", title: "Date Picker", path: "/components/date-picker", isPathHref: true, + loaded: true, }, { + type: "link", title: "Drawer", path: "/components/drawer", isPathHref: true, + loaded: true, }, { + type: "link", title: "Dropdown Menu", path: "/components/dropdown-menu", isPathHref: true, + loaded: true, }, { + type: "link", title: "Focus Modal", path: "/components/focus-modal", isPathHref: true, + loaded: true, }, { + type: "link", title: "Heading", path: "/components/heading", isPathHref: true, + loaded: true, }, { + type: "link", title: "Icon Badge", path: "/components/icon-badge", isPathHref: true, + loaded: true, }, { + type: "link", title: "Icon Button", path: "/components/icon-button", isPathHref: true, + loaded: true, }, { + type: "link", title: "Input", path: "/components/input", isPathHref: true, + loaded: true, }, { + type: "link", title: "Kbd", path: "/components/kbd", isPathHref: true, + loaded: true, }, { + type: "link", title: "Label", path: "/components/label", isPathHref: true, + loaded: true, }, { + type: "link", title: "Progress Accordion", path: "/components/progress-accordion", isPathHref: true, + loaded: true, }, { + type: "link", title: "Progress Tabs", path: "/components/progress-tabs", isPathHref: true, + loaded: true, }, { + type: "link", title: "Prompt", path: "/components/prompt", isPathHref: true, + loaded: true, }, { + type: "link", title: "Radio Group", path: "/components/radio-group", isPathHref: true, + loaded: true, }, { + type: "link", title: "Select", path: "/components/select", isPathHref: true, + loaded: true, }, { + type: "link", title: "Status Badge", path: "/components/status-badge", isPathHref: true, + loaded: true, }, { + type: "link", title: "Switch", path: "/components/switch", isPathHref: true, + loaded: true, }, { + type: "link", title: "Table", path: "/components/table", isPathHref: true, + loaded: true, }, { + type: "link", title: "Tabs", path: "/components/tabs", isPathHref: true, + loaded: true, }, { + type: "link", title: "Text", path: "/components/text", isPathHref: true, + loaded: true, }, { + type: "link", title: "Textarea", path: "/components/textarea", isPathHref: true, + loaded: true, }, { + type: "link", title: "Toast", path: "/components/toast", isPathHref: true, + loaded: true, }, { + type: "link", title: "Tooltip", path: "/components/tooltip", isPathHref: true, + loaded: true, }, ], }, { + type: "category", title: "Hooks", + loaded: true, children: [ { + type: "link", title: "usePrompt", path: "/hooks/use-prompt", isPathHref: true, + loaded: true, }, { + type: "link", title: "useToggleState", path: "/hooks/use-toggle-state", isPathHref: true, + loaded: true, }, ], }, { + type: "category", title: "Utils", + loaded: true, children: [ { + type: "link", title: "clx", path: "/utils/clx", isPathHref: true, + loaded: true, }, ], }, diff --git a/www/apps/ui/src/config/site.ts b/www/apps/ui/src/config/site.ts index f81e9b9776..e07645fcda 100644 --- a/www/apps/ui/src/config/site.ts +++ b/www/apps/ui/src/config/site.ts @@ -16,8 +16,7 @@ export const siteConfig: SiteConfig = { description: "Primitives for building Medusa applications.", // sidebar is defined in docs.tsx sidebar: { - top: [], - bottom: [], + default: [], mobile: [], }, } diff --git a/www/apps/ui/src/providers/index.tsx b/www/apps/ui/src/providers/index.tsx index 279d92cf1c..20cab2fc49 100644 --- a/www/apps/ui/src/providers/index.tsx +++ b/www/apps/ui/src/providers/index.tsx @@ -11,6 +11,7 @@ import { import SearchProvider from "./search" import SidebarProvider from "./sidebar" import { siteConfig } from "../config/site" +import { MainNavProvider } from "./main-nav" type ProvidersProps = { children: React.ReactNode @@ -25,7 +26,9 @@ const Providers = ({ children }: ProvidersProps) => { - {children} + + {children} + diff --git a/www/apps/ui/src/providers/main-nav.tsx b/www/apps/ui/src/providers/main-nav.tsx new file mode 100644 index 0000000000..ce60c4d9b2 --- /dev/null +++ b/www/apps/ui/src/providers/main-nav.tsx @@ -0,0 +1,42 @@ +"use client" + +import { + formatReportLink, + getNavDropdownItems, + MainNavProvider as UiMainNavProvider, + useIsBrowser, +} from "docs-ui" +import { useMemo } from "react" +import { siteConfig } from "../config/site" +import { basePathUrl } from "../lib/base-path-url" + +type MainNavProviderProps = { + children?: React.ReactNode +} + +export const MainNavProvider = ({ children }: MainNavProviderProps) => { + const isBrowser = useIsBrowser() + const navigationDropdownItems = useMemo( + () => + getNavDropdownItems({ + basePath: siteConfig.baseUrl, + activePath: basePathUrl(), + version: "v1", + }), + [] + ) + + const reportLink = useMemo( + () => formatReportLink("UI Docs", isBrowser ? document.title : "", "ui"), + [isBrowser] + ) + + return ( + + {children} + + ) +} diff --git a/www/apps/ui/src/providers/sidebar.tsx b/www/apps/ui/src/providers/sidebar.tsx index b6bde22025..fa9a051ad9 100644 --- a/www/apps/ui/src/providers/sidebar.tsx +++ b/www/apps/ui/src/providers/sidebar.tsx @@ -10,6 +10,7 @@ type SidebarProviderProps = { const SidebarProvider = ({ children }: SidebarProviderProps) => { const { scrollableElement } = useScrollController() + return ( { - const { setMobileSidebarOpen, mobileSidebarOpen } = useSidebar() - - const navbarItems = useMemo( - () => - getNavbarItems({ - basePath: config.baseUrl, - activePath: process.env.NEXT_PUBLIC_BASE_PATH || "/user-guide", - version: "v2", - }), - [] - ) - - return ( - - ) -} - -export default Navbar diff --git a/www/apps/user-guide/config/index.ts b/www/apps/user-guide/config/index.ts index e23446dc85..8d2e6faaf2 100644 --- a/www/apps/user-guide/config/index.ts +++ b/www/apps/user-guide/config/index.ts @@ -1,4 +1,4 @@ -import { DocsConfig } from "types" +import { DocsConfig, SidebarItem } from "types" import { getMobileSidebarItems } from "docs-ui" import { generatedSidebar as sidebar } from "@/generated/sidebar.mjs" @@ -9,8 +9,7 @@ export const config: DocsConfig = { baseUrl, basePath: process.env.NEXT_PUBLIC_BASE_PATH, sidebar: { - top: sidebar, - bottom: [], + default: sidebar as SidebarItem[], mobile: getMobileSidebarItems({ baseUrl, version: "v2", diff --git a/www/apps/user-guide/generated/sidebar.mjs b/www/apps/user-guide/generated/sidebar.mjs index 8cf60bdbd8..d1e1380ec8 100644 --- a/www/apps/user-guide/generated/sidebar.mjs +++ b/www/apps/user-guide/generated/sidebar.mjs @@ -2,13 +2,18 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/", "title": "Introduction", "children": [] }, + { + "type": "separator" + }, { "loaded": true, "isPathHref": true, + "type": "category", "title": "Tips", "hasTitleStyling": true, "autogenerate_path": "/tips", @@ -16,6 +21,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/tips/bulk-editor", "title": "Bulk Editor", "children": [] @@ -23,6 +29,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/tips/languages", "title": "Admin Languages", "children": [] @@ -30,6 +37,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/tips/lists", "title": "Lists", "children": [] @@ -39,6 +47,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "path": "/orders", "title": "Orders", "hasTitleStyling": true, @@ -47,6 +56,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/orders/manage", "title": "Manage Details", "children": [] @@ -54,6 +64,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/orders/payments", "title": "Manage Payments", "children": [] @@ -61,6 +72,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/orders/fulfillments", "title": "Manage Fulfillments", "children": [] @@ -68,6 +80,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/orders/edit", "title": "Edit an Order’s Items", "children": [] @@ -75,6 +88,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/orders/drafts", "title": "Manage Draft Orders", "children": [] @@ -82,6 +96,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/orders/returns", "title": "Manage Returns", "children": [] @@ -89,6 +104,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/orders/exchange", "title": "Manage Exchanges", "children": [] @@ -96,6 +112,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/orders/claims", "title": "Manage Order's Claims", "children": [] @@ -103,6 +120,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/orders/export", "title": "Export Orders", "children": [] @@ -112,6 +130,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "path": "/products", "title": "Products", "hasTitleStyling": true, @@ -120,6 +139,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/products/manage", "title": "Manage Products", "children": [] @@ -127,6 +147,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/products/collections", "title": "Manage Product Collections", "children": [] @@ -134,6 +155,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/products/categories", "title": "Manage Product Categories", "children": [] @@ -141,12 +163,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/products/gift-cards", "title": "Gift Cards", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/products/gift-cards/product-gift-card", "title": "Manage a Product Gift Card", "children": [], @@ -155,6 +179,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/products/gift-cards/customer-gift-card", "title": "Manage a Customer Gift Card", "children": [], @@ -165,6 +190,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/products/import", "title": "Import Products", "children": [] @@ -172,6 +198,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/products/export", "title": "Export Products", "children": [] @@ -181,6 +208,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "path": "/inventory", "title": "Inventory", "hasTitleStyling": true, @@ -189,6 +217,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/inventory/inventory", "title": "Manage Inventory", "children": [] @@ -196,6 +225,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/inventory/reservations", "title": "Manage Reservations", "children": [] @@ -205,6 +235,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "path": "/customers", "title": "Customers", "hasTitleStyling": true, @@ -213,6 +244,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/customers/manage", "title": "Manage Customers", "children": [] @@ -220,6 +252,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/customers/groups", "title": "Manage Customer Groups", "children": [] @@ -229,6 +262,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "path": "/discounts", "title": "Discounts", "hasTitleStyling": true, @@ -237,6 +271,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/discounts/create", "title": "Create a Discount", "children": [] @@ -244,6 +279,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/discounts/manage", "title": "Manage Discounts", "children": [] @@ -253,6 +289,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "path": "/pricing", "title": "Pricing", "hasTitleStyling": true, @@ -261,6 +298,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/pricing/create", "title": "Create a Price List", "children": [] @@ -268,6 +306,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/pricing/manage", "title": "Manage Price Lists", "children": [] @@ -277,6 +316,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "category", "path": "/settings", "title": "Settings", "hasTitleStyling": true, @@ -285,6 +325,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/profile", "title": "Profile", "children": [] @@ -292,6 +333,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/store", "title": "Store", "children": [] @@ -299,12 +341,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/users", "title": "Users", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/users/invites", "title": "Manage Invites", "children": [], @@ -315,12 +359,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/regions", "title": "Regions", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/regions/manage", "title": "Manage Regions", "children": [], @@ -329,6 +375,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/regions/countries", "title": "Manage Countries", "children": [], @@ -337,6 +384,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/regions/providers", "title": "Manage Providers", "children": [], @@ -345,6 +393,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/regions/shipping-options", "title": "Manage Shipping Options", "children": [], @@ -355,6 +404,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/return-reasons", "title": "Return Reasons", "children": [] @@ -362,12 +412,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/taxes", "title": "Taxes", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/taxes/manage", "title": "Manage Taxes", "children": [], @@ -376,6 +428,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/taxes/tax-rates", "title": "Manage Tax Rates", "children": [], @@ -386,6 +439,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/locations", "title": "Locations", "children": [] @@ -393,12 +447,14 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/sales-channels", "title": "Sales Channels", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/sales-channels/manage", "title": "Manage Sales Channels", "children": [], @@ -407,6 +463,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/sales-channels/products", "title": "Manage Products", "children": [], @@ -417,18 +474,21 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/developer", "title": "Developer", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/developer/api-key-management", "title": "API Key Management", "children": [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/developer/api-key-management/sales-channels", "title": "Manage Sales Channels", "children": [], @@ -440,6 +500,7 @@ export const generatedSidebar = [ { "loaded": true, "isPathHref": true, + "type": "link", "path": "/settings/developer/executions", "title": "Executions", "children": [], diff --git a/www/apps/user-guide/providers/index.tsx b/www/apps/user-guide/providers/index.tsx index 268dce2b41..45892c649b 100644 --- a/www/apps/user-guide/providers/index.tsx +++ b/www/apps/user-guide/providers/index.tsx @@ -15,6 +15,7 @@ import { import SidebarProvider from "./sidebar" import SearchProvider from "./search" import { config } from "../config" +import { MainNavProvider } from "./main-nav" type ProvidersProps = { children?: React.ReactNode @@ -32,15 +33,17 @@ const Providers = ({ children }: ProvidersProps) => { - - - {children} - - + + + + {children} + + + diff --git a/www/apps/user-guide/providers/main-nav.tsx b/www/apps/user-guide/providers/main-nav.tsx new file mode 100644 index 0000000000..9bd9970e2d --- /dev/null +++ b/www/apps/user-guide/providers/main-nav.tsx @@ -0,0 +1,46 @@ +"use client" + +import { + formatReportLink, + getNavDropdownItems, + MainNavProvider as UiMainNavProvider, + useIsBrowser, +} from "docs-ui" +import { useMemo } from "react" +import { config } from "../config" +import { basePathUrl } from "../utils/base-path-url" + +type MainNavProviderProps = { + children?: React.ReactNode +} + +export const MainNavProvider = ({ children }: MainNavProviderProps) => { + const isBrowser = useIsBrowser() + const navigationDropdownItems = useMemo( + () => + getNavDropdownItems({ + basePath: config.baseUrl, + activePath: basePathUrl(), + version: "v2", + }), + [] + ) + + const reportLink = useMemo( + () => + formatReportLink( + config.titleSuffix || "", + isBrowser ? document.title : "" + ), + [isBrowser] + ) + + return ( + + {children} + + ) +} diff --git a/www/apps/user-guide/providers/sidebar.tsx b/www/apps/user-guide/providers/sidebar.tsx index 5c8ce3c927..4562e1fc8c 100644 --- a/www/apps/user-guide/providers/sidebar.tsx +++ b/www/apps/user-guide/providers/sidebar.tsx @@ -20,7 +20,6 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => { initialItems={config.sidebar} staticSidebarItems={true} disableActiveTransition={true} - noTitleStyling={true} > {children} diff --git a/www/apps/user-guide/sidebar.mjs b/www/apps/user-guide/sidebar.mjs index bcad4f5dcc..1df0f3adc1 100644 --- a/www/apps/user-guide/sidebar.mjs +++ b/www/apps/user-guide/sidebar.mjs @@ -5,51 +5,63 @@ import { sidebarAttachHrefCommonOptions } from "build-scripts" /** @type {import('types').RawSidebarItemType[]} */ export const sidebar = sidebarAttachHrefCommonOptions([ { + type: "link", path: "/", title: "Introduction", }, { + type: "separator", + }, + { + type: "category", title: "Tips", hasTitleStyling: true, autogenerate_path: "/tips", }, { + type: "category", path: "/orders", title: "Orders", hasTitleStyling: true, autogenerate_path: "/orders", }, { + type: "category", path: "/products", title: "Products", hasTitleStyling: true, autogenerate_path: "/products", }, { + type: "category", path: "/inventory", title: "Inventory", hasTitleStyling: true, autogenerate_path: "/inventory", }, { + type: "category", path: "/customers", title: "Customers", hasTitleStyling: true, autogenerate_path: "/customers", }, { + type: "category", path: "/discounts", title: "Discounts", hasTitleStyling: true, autogenerate_path: "/discounts", }, { + type: "category", path: "/pricing", title: "Pricing", hasTitleStyling: true, autogenerate_path: "/pricing", }, { + type: "category", path: "/settings", title: "Settings", hasTitleStyling: true, diff --git a/www/packages/build-scripts/src/generate-sidebar.ts b/www/packages/build-scripts/src/generate-sidebar.ts index 4978d1d67e..fcb3f88cc5 100644 --- a/www/packages/build-scripts/src/generate-sidebar.ts +++ b/www/packages/build-scripts/src/generate-sidebar.ts @@ -1,10 +1,10 @@ -import type { RawSidebarItemType } from "types" +import type { RawSidebarItem, SidebarItem } from "types" import { existsSync, mkdirSync, readdirSync, statSync } from "fs" import path from "path" import { getSidebarItemLink, sidebarAttachHrefCommonOptions } from "./index.js" import getCoreFlowsRefSidebarChildren from "./utils/get-core-flows-ref-sidebar-children.js" -export type ItemsToAdd = RawSidebarItemType & { +export type ItemsToAdd = SidebarItem & { sidebar_position?: number } @@ -37,19 +37,17 @@ async function getSidebarItems( true ) if (nested && newItems.length > 1) { - items.push( - ...sidebarAttachHrefCommonOptions([ - { - title: - fileBasename.charAt(0).toUpperCase() + - fileBasename.substring(1), - hasTitleStyling: true, - children: newItems, - }, - ]) - ) + items.push({ + type: "sub-category", + title: + fileBasename.charAt(0).toUpperCase() + fileBasename.substring(1), + children: newItems, + loaded: true, + }) } else { - items.push(...sidebarAttachHrefCommonOptions(newItems)) + items.push( + ...(sidebarAttachHrefCommonOptions(newItems) as ItemsToAdd[]) + ) } continue } @@ -69,7 +67,11 @@ async function getSidebarItems( mainPageIndex = items.length - 1 } - if (mainPageIndex !== -1 && items.length > 1) { + if ( + mainPageIndex !== -1 && + items.length > 1 && + items[0].type !== "separator" + ) { // push all other items to be children of that page. const mainPageChildren = [ ...items.splice(0, mainPageIndex), @@ -84,9 +86,19 @@ async function getSidebarItems( return items } -async function checkItem( - item: RawSidebarItemType -): Promise { +async function checkItem(item: RawSidebarItem): Promise { + if (!item.type) { + throw new Error( + `ERROR: The following item doesn't have a type: ${JSON.stringify( + item, + undefined, + 2 + )}` + ) + } + if (item.type === "separator") { + return item + } if (item.autogenerate_path) { item.children = (await getSidebarItems(item.autogenerate_path)).map( (child) => { @@ -109,7 +121,7 @@ async function checkItem( return item } -export async function generateSidebar(sidebar: RawSidebarItemType[]) { +export async function generateSidebar(sidebar: RawSidebarItem[]) { const path = await import("path") const { writeFileSync } = await import("fs") diff --git a/www/packages/build-scripts/src/utils/get-core-flows-ref-sidebar-children.ts b/www/packages/build-scripts/src/utils/get-core-flows-ref-sidebar-children.ts index 0ef99a1106..3c73d02cb1 100644 --- a/www/packages/build-scripts/src/utils/get-core-flows-ref-sidebar-children.ts +++ b/www/packages/build-scripts/src/utils/get-core-flows-ref-sidebar-children.ts @@ -14,6 +14,19 @@ export default async function getCoreFlowsRefSidebarChildren(): Promise< const sidebarItems: ItemsToAdd[] = [] + sidebarItems.push( + { + type: "link", + title: "Overview", + path: "/medusa-workflows-reference", + loaded: true, + isPathHref: true, + }, + { + type: "separator", + } + ) + for (const directory of directories) { if ( !directory.isDirectory() || @@ -66,21 +79,28 @@ export default async function getCoreFlowsRefSidebarChildren(): Promise< if (workflowItems.length || stepItems.length) { const item: ItemsToAdd = { + type: "category", title: directory.name.replaceAll("_", " "), children: [], + loaded: true, + initialOpen: false, } if (workflowItems.length) { item.children!.push({ + type: "sub-category", title: "Workflows", children: workflowItems, + loaded: true, }) } if (stepItems.length) { item.children!.push({ + type: "sub-category", title: "Steps", children: stepItems, + loaded: true, }) } diff --git a/www/packages/build-scripts/src/utils/get-sidebar-item-link.ts b/www/packages/build-scripts/src/utils/get-sidebar-item-link.ts index fb61050a66..62f6f790b3 100644 --- a/www/packages/build-scripts/src/utils/get-sidebar-item-link.ts +++ b/www/packages/build-scripts/src/utils/get-sidebar-item-link.ts @@ -3,6 +3,7 @@ import { ItemsToAdd, sidebarAttachHrefCommonOptions } from "../index.js" import { readFileSync } from "fs" import findMetadataTitle from "./find-metadata-title.js" import findPageHeading from "./find-page-heading.js" +import { InteractiveSidebarItem } from "types" export async function getSidebarItemLink({ filePath, @@ -24,6 +25,7 @@ export async function getSidebarItemLink({ const newItem = sidebarAttachHrefCommonOptions([ { + type: "link", path: frontmatter.slug || filePath.replace(basePath, "").replace(`/${fileBasename}`, ""), @@ -33,7 +35,7 @@ export async function getSidebarItemLink({ findPageHeading(fileContent) || "", }, - ])[0] + ])[0] as InteractiveSidebarItem return { ...newItem, diff --git a/www/packages/build-scripts/src/utils/sidebar-attach-href-common-options.ts b/www/packages/build-scripts/src/utils/sidebar-attach-href-common-options.ts index 363b6d6d72..bb44f8b048 100644 --- a/www/packages/build-scripts/src/utils/sidebar-attach-href-common-options.ts +++ b/www/packages/build-scripts/src/utils/sidebar-attach-href-common-options.ts @@ -1,16 +1,22 @@ -import { RawSidebarItemType } from "types" +import { RawSidebarItem } from "types" -const commonOptions: Partial = { +const commonOptions: Partial = { loaded: true, isPathHref: true, } export function sidebarAttachHrefCommonOptions( - sidebar: RawSidebarItemType[] -): RawSidebarItemType[] { - return sidebar.map((item) => ({ - ...commonOptions, - ...item, - children: sidebarAttachHrefCommonOptions(item.children || []), - })) + sidebar: RawSidebarItem[] +): RawSidebarItem[] { + return sidebar.map((item) => { + if (item.type === "separator") { + return item + } + + return { + ...commonOptions, + ...item, + children: sidebarAttachHrefCommonOptions(item.children || []), + } + }) } diff --git a/www/packages/docs-ui/package.json b/www/packages/docs-ui/package.json index 313f2204eb..57a1e236f8 100644 --- a/www/packages/docs-ui/package.json +++ b/www/packages/docs-ui/package.json @@ -78,6 +78,7 @@ "react-medium-image-zoom": "^5.1.10", "react-tooltip": "^5.21.3", "react-transition-group": "^4.4.5", - "react-uuid": "^2.0.0" + "react-uuid": "^2.0.0", + "slugify": "^1.6.6" } } diff --git a/www/packages/docs-ui/src/components/Bannerv2/index.tsx b/www/packages/docs-ui/src/components/Bannerv2/index.tsx index bb8cdb35a1..14b51cf6ae 100644 --- a/www/packages/docs-ui/src/components/Bannerv2/index.tsx +++ b/www/packages/docs-ui/src/components/Bannerv2/index.tsx @@ -1,15 +1,65 @@ -import React from "react" -import { Card, Link } from "../.." +"use client" + +import React, { useEffect, useState } from "react" +import { Button, useIsBrowser } from "../.." +import { ExclamationCircleSolid, XMark } from "@medusajs/icons" +import clsx from "clsx" + +const LOCAL_STORAGE_KEY = "banner-v2" + +export type Bannerv2Props = { + className?: string +} + +export const Bannerv2 = ({ className }: Bannerv2Props) => { + const [show, setShow] = useState(false) + const isBrowser = useIsBrowser() + + useEffect(() => { + if (!isBrowser) { + return + } + + const localStorageValue = localStorage.getItem(LOCAL_STORAGE_KEY) + if (!localStorageValue) { + setShow(true) + } + }, [isBrowser]) + + const handleClose = () => { + setShow(false) + localStorage.setItem(LOCAL_STORAGE_KEY, "true") + } -export const Bannerv2 = () => { return ( - - This documentation is for Medusa v2, which isn't ready for - production. -
-
- For production-use, refer to{" "} - this documentation instead. -
+ ) } diff --git a/www/packages/docs-ui/src/components/BorderedIcon/index.tsx b/www/packages/docs-ui/src/components/BorderedIcon/index.tsx index ffd66a620f..00f7726cca 100644 --- a/www/packages/docs-ui/src/components/BorderedIcon/index.tsx +++ b/www/packages/docs-ui/src/components/BorderedIcon/index.tsx @@ -1,5 +1,4 @@ import React from "react" -import { Bordered } from "@/components/Bordered" import clsx from "clsx" import { IconProps } from "@medusajs/icons/dist/types" @@ -15,37 +14,35 @@ export type BorderedIconProps = { export const BorderedIcon = ({ icon = "", IconComponent = null, - wrapperClassName, iconWrapperClassName, iconClassName, iconColorClassName = "", }: BorderedIconProps) => { return ( - - - {!IconComponent && ( - - )} - {IconComponent && ( - - )} - - + + {!IconComponent && ( + + )} + {IconComponent && ( + + )} + ) } diff --git a/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx b/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx index fd6bd17d74..83ad81a08f 100644 --- a/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx +++ b/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx @@ -17,8 +17,13 @@ export const Breadcrumbs = () => { tempBreadcrumbItems = getBreadcrumbsOfItem(item.previousSidebar) } + const parentPath = + item.parentItem?.type === "link" ? item.parentItem.path : undefined + const firstItemPath = + item.default[0].type === "link" ? item.default[0].path : undefined + tempBreadcrumbItems.set( - item.parentItem?.path || item.top[0].path || "/", + parentPath || firstItemPath || "/", item.parentItem?.childSidebarTitle || item.parentItem?.title || "" ) diff --git a/www/packages/docs-ui/src/components/ChildDocs/index.tsx b/www/packages/docs-ui/src/components/ChildDocs/index.tsx index ec33520709..65a5a1ab9a 100644 --- a/www/packages/docs-ui/src/components/ChildDocs/index.tsx +++ b/www/packages/docs-ui/src/components/ChildDocs/index.tsx @@ -2,7 +2,8 @@ import React, { useMemo } from "react" import { Card, CardList, MDXComponents, useSidebar } from "../.." -import { SidebarItemType } from "types" +import { InteractiveSidebarItem, SidebarItem, SidebarItemLink } from "types" +import slugify from "slugify" type ChildDocsProps = { onlyTopLevel?: boolean @@ -30,16 +31,19 @@ export const ChildDocs = ({ : "all" }, [showItems, hideItems]) - const filterCondition = (item: SidebarItemType): boolean => { + const filterCondition = (item: SidebarItem): boolean => { + if (item.type === "separator") { + return false + } switch (filterType) { case "hide": return ( - (!item.path || !hideItems.includes(item.path)) && + (item.type !== "link" || !hideItems.includes(item.path)) && !hideItems.includes(item.title) ) case "show": return ( - (item.path !== undefined && showItems!.includes(item.path)) || + (item.type === "link" && showItems!.includes(item.path)) || showItems!.includes(item.title) ) case "all": @@ -47,12 +51,16 @@ export const ChildDocs = ({ } } - const filterItems = (items: SidebarItemType[]): SidebarItemType[] => { + const filterItems = (items: SidebarItem[]): SidebarItem[] => { return items .filter(filterCondition) .map((item) => Object.assign({}, item)) .map((item) => { - if (item.children && filterType === "hide") { + if ( + item.type !== "separator" && + item.children && + filterType === "hide" + ) { item.children = filterItems(item.children) } @@ -67,8 +75,7 @@ export const ChildDocs = ({ ? Object.assign({}, currentItems) : undefined : { - top: [...(getActiveItem()?.children || [])], - bottom: [], + default: [...(getActiveItem()?.children || [])], } if (filterType === "all" || !targetItems) { return targetItems @@ -76,25 +83,34 @@ export const ChildDocs = ({ return { ...targetItems, - top: filterItems(targetItems.top), - bottom: filterItems(targetItems.bottom), + default: filterItems(targetItems.default), } }, [currentItems, type, getActiveItem, filterItems]) + const filterNonInteractiveItems = ( + items: SidebarItem[] | undefined + ): InteractiveSidebarItem[] => { + return ( + (items?.filter( + (item) => item.type !== "separator" + ) as InteractiveSidebarItem[]) || [] + ) + } + const getChildrenForLevel = ( - item: SidebarItemType, + item: InteractiveSidebarItem, currentLevel = 1 - ): SidebarItemType[] | undefined => { + ): InteractiveSidebarItem[] | undefined => { if (currentLevel === childLevel) { - return item.children + return filterNonInteractiveItems(item.children) } if (!item.children) { return } - const childrenResult: SidebarItemType[] = [] + const childrenResult: InteractiveSidebarItem[] = [] - item.children.forEach((child) => { + filterNonInteractiveItems(item.children).forEach((child) => { const childChildren = getChildrenForLevel(child, currentLevel + 1) if (!childChildren) { @@ -107,20 +123,34 @@ export const ChildDocs = ({ return childrenResult } - const getTopLevelElms = (items?: SidebarItemType[]) => ( - ({ - title: childItem.title, - href: childItem.path, - showLinkIcon: false, - })) || [] - } - /> - ) + const getTopLevelElms = (items?: SidebarItem[]) => { + return ( + { + const href = + childItem.type === "link" + ? childItem.path + : childItem.children?.length + ? ( + childItem.children.find( + (item) => item.type === "link" + ) as SidebarItemLink + )?.path + : "#" + return { + title: childItem.title, + href, + showLinkIcon: false, + } + }) || [] + } + /> + ) + } - const getAllLevelsElms = (items?: SidebarItemType[]) => - items?.map((item, key) => { + const getAllLevelsElms = (items?: SidebarItem[]) => + filterNonInteractiveItems(items).map((item, key) => { const itemChildren = getChildrenForLevel(item) const HeadingComponent = itemChildren?.length ? MDXComponents["h2"] @@ -130,12 +160,16 @@ export const ChildDocs = ({ {HeadingComponent && ( <> - {!hideTitle && {item.title}} + {!hideTitle && ( + + {item.title} + + )} ({ title: childItem.title, - href: childItem.path, + href: childItem.type === "link" ? childItem.path : "", showLinkIcon: false, })) || [] } @@ -143,20 +177,19 @@ export const ChildDocs = ({ )} {!HeadingComponent && ( - + )} ) }) - const getElms = (items?: SidebarItemType[]) => { + const getElms = (items?: SidebarItem[]) => { return onlyTopLevel ? getTopLevelElms(items) : getAllLevelsElms(items) } - return ( - <> - {getElms(filteredItems?.top)} - {getElms(filteredItems?.bottom)} - - ) + return <>{getElms(filteredItems?.default)} } diff --git a/www/packages/docs-ui/src/components/HelpButton/index.tsx b/www/packages/docs-ui/src/components/HelpButton/index.tsx index f75ac2385b..a2216e6570 100644 --- a/www/packages/docs-ui/src/components/HelpButton/index.tsx +++ b/www/packages/docs-ui/src/components/HelpButton/index.tsx @@ -1,39 +1,23 @@ "use client" -import React, { useCallback, useEffect, useRef, useState } from "react" +import React, { useEffect, useRef, useState } from "react" import { Button } from "@/components" import clsx from "clsx" import { CSSTransition } from "react-transition-group" import { HelpButtonActions } from "./Actions" -import { useIsBrowser } from "../.." +import { useClickOutside } from "../.." export const HelpButton = () => { const [showText, setShowText] = useState(false) const [showHelp, setShowHelp] = useState(false) const ref = useRef(null) - const isBrowser = useIsBrowser() - - const onClickOutside = useCallback( - (e: MouseEvent) => { - if (!ref.current?.contains(e.target as Node)) { - setShowHelp(false) - setShowText(false) - } + useClickOutside({ + elmRef: ref, + onClickOutside: () => { + setShowHelp(false) + setShowText(false) }, - [ref.current] - ) - - useEffect(() => { - if (!isBrowser) { - return - } - - window.document.addEventListener("click", onClickOutside) - - return () => { - window.document.removeEventListener("click", onClickOutside) - } - }, [isBrowser]) + }) useEffect(() => { if (showHelp) { diff --git a/www/packages/docs-ui/src/components/Icons/House/index.tsx b/www/packages/docs-ui/src/components/Icons/House/index.tsx new file mode 100644 index 0000000000..8d5fddd235 --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/House/index.tsx @@ -0,0 +1,23 @@ +import React from "react" +import { IconProps } from "@medusajs/icons/dist/types" + +export const HouseIcon = (props: IconProps) => { + return ( + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Icons/MedusaLogo/index.tsx b/www/packages/docs-ui/src/components/Icons/MedusaLogo/index.tsx new file mode 100644 index 0000000000..2e7065d8c2 --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/MedusaLogo/index.tsx @@ -0,0 +1,60 @@ +import { IconProps } from "@medusajs/icons/dist/types" +import React from "react" + +export const MedusaIcon = (props: IconProps) => { + return ( + + + + + + + + + + + + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Admin/index.tsx b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Admin/index.tsx new file mode 100644 index 0000000000..d424affdc1 --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Admin/index.tsx @@ -0,0 +1,33 @@ +import { IconProps } from "@medusajs/icons/dist/types" +import React from "react" + +export const NavigationDropdownAdminIcon = (props: IconProps) => { + return ( + + + + + + + + + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Doc/index.tsx b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Doc/index.tsx new file mode 100644 index 0000000000..11ac92fc28 --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Doc/index.tsx @@ -0,0 +1,41 @@ +import { IconProps } from "@medusajs/icons/dist/types" +import React from "react" + +export const NavigationDropdownDocIcon = (props: IconProps) => { + return ( + + + + + + + + + + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Icons/NavigationDropdown/DocV1/index.tsx b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/DocV1/index.tsx new file mode 100644 index 0000000000..3cf2bdb16b --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/DocV1/index.tsx @@ -0,0 +1,37 @@ +import { IconProps } from "@medusajs/icons/dist/types" +import React from "react" + +export const NavigationDropdownDocV1Icon = (props: IconProps) => { + return ( + + + + + + + + + + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Resources/index.tsx b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Resources/index.tsx new file mode 100644 index 0000000000..17ac939457 --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Resources/index.tsx @@ -0,0 +1,37 @@ +import { IconProps } from "@medusajs/icons/dist/types" +import React from "react" + +export const NavigationDropdownResourcesIcon = (props: IconProps) => { + return ( + + + + + + + + + + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Store/index.tsx b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Store/index.tsx new file mode 100644 index 0000000000..7527cb9693 --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Store/index.tsx @@ -0,0 +1,37 @@ +import { IconProps } from "@medusajs/icons/dist/types" +import React from "react" + +export const NavigationDropdownStoreIcon = (props: IconProps) => { + return ( + + + + + + + + + + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Ui/index.tsx b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Ui/index.tsx new file mode 100644 index 0000000000..b19e199f4b --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/Ui/index.tsx @@ -0,0 +1,37 @@ +import { IconProps } from "@medusajs/icons/dist/types" +import React from "react" + +export const NavigationDropdownUiIcon = (props: IconProps) => { + return ( + + + + + + + + + + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Icons/NavigationDropdown/User/index.tsx b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/User/index.tsx new file mode 100644 index 0000000000..980732cd7e --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/NavigationDropdown/User/index.tsx @@ -0,0 +1,37 @@ +import { IconProps } from "@medusajs/icons/dist/types" +import React from "react" + +export const NavigationDropdownUserIcon = (props: IconProps) => { + return ( + + + + + + + + + + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Icons/SidebarLeft/index.tsx b/www/packages/docs-ui/src/components/Icons/SidebarLeft/index.tsx new file mode 100644 index 0000000000..963b08a601 --- /dev/null +++ b/www/packages/docs-ui/src/components/Icons/SidebarLeft/index.tsx @@ -0,0 +1,42 @@ +import { IconProps } from "@medusajs/icons/dist/types" +import React from "react" + +export const SidebarLeftIcon = (props: IconProps) => { + return ( + + + + + + + + + + + + ) +} diff --git a/www/packages/docs-ui/src/components/Kbd/index.tsx b/www/packages/docs-ui/src/components/Kbd/index.tsx index 414d9b0c75..60acc5cece 100644 --- a/www/packages/docs-ui/src/components/Kbd/index.tsx +++ b/www/packages/docs-ui/src/components/Kbd/index.tsx @@ -9,9 +9,9 @@ export const Kbd = ({ children, className, ...props }: KbdProps) => { className={clsx( "rounded-docs_xs border-solid border border-medusa-border-base", "inline-flex items-center justify-center", - "py-0 px-[6px]", + "py-0 px-docs_0.25", "bg-medusa-bg-field", - "text-medusa-tag-neutral-text", + "text-medusa-fg-subtle", "text-compact-x-small-plus font-base shadow-none", className )} diff --git a/www/packages/docs-ui/src/components/MainNav/Breadcrumb/index.tsx b/www/packages/docs-ui/src/components/MainNav/Breadcrumb/index.tsx new file mode 100644 index 0000000000..af6a014a47 --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/Breadcrumb/index.tsx @@ -0,0 +1,84 @@ +"use client" + +import React, { useMemo } from "react" +import { CurrentItemsState, useSidebar } from "../../.." +import clsx from "clsx" +import Link from "next/link" +import { SidebarItemLink } from "types" + +export const MainNavBreadcrumbs = () => { + const { currentItems, getActiveItem } = useSidebar() + + const getLinkPath = (item?: SidebarItemLink): string | undefined => { + if (!item) { + return + } + return item.isPathHref ? item.path : `#${item.path}` + } + + const getBreadcrumbsOfItem = ( + item: CurrentItemsState + ): Map => { + let tempBreadcrumbItems: Map = new Map() + if (item.previousSidebar) { + tempBreadcrumbItems = getBreadcrumbsOfItem(item.previousSidebar) + } + + const parentPath = + item.parentItem?.type === "link" + ? getLinkPath(item.parentItem) + : undefined + const firstItemPath = + item.default[0].type === "link" ? getLinkPath(item.default[0]) : undefined + + tempBreadcrumbItems.set( + parentPath || firstItemPath || "/", + item.parentItem?.childSidebarTitle || item.parentItem?.title || "" + ) + + return tempBreadcrumbItems + } + + const breadcrumbItems = useMemo(() => { + const tempBreadcrumbItems: Map = new Map() + if (currentItems) { + getBreadcrumbsOfItem(currentItems).forEach((value, key) => + tempBreadcrumbItems.set(key, value) + ) + } + + const activeItem = getActiveItem() + if (activeItem) { + tempBreadcrumbItems.set( + getLinkPath(activeItem) || "/", + activeItem?.title || "" + ) + } + + return tempBreadcrumbItems + }, [currentItems, getActiveItem]) + + return ( +
+ {Array.from(breadcrumbItems).map(([link, title]) => ( + + / + + {title} + + + ))} +
+ ) +} diff --git a/www/packages/docs-ui/src/components/MainNav/ColorMode/index.tsx b/www/packages/docs-ui/src/components/MainNav/ColorMode/index.tsx new file mode 100644 index 0000000000..1f84c42cf5 --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/ColorMode/index.tsx @@ -0,0 +1,22 @@ +"use client" + +import React from "react" +import { useColorMode } from "../../../providers" +import { Button } from "../../.." +import { Moon, Sun } from "@medusajs/icons" +import clsx from "clsx" + +export const MainNavColorMode = () => { + const { colorMode, toggleColorMode } = useColorMode() + + return ( + + ) +} diff --git a/www/packages/docs-ui/src/components/MainNav/Divider/index.tsx b/www/packages/docs-ui/src/components/MainNav/Divider/index.tsx new file mode 100644 index 0000000000..23d27c58a8 --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/Divider/index.tsx @@ -0,0 +1,13 @@ +import clsx from "clsx" +import React from "react" + +export const MainNavDivider = () => { + return ( + + ) +} diff --git a/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Icon/index.tsx b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Icon/index.tsx new file mode 100644 index 0000000000..4820d0b20b --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Icon/index.tsx @@ -0,0 +1,21 @@ +import React from "react" +import { BorderedIcon } from "@/components" +import { IconProps } from "@medusajs/icons/dist/types" + +export type MainNavigationDropdownIconProps = { + icon: React.FC + inDropdown?: boolean +} + +export const MainNavigationDropdownIcon = ({ + icon, + inDropdown = false, +}: MainNavigationDropdownIconProps) => { + return ( + + ) +} diff --git a/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Menu/Item/index.tsx b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Menu/Item/index.tsx new file mode 100644 index 0000000000..045e8c7bdc --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Menu/Item/index.tsx @@ -0,0 +1,50 @@ +"use client" + +import React from "react" +import { NavigationDropdownItem } from "types" +import Link from "next/link" +import clsx from "clsx" +import { EllipseMiniSolid } from "@medusajs/icons" +import { MainNavigationDropdownIcon } from "../../Icon" +import { SidebarSeparator } from "../../../../Sidebar/Separator" + +export type MainNavigationDropdownMenuItemProps = { + item: NavigationDropdownItem + onSelect: () => void +} + +export const MainNavigationDropdownMenuItem = ({ + item, + onSelect, +}: MainNavigationDropdownMenuItemProps) => { + switch (item.type) { + case "divider": + return + case "link": + return ( + +
  • + + + + + {item.title} +
  • + + ) + } +} diff --git a/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Menu/index.tsx b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Menu/index.tsx new file mode 100644 index 0000000000..2f9090da58 --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Menu/index.tsx @@ -0,0 +1,36 @@ +"use client" + +import clsx from "clsx" +import React from "react" +import { NavigationDropdownItem } from "types" +import { MainNavigationDropdownMenuItem } from "./Item" + +export type MainNavigationDropdownMenuProps = { + items: NavigationDropdownItem[] + open: boolean + onSelect: () => void +} + +export const MainNavigationDropdownMenu = ({ + items, + open, + onSelect, +}: MainNavigationDropdownMenuProps) => { + return ( +
      + {items.map((item, index) => ( + + ))} +
    + ) +} diff --git a/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Selected/index.tsx b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Selected/index.tsx new file mode 100644 index 0000000000..ecbea2a6a9 --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/Selected/index.tsx @@ -0,0 +1,40 @@ +"use client" + +import React from "react" +import { NavigationDropdownItem } from "types" +import { TrianglesMini } from "@medusajs/icons" +import clsx from "clsx" +import { MainNavigationDropdownIcon } from "../Icon" + +export type MainNavigationDropdownSelectedProps = { + item: NavigationDropdownItem + onClick: () => void +} + +export const MainNavigationDropdownSelected = ({ + item, + onClick, +}: MainNavigationDropdownSelectedProps) => { + if (item.type === "divider") { + return <> + } + + return ( +
    + +
    + + {item.title} + + +
    +
    + ) +} diff --git a/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/index.tsx b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/index.tsx new file mode 100644 index 0000000000..b1a8737bb7 --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/NavigationDropdown/index.tsx @@ -0,0 +1,46 @@ +"use client" + +import clsx from "clsx" +import React, { useMemo, useRef, useState } from "react" +import { MainNavigationDropdownSelected } from "./Selected" +import { MainNavigationDropdownMenu } from "./Menu" +import { useClickOutside, useMainNav } from "../../.." + +export const MainNavigationDropdown = () => { + const { navItems: items } = useMainNav() + const navigationRef = useRef(null) + const [menuOpen, setMenuOpen] = useState(false) + useClickOutside({ + elmRef: navigationRef, + onClickOutside: () => { + setMenuOpen(false) + }, + }) + + const selectedItem = useMemo(() => { + const activeItem = items.find( + (item) => item.type === "link" && item.isActive + ) + + if (!activeItem) { + return items.length ? items[0] : undefined + } + + return activeItem + }, [items]) + return ( +
    + {selectedItem && ( + setMenuOpen((prev) => !prev)} + /> + )} + setMenuOpen(false)} + /> +
    + ) +} diff --git a/www/packages/docs-ui/src/components/MainNav/SidebarOpener/index.tsx b/www/packages/docs-ui/src/components/MainNav/SidebarOpener/index.tsx new file mode 100644 index 0000000000..458a768965 --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/SidebarOpener/index.tsx @@ -0,0 +1,24 @@ +"use client" + +import React from "react" +import { Button, useSidebar } from "../../.." +import clsx from "clsx" +import { SidebarLeft } from "@medusajs/icons" + +export const MainNavSidebarOpener = () => { + const { desktopSidebarOpen, setDesktopSidebarOpen } = useSidebar() + + if (desktopSidebarOpen) { + return <> + } + + return ( + + ) +} diff --git a/www/packages/docs-ui/src/components/MainNav/index.tsx b/www/packages/docs-ui/src/components/MainNav/index.tsx new file mode 100644 index 0000000000..5e62cdf844 --- /dev/null +++ b/www/packages/docs-ui/src/components/MainNav/index.tsx @@ -0,0 +1,38 @@ +"use client" + +import clsx from "clsx" +import React from "react" +import { MainNavigationDropdown } from "./NavigationDropdown" +import { MainNavBreadcrumbs } from "./Breadcrumb" +import { SearchModalOpener, useMainNav } from "../.." +import { MainNavColorMode } from "./ColorMode" +import Link from "next/link" +import { MainNavDivider } from "./Divider" +import { MainNavSidebarOpener } from "./SidebarOpener" + +export const MainNav = () => { + const { reportIssueLink } = useMainNav() + return ( +
    +
    + + + +
    +
    + + Report Issue + + + + +
    +
    + ) +} diff --git a/www/packages/docs-ui/src/components/Menu/Action/index.tsx b/www/packages/docs-ui/src/components/Menu/Action/index.tsx new file mode 100644 index 0000000000..c24e6c4d84 --- /dev/null +++ b/www/packages/docs-ui/src/components/Menu/Action/index.tsx @@ -0,0 +1,32 @@ +"use client" + +import clsx from "clsx" +import React from "react" +import { MenuItemAction } from "types" + +export type MenuActionProps = { + item: MenuItemAction +} + +export const MenuAction = ({ item }: MenuActionProps) => { + return ( + + {item.icon} + {item.title} + {item.shortcut && ( + + {item.shortcut} + + )} + + ) +} diff --git a/www/packages/docs-ui/src/components/Menu/Divider/index.tsx b/www/packages/docs-ui/src/components/Menu/Divider/index.tsx new file mode 100644 index 0000000000..4527c2d032 --- /dev/null +++ b/www/packages/docs-ui/src/components/Menu/Divider/index.tsx @@ -0,0 +1,7 @@ +"use client" + +import React from "react" + +export const MenuDivider = () => { + return
    +} diff --git a/www/packages/docs-ui/src/components/Menu/Item/index.tsx b/www/packages/docs-ui/src/components/Menu/Item/index.tsx new file mode 100644 index 0000000000..fd11c770f5 --- /dev/null +++ b/www/packages/docs-ui/src/components/Menu/Item/index.tsx @@ -0,0 +1,27 @@ +"use client" + +import clsx from "clsx" +import Link from "next/link" +import React from "react" +import { MenuItemLink } from "types" + +export type MenuItemProps = { + item: MenuItemLink +} + +export const MenuItem = ({ item }: MenuItemProps) => { + return ( + + {item.icon} + {item.title} + + ) +} diff --git a/www/packages/docs-ui/src/components/Menu/index.tsx b/www/packages/docs-ui/src/components/Menu/index.tsx new file mode 100644 index 0000000000..f886b7a5f6 --- /dev/null +++ b/www/packages/docs-ui/src/components/Menu/index.tsx @@ -0,0 +1,31 @@ +import clsx from "clsx" +import React from "react" +import { MenuItem as MenuItemType } from "types" +import { MenuItem } from "./Item" +import { MenuDivider } from "./Divider" +import { MenuAction } from "./Action" + +export type MenuProps = { + items: MenuItemType[] + className?: string +} + +export const Menu = ({ items, className }: MenuProps) => { + return ( +
    + {items.map((item, index) => ( + + {item.type === "link" && } + {item.type === "action" && } + {item.type === "divider" && } + + ))} +
    + ) +} diff --git a/www/packages/docs-ui/src/components/MobileNavigation/index.tsx b/www/packages/docs-ui/src/components/MobileNavigation/index.tsx new file mode 100644 index 0000000000..22669aba8e --- /dev/null +++ b/www/packages/docs-ui/src/components/MobileNavigation/index.tsx @@ -0,0 +1,32 @@ +"use client" + +import clsx from "clsx" +import React from "react" +import { SidebarLeftIcon } from "../Icons/SidebarLeft" +import { Button, SearchModalOpener, useSidebar } from "../.." +import { MainNavigationDropdown } from "../MainNav/NavigationDropdown" + +export const MobileNavigation = () => { + const { setMobileSidebarOpen } = useSidebar() + + return ( +
    + + + +
    + ) +} diff --git a/www/packages/docs-ui/src/components/Modal/index.tsx b/www/packages/docs-ui/src/components/Modal/index.tsx index 46671f14ad..fb5f8b9290 100644 --- a/www/packages/docs-ui/src/components/Modal/index.tsx +++ b/www/packages/docs-ui/src/components/Modal/index.tsx @@ -88,7 +88,7 @@ export const Modal = ({ {...props} className={clsx( "fixed top-0 left-0 flex h-screen w-screen items-center justify-center", - "bg-medusa-bg-overlay", + "bg-medusa-bg-overlay z-50", "hidden open:flex border-0 p-0", className )} diff --git a/www/packages/docs-ui/src/components/Navbar/ColorModeToggle/index.tsx b/www/packages/docs-ui/src/components/Navbar/ColorModeToggle/index.tsx deleted file mode 100644 index 7383412580..0000000000 --- a/www/packages/docs-ui/src/components/Navbar/ColorModeToggle/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -"use client" - -import React from "react" -import { NavbarIconButton, NavbarIconButtonProps } from "../IconButton" -import { useColorMode } from "@/providers" -import { Moon, Sun } from "@medusajs/icons" - -export type NavbarColorModeToggleProps = { - buttonProps?: NavbarIconButtonProps -} - -export const NavbarColorModeToggle = ({ - buttonProps, -}: NavbarColorModeToggleProps) => { - const { colorMode, toggleColorMode } = useColorMode() - - return ( - toggleColorMode()}> - {colorMode === "light" && } - {colorMode === "dark" && } - - ) -} diff --git a/www/packages/docs-ui/src/components/Navbar/IconButton/index.tsx b/www/packages/docs-ui/src/components/Navbar/IconButton/index.tsx deleted file mode 100644 index 0fea86774b..0000000000 --- a/www/packages/docs-ui/src/components/Navbar/IconButton/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from "react" -import clsx from "clsx" -import { Button, ButtonProps } from "@/components" - -export type NavbarIconButtonProps = ButtonProps - -export const NavbarIconButton = ({ - children, - className, - ...props -}: NavbarIconButtonProps) => { - return ( - - ) -} diff --git a/www/packages/docs-ui/src/components/Navbar/Link/index.tsx b/www/packages/docs-ui/src/components/Navbar/Link/index.tsx deleted file mode 100644 index fee3cc4fe0..0000000000 --- a/www/packages/docs-ui/src/components/Navbar/Link/index.tsx +++ /dev/null @@ -1,40 +0,0 @@ -"use client" - -import React from "react" -import clsx from "clsx" -import { Badge, BadgeProps, Link, LinkProps } from "@/components" - -export type NavbarLinkProps = { - href: string - label: string - className?: string - activeValuePattern?: RegExp - isActive?: boolean - badge?: BadgeProps -} & LinkProps - -export const NavbarLink = ({ - href, - label, - className, - isActive, - badge, -}: NavbarLinkProps) => { - return ( - - {label} - {badge && ( - - )} - - ) -} diff --git a/www/packages/docs-ui/src/components/Navbar/Logo/index.tsx b/www/packages/docs-ui/src/components/Navbar/Logo/index.tsx deleted file mode 100644 index e28ef7f717..0000000000 --- a/www/packages/docs-ui/src/components/Navbar/Logo/index.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client" - -import React from "react" -import { useColorMode } from "@/providers" -import Link from "next/link" -import clsx from "clsx" -import Image from "next/image" - -export type NavbarLogoProps = { - light: string - dark?: string - className?: string - imageClassName?: string -} - -export const NavbarLogo = ({ - light, - dark, - className, - imageClassName, -}: NavbarLogoProps) => { - const { colorMode } = useColorMode() - - return ( - - Medusa Logo - - ) -} diff --git a/www/packages/docs-ui/src/components/Navbar/MobileMenu/Button/index.tsx b/www/packages/docs-ui/src/components/Navbar/MobileMenu/Button/index.tsx deleted file mode 100644 index a24c6bd6fb..0000000000 --- a/www/packages/docs-ui/src/components/Navbar/MobileMenu/Button/index.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client" - -import React from "react" -import { NavbarIconButton, NavbarIconButtonProps } from "../../IconButton" -import clsx from "clsx" -import { SidebarLeft, XMark } from "@medusajs/icons" - -export type NavbarMobileMenuButtonProps = { - buttonProps?: NavbarIconButtonProps - mobileSidebarOpen: boolean - setMobileSidebarOpen: React.Dispatch> - isLoading?: boolean -} - -export const NavbarMobileMenuButton = ({ - buttonProps, - mobileSidebarOpen, - setMobileSidebarOpen, - isLoading = false, -}: NavbarMobileMenuButtonProps) => { - return ( - { - if (!isLoading) { - setMobileSidebarOpen((prevValue) => !prevValue) - } - }} - > - {!mobileSidebarOpen && } - {mobileSidebarOpen && } - - ) -} diff --git a/www/packages/docs-ui/src/components/Navbar/MobileMenu/index.tsx b/www/packages/docs-ui/src/components/Navbar/MobileMenu/index.tsx deleted file mode 100644 index 5163bd7287..0000000000 --- a/www/packages/docs-ui/src/components/Navbar/MobileMenu/index.tsx +++ /dev/null @@ -1,50 +0,0 @@ -"use client" - -import React from "react" -import { NavbarMobileMenuButton, NavbarMobileMenuButtonProps } from "./Button" -import { NavbarColorModeToggle } from "../ColorModeToggle" -import { NavbarSearchModalOpener } from "../SearchModalOpener" -import { useMobile } from "@/providers" -import clsx from "clsx" -import { NavbarLogo, NavbarLogoProps } from "../Logo" - -export type NavbarMobileMenuProps = { - menuButton: NavbarMobileMenuButtonProps - logo: NavbarLogoProps -} - -export const NavbarMobileMenu = ({ - menuButton, - logo, -}: NavbarMobileMenuProps) => { - const { isMobile } = useMobile() - - return ( -
    - {isMobile && ( - <> - - -
    - - -
    - - )} -
    - ) -} diff --git a/www/packages/docs-ui/src/components/Navbar/NavbarDivider/index.tsx b/www/packages/docs-ui/src/components/Navbar/NavbarDivider/index.tsx deleted file mode 100644 index 933a83e273..0000000000 --- a/www/packages/docs-ui/src/components/Navbar/NavbarDivider/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import clsx from "clsx" -import React from "react" - -export const NavbarDivider = () => { - return ( -
    - ) -} diff --git a/www/packages/docs-ui/src/components/Navbar/SearchModalOpener/index.tsx b/www/packages/docs-ui/src/components/Navbar/SearchModalOpener/index.tsx deleted file mode 100644 index 5700b9ce3f..0000000000 --- a/www/packages/docs-ui/src/components/Navbar/SearchModalOpener/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -"use client" - -import React from "react" -import { SearchModalOpener } from "@/components" -import { useMobile } from "@/providers" - -export type NavbarSearchModalOpenerProps = { - isLoading?: boolean -} - -export const NavbarSearchModalOpener = ({ - isLoading, -}: NavbarSearchModalOpenerProps) => { - const { isMobile } = useMobile() - - return -} diff --git a/www/packages/docs-ui/src/components/Navbar/index.tsx b/www/packages/docs-ui/src/components/Navbar/index.tsx deleted file mode 100644 index 09d76bbc39..0000000000 --- a/www/packages/docs-ui/src/components/Navbar/index.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React from "react" -import clsx from "clsx" -import { NavbarLink, NavbarLinkProps } from "./Link" -import { NavbarColorModeToggle } from "./ColorModeToggle" -import { NavbarLogo, NavbarLogoProps } from "./Logo" -import { NavbarMobileMenu } from "./MobileMenu" -import { NavbarSearchModalOpener } from "./SearchModalOpener" -import { NavbarMobileMenuButtonProps } from "./MobileMenu/Button" -import { NavbarDivider } from "./NavbarDivider" - -export type NavbarItem = - | { - type: "link" - props: NavbarLinkProps - } - | { - type: "divider" - props?: Record - } - -export type NavbarProps = { - logo: NavbarLogoProps - items: NavbarItem[] - showSearchOpener?: boolean - showColorModeToggle?: boolean - additionalActionsAfter?: React.ReactNode - additionalActionsBefore?: React.ReactNode - mobileMenuButton: NavbarMobileMenuButtonProps - isLoading?: boolean - className?: string -} - -export const Navbar = ({ - logo, - items, - showSearchOpener = true, - showColorModeToggle = true, - additionalActionsBefore, - additionalActionsAfter, - mobileMenuButton, - isLoading, - className, -}: NavbarProps) => { - return ( - - ) -} diff --git a/www/packages/docs-ui/src/components/Notification/index.tsx b/www/packages/docs-ui/src/components/Notification/index.tsx index 753481c00d..74d326182e 100644 --- a/www/packages/docs-ui/src/components/Notification/index.tsx +++ b/www/packages/docs-ui/src/components/Notification/index.tsx @@ -26,7 +26,7 @@ export const NotificationContainer = () => { return ( { + const { isMobile } = useMobile() const { setIsOpen } = useSearch() const isApple = useMemo(() => { return typeof navigator !== "undefined" @@ -52,39 +53,19 @@ export const SearchModalOpener = ({ )} {!isMobile && ( -
    - - e.target.blur()} - tabIndex={-1} - addGroupStyling={true} - /> - - {isApple ? "⌘" : "Ctrl"} - K - -
    + + {isApple ? "⌘" : "Ctrl"}K + )} ) diff --git a/www/packages/docs-ui/src/components/Sidebar/Back/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Back/index.tsx deleted file mode 100644 index baa43177e3..0000000000 --- a/www/packages/docs-ui/src/components/Sidebar/Back/index.tsx +++ /dev/null @@ -1,26 +0,0 @@ -"use client" - -import React from "react" -import { useSidebar } from "../../../providers" -import clsx from "clsx" -import { ArrowUturnLeft } from "@medusajs/icons" - -export const SidebarBack = () => { - const { goBack } = useSidebar() - - return ( -
    - - Back -
    - ) -} diff --git a/www/packages/docs-ui/src/components/Sidebar/Child/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Child/index.tsx new file mode 100644 index 0000000000..c45f19eeea --- /dev/null +++ b/www/packages/docs-ui/src/components/Sidebar/Child/index.tsx @@ -0,0 +1,34 @@ +"use client" + +import React from "react" +import clsx from "clsx" +import { InteractiveSidebarItem } from "types" +import { ArrowUturnLeft } from "@medusajs/icons" +import { useSidebar } from "../../.." + +type SidebarTitleProps = { + item: InteractiveSidebarItem +} + +export const SidebarChild = ({ item }: SidebarTitleProps) => { + const { goBack } = useSidebar() + + return ( +
    +
    + + + {item.childSidebarTitle || item.title} + +
    +
    + ) +} diff --git a/www/packages/docs-ui/src/components/Sidebar/Item/Category/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Item/Category/index.tsx new file mode 100644 index 0000000000..9538c91214 --- /dev/null +++ b/www/packages/docs-ui/src/components/Sidebar/Item/Category/index.tsx @@ -0,0 +1,115 @@ +"use client" + +// @refresh reset + +import React, { useEffect, useMemo, useRef, useState } from "react" +import { SidebarItemCategory as SidebarItemCategoryType } from "types" +import { Loading, SidebarItem, useSidebar } from "../../../.." +import clsx from "clsx" +import { MinusMini, PlusMini } from "@medusajs/icons" + +export type SidebarItemCategory = { + item: SidebarItemCategoryType + expandItems?: boolean +} & React.AllHTMLAttributes + +export const SidebarItemCategory = ({ + item, + expandItems = true, + className, +}: SidebarItemCategory) => { + const [showLoading, setShowLoading] = useState(false) + const [open, setOpen] = useState( + item.initialOpen !== undefined ? item.initialOpen : expandItems + ) + const childrenRef = useRef(null) + const { isChildrenActive } = useSidebar() + + useEffect(() => { + if (open && !item.loaded) { + setShowLoading(true) + } + }, [open]) + + useEffect(() => { + if (item.loaded && showLoading) { + setShowLoading(false) + } + }, [item]) + + useEffect(() => { + const isActive = isChildrenActive(item) + if (isActive && !open) { + setOpen(true) + } + }, [isChildrenActive]) + + const handleOpen = () => { + item.onOpen?.() + } + + const isTitleOneWord = useMemo( + () => item.title.split(" ").length === 1, + [item.title] + ) + + return ( +
    +
    +
    { + if (!open) { + handleOpen() + } + setOpen((prev) => !prev) + }} + > + + {item.title} + + {item.additionalElms} + {!item.additionalElms && ( + <> + {open && } + {!open && } + + )} +
    +
    +
      + {showLoading && ( + + )} + {item.children?.map((childItem, index) => ( + + ))} +
    +
    + ) +} diff --git a/www/packages/docs-ui/src/components/Sidebar/Item/Link/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Item/Link/index.tsx new file mode 100644 index 0000000000..a55d9b29c3 --- /dev/null +++ b/www/packages/docs-ui/src/components/Sidebar/Item/Link/index.tsx @@ -0,0 +1,147 @@ +"use client" + +// @refresh reset + +import React, { useCallback, useEffect, useMemo, useRef } from "react" +import { SidebarItemLink as SidebarItemlinkType } from "types" +import { + checkSidebarItemVisibility, + SidebarItem, + useMobile, + useSidebar, +} from "../../../.." +import clsx from "clsx" +import Link from "next/link" + +export type SidebarItemLinkProps = { + item: SidebarItemlinkType + nested?: boolean +} & React.AllHTMLAttributes + +export const SidebarItemLink = ({ + item, + className, + nested = false, +}: SidebarItemLinkProps) => { + const { + isLinkActive, + setMobileSidebarOpen: setSidebarOpen, + disableActiveTransition, + sidebarRef, + sidebarTopHeight, + } = useSidebar() + const { isMobile } = useMobile() + const active = useMemo(() => isLinkActive(item, true), [isLinkActive, item]) + const ref = useRef(null) + + const newTopCalculator = useCallback(() => { + if (!sidebarRef.current || !ref.current) { + return 0 + } + + const sidebarBoundingRect = sidebarRef.current.getBoundingClientRect() + const itemBoundingRect = ref.current.getBoundingClientRect() + + return ( + itemBoundingRect.top - + (sidebarBoundingRect.top + sidebarTopHeight) + + sidebarRef.current.scrollTop + ) + }, [sidebarTopHeight, sidebarRef, ref]) + + useEffect(() => { + if (active && ref.current && sidebarRef.current && !isMobile) { + const isVisible = checkSidebarItemVisibility( + (ref.current.children.item(0) as HTMLElement) || ref.current, + !disableActiveTransition + ) + if (isVisible) { + return + } + if (!disableActiveTransition) { + ref.current.scrollIntoView({ + block: "center", + }) + } else { + sidebarRef.current.scrollTo({ + top: newTopCalculator(), + }) + } + } + }, [ + active, + sidebarRef.current, + disableActiveTransition, + isMobile, + newTopCalculator, + ]) + + const hasChildren = useMemo(() => { + return !item.isChildSidebar && (item.children?.length || 0) > 0 + }, [item.children]) + + const isTitleOneWord = useMemo( + () => item.title.split(" ").length === 1, + [item.title] + ) + + return ( +
  • + + { + if (isMobile) { + setSidebarOpen(false) + } + }} + replace={!item.isPathHref} + shallow={!item.isPathHref} + {...item.linkProps} + > + + {item.title} + + {item.additionalElms} + + + {hasChildren && ( +
      + {item.children!.map((childItem, index) => ( + + ))} +
    + )} +
  • + ) +} diff --git a/www/packages/docs-ui/src/components/Sidebar/Item/SubCategory/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Item/SubCategory/index.tsx new file mode 100644 index 0000000000..8b997bb77d --- /dev/null +++ b/www/packages/docs-ui/src/components/Sidebar/Item/SubCategory/index.tsx @@ -0,0 +1,145 @@ +"use client" + +// @refresh reset + +import React, { useEffect, useMemo, useRef } from "react" +import { SidebarItemSubCategory as SidebarItemSubCategoryType } from "types" +import { + checkSidebarItemVisibility, + SidebarItem, + useMobile, + useSidebar, +} from "../../../.." +import clsx from "clsx" + +export type SidebarItemLinkProps = { + item: SidebarItemSubCategoryType + nested?: boolean +} & React.AllHTMLAttributes + +export const SidebarItemSubCategory = ({ + item, + className, + nested = false, +}: SidebarItemLinkProps) => { + const { isLinkActive, disableActiveTransition, sidebarRef } = useSidebar() + const { isMobile } = useMobile() + const active = useMemo( + () => !isMobile && isLinkActive(item, true), + [isLinkActive, item, isMobile] + ) + const ref = useRef(null) + + /** + * Tries to place the item in the center of the sidebar + */ + const newTopCalculator = (): number => { + if (!sidebarRef.current || !ref.current) { + return 0 + } + const sidebarBoundingRect = sidebarRef.current.getBoundingClientRect() + const sidebarHalf = sidebarBoundingRect.height / 2 + const itemTop = ref.current.offsetTop + const itemBottom = + itemTop + (ref.current.children.item(0) as HTMLElement)?.clientHeight + + // try deducting half + let newTop = itemTop - sidebarHalf + let newBottom = newTop + sidebarBoundingRect.height + if (newTop <= itemTop && newBottom >= itemBottom) { + return newTop + } + + // try adding half + newTop = itemTop + sidebarHalf + newBottom = newTop + sidebarBoundingRect.height + if (newTop <= itemTop && newBottom >= itemBottom) { + return newTop + } + + //return the item's top minus some top margin + return itemTop - sidebarBoundingRect.top + } + + useEffect(() => { + if ( + active && + ref.current && + sidebarRef.current && + window.innerWidth >= 1025 + ) { + if ( + !disableActiveTransition && + !checkSidebarItemVisibility( + (ref.current.children.item(0) as HTMLElement) || ref.current, + !disableActiveTransition + ) + ) { + ref.current.scrollIntoView({ + block: "center", + }) + } else if (disableActiveTransition) { + sidebarRef.current.scrollTo({ + top: newTopCalculator(), + }) + } + } + }, [active, sidebarRef.current, disableActiveTransition]) + + const hasChildren = useMemo(() => { + return item.children?.length || 0 > 0 + }, [item.children]) + + const isTitleOneWord = useMemo( + () => item.title.split(" ").length === 1, + [item.title] + ) + + return ( +
  • + + + + {item.title} + + {item.additionalElms} + + + {hasChildren && ( +
      + {item.children!.map((childItem, index) => ( + + ))} +
    + )} +
  • + ) +} diff --git a/www/packages/docs-ui/src/components/Sidebar/Item/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Item/index.tsx index 2276d12ae3..9a3b5d4912 100644 --- a/www/packages/docs-ui/src/components/Sidebar/Item/index.tsx +++ b/www/packages/docs-ui/src/components/Sidebar/Item/index.tsx @@ -1,204 +1,37 @@ "use client" -// @refresh reset - -import React, { useEffect, useMemo, useRef, useState } from "react" -import { useSidebar } from "@/providers" -import clsx from "clsx" -import Link from "next/link" -import { checkSidebarItemVisibility } from "@/utils" -import { Loading } from "@/components" -import { SidebarItemType } from "types" +import React from "react" +import { SidebarItem as SidebarItemType } from "types" +import { SidebarItemCategory } from "./Category" +import { SidebarItemLink } from "./Link" +import { SidebarItemSubCategory } from "./SubCategory" +import { SidebarSeparator } from "../Separator" export type SidebarItemProps = { item: SidebarItemType nested?: boolean expandItems?: boolean - currentLevel?: number - isSidebarTitle?: boolean - sidebarHasParent?: boolean - isMobile?: boolean -} & React.AllHTMLAttributes + hasNextItems?: boolean +} & React.AllHTMLAttributes export const SidebarItem = ({ item, - nested = false, - expandItems = false, - className, - currentLevel = 1, - sidebarHasParent = false, - isMobile = false, + hasNextItems = false, + ...props }: SidebarItemProps) => { - const [showLoading, setShowLoading] = useState(false) - const { - isItemActive, - setMobileSidebarOpen: setSidebarOpen, - disableActiveTransition, - noTitleStyling, - sidebarRef, - } = useSidebar() - const active = useMemo( - () => !isMobile && isItemActive(item, nested), - [isItemActive, item, nested, isMobile] - ) - const collapsed = !expandItems && !isItemActive(item, true) - const ref = useRef(null) - - const itemChildren = useMemo(() => { - return item.isChildSidebar ? undefined : item.children - }, [item]) - const canHaveTitleStyling = useMemo( - () => - item.hasTitleStyling || - ((itemChildren?.length || !item.loaded) && !noTitleStyling && !nested), - [itemChildren, noTitleStyling, item, nested] - ) - - const classNames = useMemo( - () => - clsx( - "flex items-center justify-between gap-docs_0.5 rounded-docs_xs px-docs_0.5 py-[6px]", - "hover:no-underline hover:bg-medusa-bg-component-hover", - !canHaveTitleStyling && "text-compact-small-plus text-medusa-fg-subtle", - canHaveTitleStyling && - "text-compact-x-small-plus text-medusa-fg-muted uppercase", - !item.path && "cursor-default", - item.path !== undefined && - active && - "text-medusa-fg-base bg-medusa-bg-component-hover" - ), - [canHaveTitleStyling, active, item.path] - ) - - /** - * Tries to place the item in the center of the sidebar - */ - const newTopCalculator = (): number => { - if (!sidebarRef.current || !ref.current) { - return 0 - } - const sidebarBoundingRect = sidebarRef.current.getBoundingClientRect() - const sidebarHalf = sidebarBoundingRect.height / 2 - const itemTop = ref.current.offsetTop - const itemBottom = - itemTop + (ref.current.children.item(0) as HTMLElement)?.clientHeight - - // try deducting half - let newTop = itemTop - sidebarHalf - let newBottom = newTop + sidebarBoundingRect.height - if (newTop <= itemTop && newBottom >= itemBottom) { - return newTop - } - - // try adding half - newTop = itemTop + sidebarHalf - newBottom = newTop + sidebarBoundingRect.height - if (newTop <= itemTop && newBottom >= itemBottom) { - return newTop - } - - //return the item's top minus some top margin - return itemTop - sidebarBoundingRect.top + switch (item.type) { + case "category": + return ( + <> + + {hasNextItems && } + + ) + case "sub-category": + return + case "link": + return + case "separator": + return } - - useEffect(() => { - if ( - active && - ref.current && - sidebarRef.current && - window.innerWidth >= 1025 - ) { - if ( - !disableActiveTransition && - !checkSidebarItemVisibility( - (ref.current.children.item(0) as HTMLElement) || ref.current, - !disableActiveTransition - ) - ) { - ref.current.scrollIntoView({ - block: "center", - }) - } else if (disableActiveTransition) { - sidebarRef.current.scrollTo({ - top: newTopCalculator(), - }) - } - } - if (active) { - setShowLoading(true) - } - }, [active, sidebarRef.current, disableActiveTransition]) - - return ( -
  • - {item.path === undefined && ( - - {item.title} - {item.additionalElms} - - )} - {item.path !== undefined && ( - { - if (window.innerWidth < 1025) { - setSidebarOpen(false) - } - }} - replace={!item.isPathHref} - shallow={!item.isPathHref} - {...item.linkProps} - > - {item.title} - {item.additionalElms} - - )} - {itemChildren && ( -
      - {showLoading && !item.loaded && ( - - )} - {itemChildren?.map((childItem, index) => ( - - ))} -
    - )} -
  • - ) } diff --git a/www/packages/docs-ui/src/components/Sidebar/Separator/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Separator/index.tsx new file mode 100644 index 0000000000..f580ddfdc5 --- /dev/null +++ b/www/packages/docs-ui/src/components/Sidebar/Separator/index.tsx @@ -0,0 +1,22 @@ +"use client" + +import clsx from "clsx" +import React from "react" + +export type SidebarSeparatorProps = { + className?: string +} + +export const SidebarSeparator = ({ className }: SidebarSeparatorProps) => { + return ( +
    + +
    + ) +} diff --git a/www/packages/docs-ui/src/components/Sidebar/Title/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Title/index.tsx deleted file mode 100644 index dbcafdb740..0000000000 --- a/www/packages/docs-ui/src/components/Sidebar/Title/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from "react" -import Link from "next/link" -import clsx from "clsx" -import { SidebarItemType } from "types" - -type SidebarTitleProps = { - item: SidebarItemType -} - -export const SidebarTitle = ({ item }: SidebarTitleProps) => { - return ( - - {item.childSidebarTitle || item.title} - {item.additionalElms} - - ) -} diff --git a/www/packages/docs-ui/src/components/Sidebar/Top/MedusaMenu/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Top/MedusaMenu/index.tsx new file mode 100644 index 0000000000..42e24273b1 --- /dev/null +++ b/www/packages/docs-ui/src/components/Sidebar/Top/MedusaMenu/index.tsx @@ -0,0 +1,90 @@ +"use client" + +import clsx from "clsx" +import React, { useRef, useState } from "react" +import { + BorderedIcon, + getOsShortcut, + useClickOutside, + useSidebar, +} from "../../../.." +import { + EllipsisHorizontal, + SidebarLeft, + TimelineVertical, +} from "@medusajs/icons" +import { MedusaIcon } from "../../../Icons/MedusaLogo" +import { HouseIcon } from "../../../Icons/House" +import { Menu } from "../../../Menu" + +export const SidebarTopMedusaMenu = () => { + const [openMenu, setOpenMenu] = useState(false) + const { setDesktopSidebarOpen } = useSidebar() + const ref = useRef(null) + + const toggleOpen = () => setOpenMenu((prev) => !prev) + + useClickOutside({ + elmRef: ref, + onClickOutside: () => { + setOpenMenu(false) + }, + }) + + return ( +
    +
    + + + Medusa Docs + + +
    +
    + , + title: "Homepage", + link: "https://medusajs.com", + }, + { + type: "link", + icon: , + title: "Changelog", + link: "https://medusajs.com/changelog", + }, + { + type: "divider", + }, + { + type: "action", + title: "Hide Sidebar", + icon: , + shortcut: `${getOsShortcut()}.`, + action: () => { + setDesktopSidebarOpen(false) + setOpenMenu(false) + }, + }, + ]} + /> +
    +
    + ) +} diff --git a/www/packages/docs-ui/src/components/Sidebar/Top/MobileClose/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Top/MobileClose/index.tsx new file mode 100644 index 0000000000..11a07aa101 --- /dev/null +++ b/www/packages/docs-ui/src/components/Sidebar/Top/MobileClose/index.tsx @@ -0,0 +1,21 @@ +"use client" + +import React from "react" +import { Button, useSidebar } from "../../../.." +import { XMarkMini } from "@medusajs/icons" + +export const SidebarTopMobileClose = () => { + const { setMobileSidebarOpen } = useSidebar() + + return ( +
    + +
    + ) +} diff --git a/www/packages/docs-ui/src/components/Sidebar/Top/index.tsx b/www/packages/docs-ui/src/components/Sidebar/Top/index.tsx new file mode 100644 index 0000000000..75909e9680 --- /dev/null +++ b/www/packages/docs-ui/src/components/Sidebar/Top/index.tsx @@ -0,0 +1,32 @@ +"use client" + +import React from "react" +import { SidebarChild } from "../Child" +import { InteractiveSidebarItem } from "types" +import { SidebarSeparator } from "../Separator" +import { SidebarTopMobileClose } from "./MobileClose" +import { SidebarTopMedusaMenu } from "./MedusaMenu" + +export type SidebarTopProps = { + parentItem?: InteractiveSidebarItem +} + +export const SidebarTop = React.forwardRef( + function SidebarTop({ parentItem }, ref) { + return ( +
    + +
    + + {parentItem && ( + <> + + + + )} + +
    +
    + ) + } +) diff --git a/www/packages/docs-ui/src/components/Sidebar/index.tsx b/www/packages/docs-ui/src/components/Sidebar/index.tsx index 389ee9db12..dab63f0724 100644 --- a/www/packages/docs-ui/src/components/Sidebar/index.tsx +++ b/www/packages/docs-ui/src/components/Sidebar/index.tsx @@ -5,125 +5,153 @@ import { useSidebar } from "@/providers" import clsx from "clsx" import { Loading } from "@/components" import { SidebarItem } from "./Item" -import { SidebarTitle } from "./Title" -import { SidebarBack } from "./Back" import { CSSTransition, SwitchTransition } from "react-transition-group" +import { SidebarTop, SidebarTopProps } from "./Top" +import useResizeObserver from "@react-hook/resize-observer" +import { SidebarSeparator } from "./Separator" +import { useClickOutside, useKeyboardShortcut } from "@/hooks" export type SidebarProps = { className?: string expandItems?: boolean - banner?: React.ReactNode + sidebarTopProps?: Omit } export const Sidebar = ({ className = "", - expandItems = false, - banner, + expandItems = true, + sidebarTopProps, }: SidebarProps) => { + const sidebarWrapperRef = useRef(null) + const sidebarTopRef = useRef(null) const { items, currentItems, mobileSidebarOpen, - desktopSidebarOpen, + setMobileSidebarOpen, staticSidebarItems, sidebarRef, + sidebarTopHeight, + setSidebarTopHeight, + desktopSidebarOpen, + setDesktopSidebarOpen, } = useSidebar() + useClickOutside({ + elmRef: sidebarWrapperRef, + onClickOutside: () => { + if (mobileSidebarOpen) { + setMobileSidebarOpen(false) + } + }, + }) + useKeyboardShortcut({ + metakey: true, + shortcutKeys: ["."], + action: () => { + setDesktopSidebarOpen((prev) => !prev) + }, + }) const sidebarItems = useMemo( () => currentItems || items, [items, currentItems] ) - const sidebarHasParent = useMemo( - () => sidebarItems.parentItem !== undefined, - [sidebarItems] - ) + useResizeObserver(sidebarTopRef, () => { + setSidebarTopHeight(sidebarTopRef.current?.clientHeight || 0) + }) return ( - + + + + + ) } diff --git a/www/packages/docs-ui/src/components/Toc/Item/index.tsx b/www/packages/docs-ui/src/components/Toc/Item/index.tsx new file mode 100644 index 0000000000..64668b3fe2 --- /dev/null +++ b/www/packages/docs-ui/src/components/Toc/Item/index.tsx @@ -0,0 +1,33 @@ +"use client" + +import clsx from "clsx" +import React, { useMemo } from "react" +import { ToCItemUi } from "types" +import { TocList } from "../List" + +export type TocItemProps = { + item: ToCItemUi + activeItem: string +} + +export const TocItem = ({ item, activeItem }: TocItemProps) => { + const isActive = useMemo(() => item.id === activeItem, [item, activeItem]) + + return ( +
  • + + {(item.children?.length || 0) > 0 && ( + + )} +
  • + ) +} diff --git a/www/packages/docs-ui/src/components/Toc/List/index.tsx b/www/packages/docs-ui/src/components/Toc/List/index.tsx new file mode 100644 index 0000000000..597a7a7ba2 --- /dev/null +++ b/www/packages/docs-ui/src/components/Toc/List/index.tsx @@ -0,0 +1,29 @@ +import clsx from "clsx" +import React from "react" +import { ToCItemUi } from "types" +import { TocItem } from "../Item" + +export type TocListProps = { + items: ToCItemUi[] + topLevel?: boolean + activeItem: string +} + +export const TocList = ({ + items, + topLevel = false, + activeItem, +}: TocListProps) => { + return ( +
      + {items.map((item, key) => ( + + ))} +
    + ) +} diff --git a/www/packages/docs-ui/src/components/Toc/Menu/index.tsx b/www/packages/docs-ui/src/components/Toc/Menu/index.tsx new file mode 100644 index 0000000000..79c83fba02 --- /dev/null +++ b/www/packages/docs-ui/src/components/Toc/Menu/index.tsx @@ -0,0 +1,80 @@ +"use client" + +import { EllipseMiniSolid } from "@medusajs/icons" +import clsx from "clsx" +import React from "react" +import { ToCItemUi } from "types" +import { Button, useScrollController } from "../../.." + +export type TocMenuProps = { + items: ToCItemUi[] + activeItem: string + show: boolean + setShow: (value: boolean) => void +} + +export const TocMenu = ({ items, activeItem, show, setShow }: TocMenuProps) => { + const { scrollToElement } = useScrollController() + + const getItemElm = (item: ToCItemUi) => { + const isActive = item.id === activeItem + const hasChildren = item.children?.length || 0 > 0 + return ( +
  • + + {hasChildren && ( +
      + {item.children!.map((childItem, index) => ( + + {getItemElm(childItem)} + + ))} +
    + )} +
  • + ) + } + + return ( +
    setShow(false)} + > +
      + {items.map((item, index) => ( + {getItemElm(item)} + ))} +
    +
    + ) +} diff --git a/www/packages/docs-ui/src/components/Toc/index.tsx b/www/packages/docs-ui/src/components/Toc/index.tsx new file mode 100644 index 0000000000..4ad6da1ea6 --- /dev/null +++ b/www/packages/docs-ui/src/components/Toc/index.tsx @@ -0,0 +1,99 @@ +"use client" + +import React, { useEffect, useState } from "react" +import { ToCItemUi } from "types" +import { + ActiveOnScrollItem, + isElmWindow, + useActiveOnScroll, + useIsBrowser, + useScrollController, +} from "../.." +import { TocList } from "./List" +import clsx from "clsx" +import { TocMenu } from "./Menu" + +export const Toc = () => { + const [items, setItems] = useState([]) + const [showMenu, setShowMenu] = useState(false) + const isBrowser = useIsBrowser() + const { items: headingItems, activeItemId } = useActiveOnScroll({}) + const [maxHeight, setMaxHeight] = useState(0) + const { scrollableElement } = useScrollController() + + const formatHeadingContent = (content: string | null): string => { + return content?.replaceAll(/#$/g, "") || "" + } + + const formatHeadingObject = ({ + heading, + children, + }: ActiveOnScrollItem): ToCItemUi => { + const level = parseInt(heading.tagName.replace("H", "")) + return { + title: formatHeadingContent(heading.textContent), + id: heading.id, + level, + children: children?.map(formatHeadingObject), + associatedHeading: heading as HTMLHeadingElement, + } + } + + useEffect(() => { + setItems(headingItems.map(formatHeadingObject)) + }, [headingItems]) + + const handleResize = () => { + const offset = + (scrollableElement instanceof HTMLElement + ? scrollableElement.offsetTop + : 0) + 56 + + setMaxHeight( + (isElmWindow(scrollableElement) + ? scrollableElement.innerHeight + : scrollableElement?.clientHeight || 0) - offset + ) + } + + useEffect(() => { + if (!isBrowser) { + return + } + + handleResize() + + window.addEventListener("resize", handleResize) + + return () => { + window.removeEventListener("resize", handleResize) + } + }, [isBrowser]) + + return ( +
    setShowMenu(true)}> +
    = 1000 && "-translate-y-1/2" + )} + onMouseOver={() => setShowMenu(true)} + style={{ + maxHeight, + }} + > + +
    + +
    + ) +} diff --git a/www/packages/docs-ui/src/components/TypeList/index.tsx b/www/packages/docs-ui/src/components/TypeList/index.tsx index 9e1bdf9174..94190b6de2 100644 --- a/www/packages/docs-ui/src/components/TypeList/index.tsx +++ b/www/packages/docs-ui/src/components/TypeList/index.tsx @@ -36,7 +36,8 @@ export const TypeList = ({ return (
    { + const [items, setItems] = useState([]) + const [activeItemId, setActiveItemId] = useState("") + const { scrollableElement } = useScrollController() + const isBrowser = useIsBrowser() + const pathname = usePathname() + const root = useMemo(() => { + if (!enable) { + return + } + if (rootElm) { + return rootElm + } + + if (!isBrowser) { + return + } + + return document + }, [rootElm, isBrowser, enable]) + const getHeadingsInElm = useCallback(() => { + if (!isBrowser || !enable) { + return [] + } + + return root?.querySelectorAll("h2,h3") + }, [isBrowser, pathname, root, enable]) + const setHeadingItems = useCallback(() => { + if (!enable) { + return + } + const headings = getHeadingsInElm() + const itemsToSet: ActiveOnScrollItem[] = [] + let lastLevel2HeadingIndex = -1 + + headings?.forEach((heading) => { + const level = parseInt(heading.tagName.replace("H", "")) + const isLevel2 = level === 2 + const headingItem: ActiveOnScrollItem = { + heading: heading as HTMLHeadingElement, + children: [], + } + + if (isLevel2 || lastLevel2HeadingIndex === -1) { + itemsToSet.push(headingItem) + if (isLevel2) { + lastLevel2HeadingIndex = itemsToSet.length - 1 + } + } else if (lastLevel2HeadingIndex !== -1) { + itemsToSet[lastLevel2HeadingIndex].children?.push(headingItem) + } + }) + + setItems(itemsToSet) + }, [getHeadingsInElm, enable]) + + useMutationObserver({ + elm: root, + callback: setHeadingItems, + }) + + const setActiveToClosest = useCallback(() => { + if (!enable) { + return + } + const headings = getHeadingsInElm() + let closestPositiveHeading: HTMLHeadingElement | undefined = undefined + let closestNegativeHeading: HTMLHeadingElement | undefined = undefined + let closestPositiveDistance = Infinity + let closestNegativeDistance = -Infinity + const halfway = isElmWindow(scrollableElement) + ? scrollableElement.innerHeight / 2 + : scrollableElement + ? scrollableElement.scrollHeight / 2 + : 0 + + headings?.forEach((heading) => { + const headingDistance = heading.getBoundingClientRect().top + + if (headingDistance > 0 && headingDistance < closestPositiveDistance) { + closestPositiveDistance = headingDistance + closestPositiveHeading = heading as HTMLHeadingElement + } else if ( + headingDistance < 0 && + headingDistance > closestNegativeDistance + ) { + closestNegativeDistance = headingDistance + closestNegativeHeading = heading as HTMLHeadingElement + } + }) + + const negativeDistanceToHalfway = Math.abs( + halfway + closestNegativeDistance + ) + const positiveDistanceToHalfway = Math.abs( + halfway - closestPositiveDistance + ) + + const chosenClosest = + negativeDistanceToHalfway > positiveDistanceToHalfway + ? closestNegativeHeading + : closestPositiveHeading + + setActiveItemId( + chosenClosest + ? (chosenClosest as HTMLHeadingElement).id + : items.length + ? useDefaultIfNoActive + ? items[0].heading.id + : "" + : "" + ) + }, [getHeadingsInElm, items, enable]) + + useEffect(() => { + if (!scrollableElement || !enable) { + return + } + + scrollableElement.addEventListener("scroll", setActiveToClosest) + + return () => { + scrollableElement.removeEventListener("scroll", setActiveToClosest) + } + }, [scrollableElement, setActiveToClosest, enable]) + + useEffect(() => { + if (items.length && enable) { + setActiveToClosest() + } + }, [items, setActiveToClosest, enable]) + + return { + items, + activeItemId, + } +} diff --git a/www/packages/docs-ui/src/hooks/use-click-outside/index.tsx b/www/packages/docs-ui/src/hooks/use-click-outside/index.tsx new file mode 100644 index 0000000000..821c80b871 --- /dev/null +++ b/www/packages/docs-ui/src/hooks/use-click-outside/index.tsx @@ -0,0 +1,37 @@ +"use client" + +import React, { useCallback, useEffect } from "react" +import { useIsBrowser } from "../.." + +export type UseClickOutsideProps = { + elmRef: React.RefObject + onClickOutside: (e: MouseEvent) => void +} + +export const useClickOutside = ({ + elmRef, + onClickOutside, +}: UseClickOutsideProps) => { + const isBrowser = useIsBrowser() + + const checkClickOutside = useCallback( + (e: MouseEvent) => { + if (!elmRef.current?.contains(e.target as Node)) { + onClickOutside(e) + } + }, + [elmRef.current, onClickOutside] + ) + + useEffect(() => { + if (!isBrowser) { + return + } + + window.document.addEventListener("click", checkClickOutside) + + return () => { + window.document.removeEventListener("click", checkClickOutside) + } + }, [isBrowser, checkClickOutside]) +} diff --git a/www/packages/docs-ui/src/hooks/use-mutation-observer.ts b/www/packages/docs-ui/src/hooks/use-mutation-observer.ts new file mode 100644 index 0000000000..4a3cb41542 --- /dev/null +++ b/www/packages/docs-ui/src/hooks/use-mutation-observer.ts @@ -0,0 +1,31 @@ +import { useEffect } from "react" + +type UseMutationObserverProps = { + elm: Document | HTMLElement | undefined + callback: () => void + options?: { + attributes?: boolean + characterData?: boolean + childList?: boolean + subtree?: boolean + } +} + +export const useMutationObserver = ({ + elm, + callback, + options = { + attributes: true, + characterData: true, + childList: true, + subtree: true, + }, +}: UseMutationObserverProps) => { + useEffect(() => { + if (elm) { + const observer = new MutationObserver(callback) + observer.observe(elm, options) + return () => observer.disconnect() + } + }, [callback, options]) +} diff --git a/www/packages/docs-ui/src/hooks/use-scroll-utils/index.tsx b/www/packages/docs-ui/src/hooks/use-scroll-utils/index.tsx index 209ed041ae..0c7f819043 100644 --- a/www/packages/docs-ui/src/hooks/use-scroll-utils/index.tsx +++ b/www/packages/docs-ui/src/hooks/use-scroll-utils/index.tsx @@ -59,6 +59,10 @@ type ScrollController = { scrollableElement: Element | Window | undefined /** Retrieves the scroll top if the scrollable element */ getScrolledTop: () => number + /** Scrolls to an element */ + scrollToElement: (elm: HTMLElement) => void + /** Scrolls to a top value */ + scrollToTop: (top: number, parentTop?: number) => void } function useScrollControllerContextValue({ @@ -83,6 +87,27 @@ function useScrollControllerContextValue({ return scrollableElement ? getScrolledTopUtil(scrollableElement) : 0 } + const scrollToElement = (elm: HTMLElement) => { + scrollToTop(elm.offsetTop) + } + + const scrollToTop = (top: number, parentTop?: number) => { + const parentOffsetTop = + parentTop !== undefined + ? parentTop + : isElmWindow(scrollableElement) + ? 0 + : scrollableElement instanceof HTMLElement + ? scrollableElement.offsetTop + : 0 + + scrollableElement?.scrollTo({ + // 56 is the height of the navbar + // might need a better way to determine it. + top: top - parentOffsetTop - 56, + }) + } + return useMemo( () => ({ scrollEventsEnabledRef, @@ -94,6 +119,8 @@ function useScrollControllerContextValue({ }, scrollableElement, getScrolledTop, + scrollToElement, + scrollToTop, }), [scrollableElement] ) diff --git a/www/packages/docs-ui/src/layouts/main-content.tsx b/www/packages/docs-ui/src/layouts/main-content.tsx new file mode 100644 index 0000000000..d3b78eeacd --- /dev/null +++ b/www/packages/docs-ui/src/layouts/main-content.tsx @@ -0,0 +1,68 @@ +"use client" + +import React, { useEffect } from "react" +import { useSidebar } from "../providers/Sidebar" +import clsx from "clsx" +import { Bannerv2, MainNav, useIsBrowser } from ".." + +export type MainContentLayoutProps = { + mainWrapperClasses?: string + showBanner?: boolean + children: React.ReactNode +} + +export const MainContentLayout = ({ + children, + mainWrapperClasses, + showBanner = true, +}: MainContentLayoutProps) => { + const isBrowser = useIsBrowser() + const { desktopSidebarOpen } = useSidebar() + + useEffect(() => { + if (!isBrowser) { + return + } + if (desktopSidebarOpen) { + document.body.classList.add("lg:grid-cols-[221px_1fr]") + } else { + document.body.classList.remove("lg:grid-cols-[221px_1fr]") + } + }, [desktopSidebarOpen, isBrowser]) + + return ( +
    + {showBanner && } +
    + +
    + {children} +
    +
    +
    + ) +} diff --git a/www/packages/docs-ui/src/layouts/root.tsx b/www/packages/docs-ui/src/layouts/root.tsx index a2ba565f77..42d0134702 100644 --- a/www/packages/docs-ui/src/layouts/root.tsx +++ b/www/packages/docs-ui/src/layouts/root.tsx @@ -1,48 +1,45 @@ import React from "react" import clsx from "clsx" import { Sidebar, SidebarProps } from "@/components" +import { MobileNavigation } from "../components/MobileNavigation" +import { Toc } from "../components/Toc" +import { MainContentLayout, MainContentLayoutProps } from "./main-content" export type RootLayoutProps = { - children: React.ReactNode ProvidersComponent: React.FC<{ children: React.ReactNode }> - NavbarComponent: React.FC + showToc?: boolean sidebarProps?: SidebarProps htmlClassName?: string bodyClassName?: string - mainWrapperClasses?: string showPagination?: boolean -} +} & MainContentLayoutProps export const RootLayout = ({ ProvidersComponent, - NavbarComponent, - children, sidebarProps, htmlClassName, bodyClassName, - mainWrapperClasses, + showToc = true, + ...mainProps }: RootLayoutProps) => { return ( - -
    -
    - - {children} -
    + + +
    + + {showToc && }
    diff --git a/www/packages/docs-ui/src/layouts/tight.tsx b/www/packages/docs-ui/src/layouts/tight.tsx index 166a643d48..f899c3a62d 100644 --- a/www/packages/docs-ui/src/layouts/tight.tsx +++ b/www/packages/docs-ui/src/layouts/tight.tsx @@ -9,24 +9,17 @@ export const TightLayout = ({ ...props }: RootLayoutProps) => { return ( - +
    -
    - {children} - {showPagination && } -
    + {children} + {showPagination && }
    ) diff --git a/www/packages/docs-ui/src/layouts/wide.tsx b/www/packages/docs-ui/src/layouts/wide.tsx index 87a3d7cf34..0019f51cbc 100644 --- a/www/packages/docs-ui/src/layouts/wide.tsx +++ b/www/packages/docs-ui/src/layouts/wide.tsx @@ -11,9 +11,9 @@ export const WideLayout = ({ return ( -
    +
    {children} {showPagination && }
    diff --git a/www/packages/docs-ui/src/providers/MainNav/index.tsx b/www/packages/docs-ui/src/providers/MainNav/index.tsx new file mode 100644 index 0000000000..a9404d14ae --- /dev/null +++ b/www/packages/docs-ui/src/providers/MainNav/index.tsx @@ -0,0 +1,51 @@ +"use client" + +import React, { createContext, useContext, useMemo, useState } from "react" +import { NavigationDropdownItem } from "types" + +export type MainNavContext = { + navItems: NavigationDropdownItem[] + activeItem?: NavigationDropdownItem + reportIssueLink: string +} + +const MainNavContext = createContext(null) + +export type MainNavProviderProps = { + navItems: NavigationDropdownItem[] + reportIssueLink: string + children?: React.ReactNode +} + +export const MainNavProvider = ({ + navItems, + reportIssueLink, + children, +}: MainNavProviderProps) => { + const activeItem = useMemo( + () => navItems.find((item) => item.type === "link" && item.isActive), + [navItems] + ) + + return ( + + {children} + + ) +} + +export const useMainNav = () => { + const context = useContext(MainNavContext) + + if (!context) { + throw new Error("useMainNav must be used within a MainNavProvider") + } + + return context +} diff --git a/www/packages/docs-ui/src/providers/Mobile/index.tsx b/www/packages/docs-ui/src/providers/Mobile/index.tsx index 9cc600c61e..77e01b55e3 100644 --- a/www/packages/docs-ui/src/providers/Mobile/index.tsx +++ b/www/packages/docs-ui/src/providers/Mobile/index.tsx @@ -22,9 +22,9 @@ export const MobileProvider = ({ children }: MobileProviderProps) => { const [isMobile, setIsMobile] = useState(false) const handleResize = useCallback(() => { - if (window.innerWidth < 1025 && !isMobile) { + if (window.innerWidth < 1024 && !isMobile) { setIsMobile(true) - } else if (window.innerWidth >= 1025 && isMobile) { + } else if (window.innerWidth >= 1024 && isMobile) { setIsMobile(false) } }, [isMobile]) diff --git a/www/packages/docs-ui/src/providers/Navbar/index.tsx b/www/packages/docs-ui/src/providers/Navbar/index.tsx deleted file mode 100644 index 20f9b45cfc..0000000000 --- a/www/packages/docs-ui/src/providers/Navbar/index.tsx +++ /dev/null @@ -1,55 +0,0 @@ -"use client" - -import React, { createContext, useContext, useState, useEffect } from "react" -import { usePathname } from "next/navigation" - -export type NavbarContextType = { - activeItem: string | null - setActiveItem: (value: string) => void -} - -const NavbarContext = createContext(null) - -export type NavbarProviderProps = { - children: React.ReactNode - basePath?: string -} - -export const NavbarProvider = ({ - children, - basePath = "", -}: NavbarProviderProps) => { - const [activeItem, setActiveItem] = useState(null) - const pathname = usePathname() - - const assemblePathName = (path: string) => - `${basePath}/${path.charAt(0) === "/" ? path.substring(1) : path}` - - useEffect(() => { - const newPath = assemblePathName(pathname) - if (activeItem !== newPath) { - setActiveItem(newPath) - } - }, [pathname, activeItem]) - - return ( - - {children} - - ) -} - -export const useNavbar = (): NavbarContextType => { - const context = useContext(NavbarContext) - - if (!context) { - throw new Error("useNavbar must be used inside a NavbarProvider") - } - - return context -} diff --git a/www/packages/docs-ui/src/providers/Pagination/index.tsx b/www/packages/docs-ui/src/providers/Pagination/index.tsx index 7104da3381..f8211b21ef 100644 --- a/www/packages/docs-ui/src/providers/Pagination/index.tsx +++ b/www/packages/docs-ui/src/providers/Pagination/index.tsx @@ -9,7 +9,7 @@ import React, { } from "react" import { useSidebar } from "../Sidebar" import { usePrevious } from "@uidotdev/usehooks" -import { SidebarItemType } from "types" +import { InteractiveSidebarItem, SidebarItem } from "types" export type Page = { title: string @@ -27,8 +27,8 @@ export const PaginationContext = createContext( null ) -type SidebarItemWithParent = SidebarItemType & { - parent?: SidebarItemType +type SidebarItemWithParent = InteractiveSidebarItem & { + parent?: SidebarItem } type SearchItemsResult = { @@ -43,20 +43,20 @@ export type PaginationProviderProps = { export const PaginationProvider = ({ children }: PaginationProviderProps) => { const { items, activePath } = useSidebar() - const combinedItems = useMemo(() => [...items.top, ...items.bottom], [items]) + const combinedItems = useMemo(() => [...items.default], [items]) const previousActivePath = usePrevious(activePath) const [nextPage, setNextPage] = useState() const [prevPage, setPrevPage] = useState() const getFirstChild = ( - item: SidebarItemType + item: InteractiveSidebarItem ): SidebarItemWithParent | undefined => { const children = getChildrenWithPages(item) if (!children?.length) { return undefined } - return children[0].path + return children[0].type === "link" ? { ...children[0], parent: item, @@ -65,16 +65,18 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { } const getChildrenWithPages = ( - item: SidebarItemType + item: InteractiveSidebarItem ): SidebarItemWithParent[] | undefined => { return item.children?.filter( (childItem) => - childItem.path !== undefined || getChildrenWithPages(childItem)?.length - ) + childItem.type === "link" || + (childItem.type !== "separator" && + getChildrenWithPages(childItem)?.length) + ) as SidebarItemWithParent[] } const getPrevItem = ( - items: SidebarItemType[], + items: SidebarItem[], index: number ): SidebarItemWithParent | undefined => { let foundItem: SidebarItemWithParent | undefined @@ -82,6 +84,9 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { .slice(0, index) .reverse() .some((item) => { + if (item.type === "separator") { + return false + } if (item.children?.length) { const childItem = getPrevItem(item.children, item.children.length) if (childItem) { @@ -90,7 +95,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { parent: item, } } - } else if (item.path) { + } else if (item.type === "link") { foundItem = item } @@ -101,12 +106,16 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { } const getNextItem = ( - items: SidebarItemType[], + items: SidebarItem[], index: number ): SidebarItemWithParent | undefined => { let foundItem: SidebarItemWithParent | undefined items.slice(index + 1).some((item) => { - if (item.path) { + if (item.type === "separator") { + return false + } + + if (item.type === "link") { foundItem = item } else if (item.children?.length) { const childItem = getNextItem(item.children, -1) @@ -124,13 +133,13 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { return foundItem } - const searchItems = (currentItems: SidebarItemType[]): SearchItemsResult => { + const searchItems = (currentItems: SidebarItem[]): SearchItemsResult => { const result: SearchItemsResult = { foundActive: false, } result.foundActive = currentItems.some((item, index) => { - if (item.path === activePath) { + if (item.type === "link" && item.path === activePath) { if (index !== 0) { result.prevItem = getPrevItem(currentItems, index) } @@ -145,16 +154,15 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { return true } - if (item.children?.length) { + if (item.type !== "separator" && item.children?.length) { const childrenResult = searchItems(item.children) if (childrenResult.foundActive) { result.prevItem = childrenResult.prevItem result.nextItem = childrenResult.nextItem if (!result.prevItem) { - result.prevItem = item.path - ? item - : getPrevItem(currentItems, index) + result.prevItem = + item.type === "link" ? item : getPrevItem(currentItems, index) } if (!result.nextItem && index !== currentItems.length - 1) { @@ -178,8 +186,11 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { result.prevItem ? { title: result.prevItem.title, - link: result.prevItem.path || "", - parentTitle: result.prevItem.parent?.title, + link: result.prevItem.type === "link" ? result.prevItem.path : "", + parentTitle: + result.prevItem.parent?.type !== "separator" + ? result.prevItem.parent?.title + : undefined, } : undefined ) @@ -187,8 +198,11 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => { result.nextItem ? { title: result.nextItem.title, - link: result.nextItem.path || "", - parentTitle: result.nextItem.parent?.title, + link: result.nextItem.type === "link" ? result.nextItem.path : "", + parentTitle: + result.nextItem.parent?.type !== "separator" + ? result.nextItem.parent?.title + : undefined, } : undefined ) diff --git a/www/packages/docs-ui/src/providers/Sidebar/index.tsx b/www/packages/docs-ui/src/providers/Sidebar/index.tsx index c4534793ce..bdc97ebe80 100644 --- a/www/packages/docs-ui/src/providers/Sidebar/index.tsx +++ b/www/packages/docs-ui/src/providers/Sidebar/index.tsx @@ -15,53 +15,47 @@ import { getScrolledTop } from "@/utils" import { useIsBrowser } from "@/hooks" import { SidebarItemSections, - SidebarItemType, - SidebarSectionItemsType, + SidebarItem, + SidebarSectionItems, + SidebarItemLink, + InteractiveSidebarItem, + SidebarItemCategory, } from "types" -export type CurrentItemsState = SidebarSectionItemsType & { +export type CurrentItemsState = SidebarSectionItems & { previousSidebar?: CurrentItemsState } export type SidebarStyleOptions = { disableActiveTransition?: boolean - noTitleStyling?: boolean } export type SidebarContextType = { - items: SidebarSectionItemsType + items: SidebarSectionItems currentItems: CurrentItemsState | undefined activePath: string | null - getActiveItem: () => SidebarItemType | undefined + getActiveItem: () => SidebarItemLink | undefined setActivePath: (path: string | null) => void - isItemActive: (item: SidebarItemType, checkChildren?: boolean) => boolean - addItems: ( - item: SidebarItemType[], - options?: { - section?: SidebarItemSections - parent?: { - path: string - changeLoaded?: boolean - } - indexPosition?: number - ignoreExisting?: boolean - } - ) => void + isLinkActive: (item: SidebarItem, checkChildren?: boolean) => boolean + isChildrenActive: (item: SidebarItemCategory) => boolean + addItems: (item: SidebarItem[], options?: ActionOptionsType) => void findItemInSection: ( - section: SidebarItemType[], - item: Partial, + section: SidebarItem[], + item: Partial, checkChildren?: boolean - ) => SidebarItemType | undefined + ) => SidebarItem | undefined mobileSidebarOpen: boolean setMobileSidebarOpen: React.Dispatch> - isSidebarEmpty: () => boolean desktopSidebarOpen: boolean setDesktopSidebarOpen: React.Dispatch> staticSidebarItems?: boolean shouldHandleHashChange: boolean sidebarRef: React.RefObject goBack: () => void + sidebarTopHeight: number + setSidebarTopHeight: React.Dispatch> resetItems: () => void + isItemLoaded: (path: string) => boolean } & SidebarStyleOptions export const SidebarContext = createContext(null) @@ -70,6 +64,7 @@ export type ActionOptionsType = { section?: SidebarItemSections parent?: { path: string + title: string changeLoaded?: boolean } indexPosition?: number @@ -79,25 +74,36 @@ export type ActionOptionsType = { export type ActionType = | { type: "add" | "update" - items: SidebarItemType[] + items: SidebarItem[] options?: ActionOptionsType } | { type: "replace" - replacementItems: SidebarSectionItemsType + replacementItems: SidebarSectionItems } +const areItemsEqual = (itemA: SidebarItem, itemB: SidebarItem): boolean => { + if (itemA.type === "separator" || itemB.type === "separator") { + return false + } + const hasSameTitle = itemA.title === itemB.title + const hasSamePath = + itemA.type === "link" && itemB.type === "link" && itemA.path === itemB.path + + return hasSameTitle || hasSamePath +} + const findItem = ( - section: SidebarItemType[], - item: Partial, + section: SidebarItem[], + item: Partial, checkChildren = true -): SidebarItemType | undefined => { - let foundItem: SidebarItemType | undefined +): SidebarItemLink | undefined => { + let foundItem: SidebarItemLink | undefined section.some((i) => { - if ( - (!item.path && !i.path && i.title === item.title) || - i.path === item.path - ) { + if (i.type === "separator") { + return false + } + if (areItemsEqual(item as SidebarItem, i) && i.type === "link") { foundItem = i } else if (checkChildren && i.children) { foundItem = findItem(i.children, item) @@ -109,28 +115,19 @@ const findItem = ( return foundItem } -export const reducer = ( - state: SidebarSectionItemsType, - actionData: ActionType -) => { +export const reducer = (state: SidebarSectionItems, actionData: ActionType) => { if (actionData.type === "replace") { return actionData.replacementItems } - const { type, options } = actionData let { items } = actionData - const { - section = SidebarItemSections.TOP, - parent, - ignoreExisting = false, - indexPosition, - } = options || {} + const { parent, ignoreExisting = false, indexPosition } = options || {} + const sectionName = SidebarItemSections.DEFAULT + const sectionItems = state[sectionName] if (!ignoreExisting) { - const selectedSection = - section === SidebarItemSections.BOTTOM ? state.bottom : state.top - items = items.filter((item) => !findItem(selectedSection, item)) + items = items.filter((item) => !findItem(sectionItems, item)) } if (!items.length) { @@ -141,21 +138,24 @@ export const reducer = ( case "add": return { ...state, - [section]: + [sectionName]: indexPosition !== undefined ? [ - ...state[section].slice(0, indexPosition), + ...sectionItems.slice(0, indexPosition), ...items, - ...state[section].slice(indexPosition), + ...sectionItems.slice(indexPosition), ] - : [...state[section], ...items], + : [...sectionItems, ...items], } case "update": // find item index return { ...state, - [section]: state[section].map((i) => { - if (i.path && parent?.path && i.path === parent?.path) { + [sectionName]: sectionItems.map((i) => { + if (i.type === "separator") { + return i + } + if (parent && areItemsEqual(i, parent as SidebarItem)) { return { ...i, children: @@ -166,7 +166,11 @@ export const reducer = ( ...(i.children?.slice(indexPosition) || []), ] : [...(i.children || []), ...items], - loaded: parent.changeLoaded ? true : i.loaded, + loaded: parent.changeLoaded + ? true + : i.type === "link" + ? i.loaded + : true, } } return i @@ -181,7 +185,7 @@ export type SidebarProviderProps = { children?: ReactNode isLoading?: boolean setIsLoading?: React.Dispatch> - initialItems?: SidebarSectionItemsType + initialItems?: SidebarSectionItems shouldHandleHashChange?: boolean shouldHandlePathChange?: boolean scrollableElement?: Element | Window @@ -199,12 +203,10 @@ export const SidebarProvider = ({ scrollableElement, staticSidebarItems = false, disableActiveTransition = false, - noTitleStyling = false, resetOnCondition, }: SidebarProviderProps) => { const [items, dispatch] = useReducer(reducer, { - top: initialItems?.top || [], - bottom: initialItems?.bottom || [], + default: initialItems?.default || [], mobile: initialItems?.mobile || [], }) const [currentItems, setCurrentItems] = useState< @@ -212,6 +214,7 @@ export const SidebarProvider = ({ >() const [activePath, setActivePath] = useState("") const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false) + const [sidebarTopHeight, setSidebarTopHeight] = useState(0) const [desktopSidebarOpen, setDesktopSidebarOpen] = useState(true) const sidebarRef = useRef(null) @@ -224,30 +227,29 @@ export const SidebarProvider = ({ const findItemInSection = useCallback(findItem, []) + const isItemLoaded = useCallback( + (path: string) => { + const item = + findItemInSection(items.mobile, { path, type: "link" }) || + findItemInSection(items.default, { path, type: "link" }) + + return item?.loaded || false + }, + [items] + ) + const getActiveItem = useCallback(() => { if (activePath === null) { return undefined } return ( - findItemInSection(items.mobile, { path: activePath }) || - findItemInSection(items.top, { path: activePath }) || - findItemInSection(items.bottom, { path: activePath }) + findItemInSection(items.mobile, { path: activePath, type: "link" }) || + findItemInSection(items.default, { path: activePath, type: "link" }) ) }, [activePath, items, findItemInSection]) - const addItems = ( - newItems: SidebarItemType[], - options?: { - section?: SidebarItemSections - parent?: { - path: string - changeLoaded?: boolean - } - indexPosition?: number - ignoreExisting?: boolean - } - ) => { + const addItems = (newItems: SidebarItem[], options?: ActionOptionsType) => { dispatch({ type: options?.parent ? "update" : "add", items: newItems, @@ -255,8 +257,12 @@ export const SidebarProvider = ({ }) } - const isItemActive = useCallback( - (item: SidebarItemType, checkChildren = false): boolean => { + const isLinkActive = useCallback( + (item: SidebarItem, checkChildren = false): boolean => { + if (item.type !== "link") { + return false + } + return ( item.path === activePath || (checkChildren && activePath?.split("_")[0] === item.path) @@ -265,15 +271,22 @@ export const SidebarProvider = ({ [activePath] ) - const isSidebarEmpty = useCallback((): boolean => { - return Object.values(items).every((sectionItems) => { - if (!Array.isArray(sectionItems)) { - return true - } + const isChildrenActive = useCallback( + (item: InteractiveSidebarItem): boolean => { + return ( + item.children?.some((child) => { + if (isLinkActive(child, true)) { + return true + } - return sectionItems.length === 0 - }) - }, [items]) + return child.type !== "separator" && child.children + ? isChildrenActive(child) + : false + }) || false + ) + }, + [isLinkActive] + ) const init = () => { const currentPath = location.hash.replace("#", "") @@ -283,23 +296,27 @@ export const SidebarProvider = ({ } const getCurrentSidebar = useCallback( - (searchItems: SidebarItemType[]): SidebarItemType | undefined => { - let currentSidebar: SidebarItemType | undefined + (searchItems: SidebarItem[]): InteractiveSidebarItem | undefined => { + let currentSidebar: InteractiveSidebarItem | undefined searchItems.some((item) => { - if (item.isChildSidebar) { - if (isItemActive(item)) { - currentSidebar = item - } else if (item.children?.length) { - const childSidebar = - getCurrentSidebar(item.children) || - findItem(item.children, { path: activePath || undefined }) + if (item.type === "separator") { + return false + } + if (item.isChildSidebar && isLinkActive(item)) { + currentSidebar = item + } - if (childSidebar) { - currentSidebar = childSidebar.isChildSidebar ? childSidebar : item - } + if (!currentSidebar && item.children?.length) { + const childSidebar = + getCurrentSidebar(item.children) || + findItem(item.children, { + path: activePath || undefined, + type: "link", + }) + + if (childSidebar) { + currentSidebar = childSidebar.isChildSidebar ? childSidebar : item } - } else if (item.children?.length) { - currentSidebar = getCurrentSidebar(item.children) } return currentSidebar !== undefined @@ -307,7 +324,7 @@ export const SidebarProvider = ({ return currentSidebar }, - [isItemActive, activePath] + [isLinkActive, activePath] ) const goBack = () => { @@ -317,9 +334,9 @@ export const SidebarProvider = ({ const previousSidebar = currentItems.previousSidebar || items - const backItem = - previousSidebar.top.find((item) => item.path && !item.isChildSidebar) || - previousSidebar.bottom.find((item) => item.path && !item.isChildSidebar) + const backItem = previousSidebar.default.find( + (item) => item.type === "link" && !item.isChildSidebar + ) as SidebarItemLink if (!backItem) { return @@ -334,8 +351,7 @@ export const SidebarProvider = ({ dispatch({ type: "replace", replacementItems: { - top: initialItems?.top || [], - bottom: initialItems?.bottom || [], + default: initialItems?.default || [], mobile: initialItems?.mobile || [], }, }) @@ -391,7 +407,7 @@ export const SidebarProvider = ({ }, [shouldHandleHashChange, isBrowser]) useEffect(() => { - if (isLoading && items.top.length && items.bottom.length) { + if (isLoading && items.default.length) { setIsLoading?.(false) } }, [items, isLoading, setIsLoading]) @@ -412,8 +428,7 @@ export const SidebarProvider = ({ return } - const currentSidebar = - getCurrentSidebar(items.top) || getCurrentSidebar(items.bottom) + const currentSidebar = getCurrentSidebar(items.default) if (!currentSidebar) { setCurrentItems(undefined) @@ -423,18 +438,20 @@ export const SidebarProvider = ({ if ( currentSidebar.isChildSidebar && currentSidebar.children && - currentItems?.parentItem?.path !== currentSidebar.path + (!currentItems?.parentItem || + !areItemsEqual(currentItems?.parentItem, currentSidebar)) ) { const { children, ...parentItem } = currentSidebar + const hasPreviousSidebar = + currentItems?.previousSidebar?.parentItem?.type === "link" && + parentItem.type === "link" && + currentItems.previousSidebar.parentItem.path !== parentItem.path + setCurrentItems({ - top: children, - bottom: [], + default: children, mobile: items.mobile, parentItem: parentItem, - previousSidebar: - currentItems?.previousSidebar?.parentItem?.path !== parentItem.path - ? currentItems - : undefined, + previousSidebar: hasPreviousSidebar ? currentItems : undefined, }) } }, [getCurrentSidebar, activePath]) @@ -443,7 +460,7 @@ export const SidebarProvider = ({ if (resetOnCondition?.()) { resetItems() } - }, [resetOnCondition]) + }, [resetOnCondition, resetItems]) return ( {children} diff --git a/www/packages/docs-ui/src/providers/SiteConifg/index.tsx b/www/packages/docs-ui/src/providers/SiteConifg/index.tsx index ee1a8ef1eb..f272cd604c 100644 --- a/www/packages/docs-ui/src/providers/SiteConifg/index.tsx +++ b/www/packages/docs-ui/src/providers/SiteConifg/index.tsx @@ -23,8 +23,7 @@ export const SiteConfigProvider = ({ initConfig || { baseUrl: "", sidebar: { - top: [], - bottom: [], + default: [], mobile: [], }, } diff --git a/www/packages/docs-ui/src/providers/index.ts b/www/packages/docs-ui/src/providers/index.ts index b9734b0aac..0c906ef4ca 100644 --- a/www/packages/docs-ui/src/providers/index.ts +++ b/www/packages/docs-ui/src/providers/index.ts @@ -2,9 +2,9 @@ export * from "./AiAssistant" export * from "./Analytics" export * from "./ColorMode" export * from "./LearningPath" +export * from "./MainNav" export * from "./Mobile" export * from "./Modal" -export * from "./Navbar" export * from "./Notification" export * from "./PageLoading" export * from "./Pagination" diff --git a/www/packages/docs-ui/src/utils/check-sidebar-item-visibility.ts b/www/packages/docs-ui/src/utils/check-sidebar-item-visibility.ts index 3b8a690def..932991eb69 100644 --- a/www/packages/docs-ui/src/utils/check-sidebar-item-visibility.ts +++ b/www/packages/docs-ui/src/utils/check-sidebar-item-visibility.ts @@ -1,21 +1,23 @@ -const TOP_MARGIN = 57 - export function checkSidebarItemVisibility( item: HTMLElement, - withTransition = false + withTransition = false, + topMargin = 0 ) { return withTransition - ? checkSidebarItemVisibilityTransition(item) - : checkSidebarItemVisibilityRelative(item) + ? checkSidebarItemVisibilityTransition(item, topMargin) + : checkSidebarItemVisibilityRelative(item, topMargin) } -function checkSidebarItemVisibilityRelative(item: HTMLElement) { +function checkSidebarItemVisibilityRelative( + item: HTMLElement, + topMargin: number +) { const sidebar = document.getElementById("sidebar") if (!sidebar) { return false } const sidebarBoundingRect = sidebar.getBoundingClientRect() - const sidebarTop = sidebarBoundingRect.top - TOP_MARGIN + const sidebarTop = sidebarBoundingRect.top - topMargin const sidebarBottom = sidebarTop + sidebarBoundingRect.height const itemBoundingRect = item.getBoundingClientRect() const itemTop = @@ -25,7 +27,10 @@ function checkSidebarItemVisibilityRelative(item: HTMLElement) { return itemTop >= sidebarTop && itemBottom <= sidebarBottom } -function checkSidebarItemVisibilityTransition(item: HTMLElement) { +function checkSidebarItemVisibilityTransition( + item: HTMLElement, + topMargin: number +) { const sidebar = document.getElementById("sidebar") if (!sidebar) { return false @@ -35,8 +40,8 @@ function checkSidebarItemVisibilityTransition(item: HTMLElement) { const activeItemBoundingRect = item.getBoundingClientRect() return ( - activeItemBoundingRect.top >= TOP_MARGIN && - activeItemBoundingRect.top - sidebarBoundingRect.height + TOP_MARGIN < 0 && + activeItemBoundingRect.top >= topMargin && + activeItemBoundingRect.top - sidebarBoundingRect.height + topMargin < 0 && activeItemBoundingRect.bottom > 0 ) } diff --git a/www/packages/docs-ui/src/utils/get-mobile-sidebar-items.ts b/www/packages/docs-ui/src/utils/get-mobile-sidebar-items.ts index eaf3761523..bd21574e02 100644 --- a/www/packages/docs-ui/src/utils/get-mobile-sidebar-items.ts +++ b/www/packages/docs-ui/src/utils/get-mobile-sidebar-items.ts @@ -1,4 +1,4 @@ -import { SidebarItemType } from "types" +import { SidebarItem } from "types" import { mobileSidebarItemsV1, mobileSidebarItemsV2 } from ".." type Options = { @@ -9,10 +9,14 @@ type Options = { export function getMobileSidebarItems({ baseUrl, version = "v1", -}: Options): SidebarItemType[] { +}: Options): SidebarItem[] { const mobileItems = version === "v2" ? mobileSidebarItemsV2 : mobileSidebarItemsV1 return mobileItems.map((item) => { + if (item.type !== "link") { + return item + } + return { ...item, path: `${baseUrl}${item.path}`, diff --git a/www/packages/docs-ui/src/utils/get-navbar-items.ts b/www/packages/docs-ui/src/utils/get-navbar-items.ts index 670e572c27..fb8fba9863 100644 --- a/www/packages/docs-ui/src/utils/get-navbar-items.ts +++ b/www/packages/docs-ui/src/utils/get-navbar-items.ts @@ -1,4 +1,5 @@ -import { NavbarItem, navbarItemsV1, navbarItemsV2 } from ".." +import { NavigationDropdownItem } from "types" +import { navDropdownItemsV1, navDropdownItemsV2 } from ".." type Options = { basePath: string @@ -6,24 +7,21 @@ type Options = { version?: "v1" | "v2" } -export function getNavbarItems({ +export function getNavDropdownItems({ basePath, activePath, version = "v1", -}: Options): NavbarItem[] { - const navbarItems = version === "v2" ? navbarItemsV2 : navbarItemsV1 - return navbarItems.map((item) => { +}: Options): NavigationDropdownItem[] { + const items = version === "v2" ? navDropdownItemsV2 : navDropdownItemsV1 + return items.map((item) => { if (item.type === "divider") { return item } return { ...item, - props: { - ...item.props, - isActive: activePath === item.props?.href, - href: `${basePath}${item.props?.href}`, - }, + isActive: activePath === item.path, + path: `${basePath}${item.path}`, } }) } diff --git a/www/packages/docs-ui/src/utils/sidebar-attach-href-common-options.ts b/www/packages/docs-ui/src/utils/sidebar-attach-href-common-options.ts index 363b6d6d72..bb44f8b048 100644 --- a/www/packages/docs-ui/src/utils/sidebar-attach-href-common-options.ts +++ b/www/packages/docs-ui/src/utils/sidebar-attach-href-common-options.ts @@ -1,16 +1,22 @@ -import { RawSidebarItemType } from "types" +import { RawSidebarItem } from "types" -const commonOptions: Partial = { +const commonOptions: Partial = { loaded: true, isPathHref: true, } export function sidebarAttachHrefCommonOptions( - sidebar: RawSidebarItemType[] -): RawSidebarItemType[] { - return sidebar.map((item) => ({ - ...commonOptions, - ...item, - children: sidebarAttachHrefCommonOptions(item.children || []), - })) + sidebar: RawSidebarItem[] +): RawSidebarItem[] { + return sidebar.map((item) => { + if (item.type === "separator") { + return item + } + + return { + ...commonOptions, + ...item, + children: sidebarAttachHrefCommonOptions(item.children || []), + } + }) } diff --git a/www/packages/remark-rehype-plugins/src/page-number.ts b/www/packages/remark-rehype-plugins/src/page-number.ts index a738592915..cc16a4d978 100644 --- a/www/packages/remark-rehype-plugins/src/page-number.ts +++ b/www/packages/remark-rehype-plugins/src/page-number.ts @@ -1,12 +1,12 @@ import path from "path" import type { Transformer } from "unified" -import type { RawSidebarItemType } from "types" +import type { RawSidebarItem } from "types" import type { UnistTree } from "./types/index.js" export function pageNumberRehypePlugin({ sidebar, }: { - sidebar: RawSidebarItemType[] + sidebar: RawSidebarItem[] }): Transformer { return async (tree, file) => { const { valueToEstree } = await import("estree-util-value-to-estree") @@ -66,12 +66,15 @@ export function pageNumberRehypePlugin({ } function findSidebarItem( - sidebar: RawSidebarItemType[], + sidebar: RawSidebarItem[], path: string -): RawSidebarItemType | undefined { +): RawSidebarItem | undefined { let foundItem = undefined for (const item of sidebar) { - if (path === item.path) { + if (item.type === "separator") { + continue + } + if (item.type === "link" && path === item.path) { foundItem = item } else if (item.children) { foundItem = findSidebarItem(item.children, path) diff --git a/www/packages/tailwind/base.tailwind.config.js b/www/packages/tailwind/base.tailwind.config.js index de32c117ec..6df148f5fa 100644 --- a/www/packages/tailwind/base.tailwind.config.js +++ b/www/packages/tailwind/base.tailwind.config.js @@ -68,6 +68,9 @@ module.exports = { error: "var(--docs-border-error)", danger: "var(--docs-border-danger)", transparent: "var(--docs-border-transparent)", + menu: { + top: "var(--docs-border-menu-top)", + }, }, button: { inverted: { @@ -269,33 +272,51 @@ module.exports = { "code-fade-bottom-to-top-dark": `linear-gradient(180deg, rgba(47, 47, 50, 0.00) 0%, #2F2F32 100%)`, "base-code-fade-right-to-left-dark": `linear-gradient(90deg, #27272aa3, #27272A)`, "subtle-code-fade-right-to-left-dark": `linear-gradient(90deg, #30303380, #303033)`, + "border-dotted": + "linear-gradient(90deg,var(--docs-border-strong) 1px,transparent 1px)", }, screens: { - xs: "576px", - lg: "1025px", - xl: "1419px", - xxl: "1440px", + xs: "568px", + sm: "640px", + md: "768px", + lg: "1024px", + xl: "1280px", + xxl: "1536px", + xxxl: "3840px", }, transitionTimingFunction: { ease: "ease", }, width: { - sidebar: "321px", - "sidebar-hidden": "0px", - "main-content": "1140px", - "main-content-hidden-sidebar": "1440px", - "ref-sidebar": "280px", - "ref-main": "calc(100% - 280px)", - "ref-content": "calc(100% - 484px)", - }, - height: { - navbar: "57px", + toc: "221px", }, maxWidth: { - "main-content": "1140px", - "main-content-hidden-sidebar": "1440px", - xl: "1419px", - xxl: "1440px", + // sidebar + "sidebar-xs": "300px", + "sidebar-sm": "300px", + "sidebar-md": "300px", + "sidebar-lg": "221px", + "sidebar-xl": "221px", + "sidebar-xxl": "221px", + "sidebar-xxxl": "221px", + // main content + "main-content-xs": "100%", + "main-content-sm": "100%", + "main-content-md": "100%", + "main-content-lg": "751px", + "main-content-xl": "1007px", + "main-content-xxl": "1263px", + "main-content-xxxl": "3567px", + // inner content + "inner-content-xs": "272px", + "inner-content-sm": "592px", + "inner-content-md": "640px", + "inner-content-lg": "640px", + "inner-content-xl": "640px", + "inner-content-xxl": "640px", + "inner-content-xxxl": "640px", + // wide layout + "wide-content": "1112px", }, minWidth: { xl: "1419px", @@ -596,6 +617,24 @@ module.exports = { backgroundColor: "transparent", }, }, + slideInDown: { + from: { + transform: "translate3d(0, -100%, 0)", + visibility: "visible", + }, + to: { + transform: "translate3d(0, 0, 0)", + }, + }, + slideOutUp: { + from: { + transform: "translate3d(0, 0, 0)", + }, + to: { + transform: "translate3d(0, -100%, 0)", + visibility: "hidden", + }, + }, }, animation: { fadeIn: "fadeIn 500ms", @@ -608,9 +647,11 @@ module.exports = { fadeOutRight: "fadeOutRight 500ms", tada: "tada 1s", slideInRight: "slideInRight 500ms", - slideOutRight: "slideOutRight 500ms", + slideOutRight: "slideOutRight 150ms", + slideOutUp: "slideOutUp 500ms", slideInLeft: "slideInLeft 500ms", slideOutLeft: "slideOutLeft 500ms", + slideInDown: "slideInDown 150ms", pulsingDots: "pulsingDots 1s alternate infinite", minimize: "minimize 500ms", maximize: "maximize 500ms", diff --git a/www/packages/tailwind/theme-presets.js b/www/packages/tailwind/theme-presets.js index 77aa118506..f0cf3b5edf 100644 --- a/www/packages/tailwind/theme-presets.js +++ b/www/packages/tailwind/theme-presets.js @@ -36,6 +36,7 @@ const light = { "--docs-border-error": "rgba(225, 29, 72, 1)", "--docs-border-danger": "rgba(190, 18, 60, 1)", "--docs-border-transparent": "rgba(255, 255, 255, 0)", + "--docs-border-menu-top": "rgba(228, 228, 231, 1)", "--docs-button-inverted": "rgba(39, 39, 42, 1)", "--docs-button-inverted-hover": "rgba(63, 63, 70, 1)", @@ -125,7 +126,7 @@ const dark = { "--docs-fg-base": "rgba(244, 244, 245, 1)", "--docs-fg-subtle": "rgba(161, 161, 170, 1)", - "--docs-fg-muted": "rgba(161, 161, 170, 1)", + "--docs-fg-muted": "rgba(113, 113, 122, 1)", "--docs-fg-disabled": "rgba(82, 82, 91, 1)", "--docs-fg-on-color": "rgba(255, 255, 255, 1)", "--docs-fg-on-inverted": "rgba(9, 9, 11, 1)", @@ -139,6 +140,7 @@ const dark = { "--docs-border-error": "rgba(251, 113, 133, 1)", "--docs-border-danger": "rgba(190, 18, 60, 1)", "--docs-border-transparent": "rgba(255, 255, 255, 0)", + "--docs-border-menu-top": "rgba(255, 255, 255, 0.08)", "--docs-button-inverted": "rgba(82, 82, 91, 1)", "--docs-button-inverted-hover": "rgba(113, 113, 122, 1)", diff --git a/www/packages/types/package.json b/www/packages/types/package.json index ee93f6bfa5..3f23092167 100644 --- a/www/packages/types/package.json +++ b/www/packages/types/package.json @@ -39,5 +39,8 @@ }, "engines": { "node": ">=18.17.0" + }, + "dependencies": { + "@medusajs/icons": "^1.2.2" } } diff --git a/www/packages/types/src/config.ts b/www/packages/types/src/config.ts index e912baf9e1..2f535e9cfe 100644 --- a/www/packages/types/src/config.ts +++ b/www/packages/types/src/config.ts @@ -1,10 +1,10 @@ -import { SidebarSectionItemsType } from "./sidebar.js" +import { SidebarSectionItems } from "./sidebar.js" export declare type DocsConfig = { titleSuffix?: string baseUrl: string basePath?: string - sidebar: SidebarSectionItemsType + sidebar: SidebarSectionItems filesBasePath?: string useNextLinks?: boolean } diff --git a/www/packages/types/src/index.ts b/www/packages/types/src/index.ts index 8d7f487fed..b9d50568d1 100644 --- a/www/packages/types/src/index.ts +++ b/www/packages/types/src/index.ts @@ -1,5 +1,8 @@ export * from "./api-testing.js" export * from "./config.js" export * from "./general.js" +export * from "./menu.js" +export * from "./navigation-dropdown.js" export * from "./sidebar.js" +export * from "./toc.js" export * from "./workflow.js" diff --git a/www/packages/types/src/menu.ts b/www/packages/types/src/menu.ts new file mode 100644 index 0000000000..51b4644588 --- /dev/null +++ b/www/packages/types/src/menu.ts @@ -0,0 +1,20 @@ +export type MenuItemLink = { + type: "link" + icon: React.ReactNode + title: string + link: string +} + +export type MenuItemDivider = { + type: "divider" +} + +export type MenuItemAction = { + type: "action" + icon: React.ReactNode + title: string + shortcut?: string + action: () => void +} + +export type MenuItem = MenuItemLink | MenuItemDivider | MenuItemAction diff --git a/www/packages/types/src/navigation-dropdown.ts b/www/packages/types/src/navigation-dropdown.ts new file mode 100644 index 0000000000..c7f1a8044e --- /dev/null +++ b/www/packages/types/src/navigation-dropdown.ts @@ -0,0 +1,16 @@ +import { IconProps } from "@medusajs/icons/dist/types.js" + +export type NavigationDropdownItemLink = { + path: string + isActive?: boolean + title: string + icon: React.FC +} + +export type NavigationDropdownItem = + | ({ + type: "link" + } & NavigationDropdownItemLink) + | { + type: "divider" + } diff --git a/www/packages/types/src/sidebar.ts b/www/packages/types/src/sidebar.ts index 33491ca24e..16138c4ca5 100644 --- a/www/packages/types/src/sidebar.ts +++ b/www/packages/types/src/sidebar.ts @@ -1,30 +1,55 @@ export enum SidebarItemSections { - TOP = "top", - BOTTOM = "bottom", + DEFAULT = "default", MOBILE = "mobile", } -export type SidebarItemType = { - path?: string +export type SidebarItemCommon = { title: string - pageTitle?: string - additionalElms?: React.ReactNode - children?: SidebarItemType[] - loaded?: boolean - isPathHref?: boolean - linkProps?: React.AllHTMLAttributes + children?: SidebarItem[] isChildSidebar?: boolean hasTitleStyling?: boolean childSidebarTitle?: string + loaded?: boolean + additionalElms?: React.ReactNode } -export type SidebarSectionItemsType = { - [k in SidebarItemSections]: SidebarItemType[] +export type SidebarItemLink = SidebarItemCommon & { + type: "link" + path: string + isPathHref?: boolean + linkProps?: React.AllHTMLAttributes + childrenSameLevel?: boolean +} + +export type SidebarItemCategory = SidebarItemCommon & { + type: "category" + onOpen?: () => void + initialOpen?: boolean +} + +export type SidebarItemSubCategory = SidebarItemCommon & { + type: "sub-category" + childrenSameLevel?: boolean +} + +export type SidebarItemSeparator = { + type: "separator" +} + +export type InteractiveSidebarItem = + | SidebarItemLink + | SidebarItemCategory + | SidebarItemSubCategory + +export type SidebarItem = InteractiveSidebarItem | SidebarItemSeparator + +export type SidebarSectionItems = { + [k in SidebarItemSections]: SidebarItem[] } & { - parentItem?: SidebarItemType + parentItem?: InteractiveSidebarItem } -export type RawSidebarItemType = SidebarItemType & { +export type RawSidebarItem = SidebarItem & { autogenerate_path?: string custom_autogenerate?: string number?: string diff --git a/www/packages/types/src/toc.ts b/www/packages/types/src/toc.ts new file mode 100644 index 0000000000..139a08b847 --- /dev/null +++ b/www/packages/types/src/toc.ts @@ -0,0 +1,11 @@ +export type ToCItem = { + title: string + id: string + level: number + children?: ToCItem[] +} + +export type ToCItemUi = Omit & { + children?: ToCItemUi[] + associatedHeading: HTMLHeadingElement +} diff --git a/www/yarn.lock b/www/yarn.lock index d631d5cd86..75350b9430 100644 --- a/www/yarn.lock +++ b/www/yarn.lock @@ -1302,6 +1302,15 @@ __metadata: languageName: node linkType: hard +"@medusajs/icons@npm:^1.2.2": + version: 1.2.2 + resolution: "@medusajs/icons@npm:1.2.2" + peerDependencies: + react: ^16.x || ^17.x || ^18.x + checksum: 610117b959ddbd68f927caa12e70fb5fc849e8c68a25ca38f4d137aca1363f36552455aa83669847bd42753cccf36ad57b82f9bd5be7794e5b23af1046f78967 + languageName: node + linkType: hard + "@medusajs/icons@npm:preview": version: 1.2.2-preview-20240812060602 resolution: "@medusajs/icons@npm:1.2.2-preview-20240812060602" @@ -7274,6 +7283,7 @@ __metadata: react-transition-group: ^4.4.5 react-uuid: ^2.0.0 rimraf: ^5.0.1 + slugify: ^1.6.6 tailwind: "*" tailwindcss: ^3.3.3 tsc-alias: ^1.8.7 @@ -14692,6 +14702,7 @@ turbo@latest: version: 0.0.0-use.local resolution: "types@workspace:packages/types" dependencies: + "@medusajs/icons": ^1.2.2 "@types/node": ^20.11.20 eslint-config-docs: "*" rimraf: ^5.0.5 @@ -14790,6 +14801,7 @@ turbo@latest: react-day-picker: ^8.10.0 react-docgen: ^7.0.1 react-dom: 18.2.0 + rehype-slug: ^6.0.0 remark: ^14.0.3 tailwind: "*" tailwindcss: 3.3.3