docs: support multiple sidebars in a project (#11768)

* changed to new sidebar across projects except resources

* finalize multi sidebar support

* clean up

* remove redundant property

* small changes

* fixes

* generate

* fix error

* fix initial open
This commit is contained in:
Shahed Nasser authored and GitHub committed 2025-03-07 15:47:38 +02:00
1 parent 2a0bd86204
commit 5deb8eaf50
108 files changed
+10303 -9418

No files matched your search

-3
View File
@@ -58,9 +58,6 @@ export default function RootLayout({
gaId={process.env.NEXT_PUBLIC_GA_ID} gaId={process.env.NEXT_PUBLIC_GA_ID}
> >
<WideLayout <WideLayout
sidebarProps={{
expandItems: false,
}}
showToc={false} showToc={false}
showBreadcrumbs={false} showBreadcrumbs={false}
ProvidersComponent={Providers} ProvidersComponent={Providers}
@@ -3,13 +3,13 @@
import { useScrollController, useSidebar, H2 as UiH2 } from "docs-ui" import { useScrollController, useSidebar, H2 as UiH2 } from "docs-ui"
import { useEffect, useMemo, useRef, useState } from "react" import { useEffect, useMemo, useRef, useState } from "react"
import getSectionId from "../../../utils/get-section-id" import getSectionId from "../../../utils/get-section-id"
import { SidebarItem } from "types" import { Sidebar } from "types"
type H2Props = React.HTMLAttributes<HTMLHeadingElement> type H2Props = React.HTMLAttributes<HTMLHeadingElement>
const H2 = ({ children, ...props }: H2Props) => { const H2 = ({ children, ...props }: H2Props) => {
const headingRef = useRef<HTMLHeadingElement>(null) const headingRef = useRef<HTMLHeadingElement>(null)
const { activePath, addItems, removeItems } = useSidebar() const { activePath, addItems, removeItems, shownSidebar } = useSidebar()
const { scrollableElement, scrollToElement } = useScrollController() const { scrollableElement, scrollToElement } = useScrollController()
const [scrolledFirstTime, setScrolledFirstTime] = useState(false) const [scrolledFirstTime, setScrolledFirstTime] = useState(false)
@@ -29,7 +29,10 @@ const H2 = ({ children, ...props }: H2Props) => {
}, [scrollableElement, headingRef, id]) }, [scrollableElement, headingRef, id])
useEffect(() => { useEffect(() => {
const item: SidebarItem[] = [ if (!shownSidebar) {
return
}
const items: Sidebar.SidebarItem[] = [
{ {
type: "link", type: "link",
path: `${id}`, path: `${id}`,
@@ -37,12 +40,17 @@ const H2 = ({ children, ...props }: H2Props) => {
loaded: true, loaded: true,
}, },
] ]
addItems(item) addItems(items, {
sidebar_id: shownSidebar.sidebar_id,
})
return () => { return () => {
removeItems(item) removeItems({
items,
sidebar_id: shownSidebar.sidebar_id,
})
} }
}, [id]) }, [id, shownSidebar?.sidebar_id])
return ( return (
<UiH2 {...props} id={id} passRef={headingRef}> <UiH2 {...props} id={id} passRef={headingRef}>
@@ -60,11 +60,12 @@ const TagOperation = ({
}, [isBrowser, scrollableElement]) }, [isBrowser, scrollableElement])
const scrollIntoView = useCallback(() => { const scrollIntoView = useCallback(() => {
if (!isBrowser) { if (!isBrowser || !nodeRef.current) {
// repeat timeout
setTimeout(scrollIntoView, 200)
return return
} }
if (!checkElementInViewport(nodeRef.current, 0)) {
if (nodeRef.current && !checkElementInViewport(nodeRef.current, 0)) {
const elm = nodeRef.current as HTMLElement const elm = nodeRef.current as HTMLElement
scrollToTop( scrollToTop(
elm.offsetTop + (elm.offsetParent as HTMLElement)?.offsetTop, elm.offsetTop + (elm.offsetParent as HTMLElement)?.offsetTop,
@@ -1,8 +1,7 @@
"use client" "use client"
import type { OpenAPIV3 } from "openapi-types" import type { Operation, PathsObject, TagObject } from "@/types/openapi"
import type { Operation, PathsObject } from "@/types/openapi" import { findSidebarItem, useSidebar } from "docs-ui"
import { useSidebar } from "docs-ui"
import { Fragment, Suspense, useEffect } from "react" import { Fragment, Suspense, useEffect } from "react"
import dynamic from "next/dynamic" import dynamic from "next/dynamic"
import type { TagOperationProps } from "../Operation" import type { TagOperationProps } from "../Operation"
@@ -10,32 +9,41 @@ import clsx from "clsx"
import getTagChildSidebarItems from "@/utils/get-tag-child-sidebar-items" import getTagChildSidebarItems from "@/utils/get-tag-child-sidebar-items"
import { useLoading } from "@/providers/loading" import { useLoading } from "@/providers/loading"
import DividedLoading from "@/components/DividedLoading" import DividedLoading from "@/components/DividedLoading"
import { SidebarItemSections, SidebarItem, SidebarItemCategory } from "types" import { Sidebar } from "types"
const TagOperation = dynamic<TagOperationProps>( const TagOperation = dynamic<TagOperationProps>(
async () => import("../Operation") async () => import("../Operation")
) as React.FC<TagOperationProps> ) as React.FC<TagOperationProps>
export type TagPathsProps = { export type TagPathsProps = {
tag: OpenAPIV3.TagObject tag: TagObject
paths: PathsObject paths: PathsObject
} & React.HTMLAttributes<HTMLDivElement> } & React.HTMLAttributes<HTMLDivElement>
const TagPaths = ({ tag, className, paths }: TagPathsProps) => { const TagPaths = ({ tag, className, paths }: TagPathsProps) => {
const { items, addItems, findItemInSection } = useSidebar() const { shownSidebar, addItems } = useSidebar()
const { loading } = useLoading() const { loading } = useLoading()
useEffect(() => { useEffect(() => {
if (!shownSidebar) {
return
}
if (paths) { if (paths) {
const parentItem = findItemInSection( const parentItem = findSidebarItem({
items[SidebarItemSections.DEFAULT], sidebarItems:
{ title: tag.name }, "items" in shownSidebar
false ? shownSidebar.items
) as SidebarItemCategory : shownSidebar.children || [],
const pathItems: SidebarItem[] = getTagChildSidebarItems(paths) item: { title: tag.name, type: "category" },
if ((parentItem?.children?.length || 0) < pathItems.length) { checkChildren: false,
}) as Sidebar.SidebarItemCategory
const pathItems: Sidebar.SidebarItem[] = getTagChildSidebarItems(paths)
const targetLength =
pathItems.length + (tag["x-associatedSchema"] ? 1 : 0)
if ((parentItem.children?.length || 0) < targetLength) {
addItems(pathItems, { addItems(pathItems, {
section: SidebarItemSections.DEFAULT, sidebar_id: shownSidebar.sidebar_id,
parent: { parent: {
type: "category", type: "category",
title: tag.name, title: tag.name,
@@ -46,7 +54,7 @@ const TagPaths = ({ tag, className, paths }: TagPathsProps) => {
} }
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [paths]) }, [paths, shownSidebar?.sidebar_id])
return ( return (
<Suspense> <Suspense>
@@ -1,6 +1,6 @@
"use client" "use client"
import { Suspense, useEffect, useMemo, useRef } from "react" import { Suspense, useEffect, useMemo } from "react"
import { SchemaObject } from "../../../../types/openapi" import { SchemaObject } from "../../../../types/openapi"
import TagOperationParameters from "../../Operation/Parameters" import TagOperationParameters from "../../Operation/Parameters"
import { import {
@@ -13,7 +13,6 @@ import {
useScrollController, useScrollController,
useSidebar, useSidebar,
} from "docs-ui" } from "docs-ui"
import { SidebarItemSections } from "types"
import getSectionId from "../../../../utils/get-section-id" import getSectionId from "../../../../utils/get-section-id"
import DividedLayout from "../../../../layouts/Divided" import DividedLayout from "../../../../layouts/Divided"
import SectionContainer from "../../../Section/Container" import SectionContainer from "../../../Section/Container"
@@ -30,7 +29,7 @@ export type TagSectionSchemaProps = {
} }
const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => { const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
const { addItems, setActivePath, activePath } = useSidebar() const { addItems, setActivePath, activePath, shownSidebar } = useSidebar()
const { displayedArea } = useArea() const { displayedArea } = useArea()
const formattedName = useMemo( const formattedName = useMemo(
() => singular(tagName).replaceAll(" ", ""), () => singular(tagName).replaceAll(" ", ""),
@@ -58,6 +57,9 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
}, [isBrowser, scrollableElement]) }, [isBrowser, scrollableElement])
useEffect(() => { useEffect(() => {
if (!shownSidebar) {
return
}
addItems( addItems(
[ [
{ {
@@ -69,7 +71,7 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
}, },
], ],
{ {
section: SidebarItemSections.DEFAULT, sidebar_id: shownSidebar.sidebar_id,
parent: { parent: {
type: "category", type: "category",
title: tagName, title: tagName,
@@ -80,7 +82,7 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
} }
) )
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [formattedName]) }, [formattedName, shownSidebar?.sidebar_id])
useEffect(() => { useEffect(() => {
if (!isBrowser) { if (!isBrowser) {
@@ -85,13 +85,15 @@ const TagSectionComponent = ({ tag }: TagSectionProps) => {
) )
useEffect(() => { useEffect(() => {
if (!isBrowser) { if (!isBrowser || !activePath || !activePath.includes(slugTagName)) {
return return
} }
if (activePath && activePath.includes(slugTagName)) {
const tagName = activePath.split("_") const tagName = activePath.split("_")
if (tagName.length === 1 && tagName[0] === slugTagName) { if (tagName[0] !== slugTagName) {
return
}
if (tagName.length === 1) {
const elm = document.getElementById(tagName[0]) const elm = document.getElementById(tagName[0])
if (elm && !checkElementInViewport(elm, 0)) { if (elm && !checkElementInViewport(elm, 0)) {
scrollToTop( scrollToTop(
@@ -99,10 +101,9 @@ const TagSectionComponent = ({ tag }: TagSectionProps) => {
0 0
) )
} }
} else if (tagName.length > 1 && tagName[0] === slugTagName) { } else if (tagName.length > 1) {
setLoadData(true) setLoadData(true)
} }
}
}, [slugTagName, activePath, isBrowser]) }, [slugTagName, activePath, isBrowser])
return ( return (
+6 -3
View File
@@ -8,8 +8,11 @@ export const config: DocsConfig = {
baseUrl, baseUrl,
basePath: process.env.NEXT_PUBLIC_BASE_PATH, basePath: process.env.NEXT_PUBLIC_BASE_PATH,
// sidebar is auto generated // sidebar is auto generated
sidebar: { sidebars: [
default: [ {
sidebar_id: "api-ref",
title: "API Reference",
items: [
{ {
type: "link", type: "link",
title: "Introduction", title: "Introduction",
@@ -17,8 +20,8 @@ export const config: DocsConfig = {
loaded: true, loaded: true,
}, },
], ],
mobile: [],
}, },
],
project: { project: {
title: "API Reference", title: "API Reference",
key: "api-reference", key: "api-reference",
@@ -2,7 +2,7 @@
import { ExpandedDocument, SecuritySchemeObject } from "@/types/openapi" import { ExpandedDocument, SecuritySchemeObject } from "@/types/openapi"
import { ReactNode, createContext, useContext, useEffect, useMemo } from "react" import { ReactNode, createContext, useContext, useEffect, useMemo } from "react"
import { SidebarItem, SidebarItemSections } from "types" import { Sidebar } from "types"
import getSectionId from "../utils/get-section-id" import getSectionId from "../utils/get-section-id"
import getTagChildSidebarItems from "../utils/get-tag-child-sidebar-items" import getTagChildSidebarItems from "../utils/get-tag-child-sidebar-items"
import { useRouter } from "next/navigation" import { useRouter } from "next/navigation"
@@ -22,7 +22,8 @@ type BaseSpecsProviderProps = {
const BaseSpecsProvider = ({ children, baseSpecs }: BaseSpecsProviderProps) => { const BaseSpecsProvider = ({ children, baseSpecs }: BaseSpecsProviderProps) => {
const router = useRouter() const router = useRouter()
const { activePath, addItems, setActivePath, resetItems } = useSidebar() const { activePath, addItems, setActivePath, resetItems, shownSidebar } =
useSidebar()
const getSecuritySchema = ( const getSecuritySchema = (
securityName: string securityName: string
@@ -48,7 +49,7 @@ const BaseSpecsProvider = ({ children, baseSpecs }: BaseSpecsProviderProps) => {
return [] return []
} }
const itemsToAdd: SidebarItem[] = [ const itemsToAdd: Sidebar.SidebarItem[] = [
{ {
type: "separator", type: "separator",
}, },
@@ -67,6 +68,7 @@ const BaseSpecsProvider = ({ children, baseSpecs }: BaseSpecsProviderProps) => {
children: childItems, children: childItems,
loaded: childItems.length > 0, loaded: childItems.length > 0,
showLoadingIfEmpty: true, showLoadingIfEmpty: true,
initialOpen: false,
onOpen: () => { onOpen: () => {
if (location.hash !== tagPathName) { if (location.hash !== tagPathName) {
router.push(`#${tagPathName}`, { router.push(`#${tagPathName}`, {
@@ -84,14 +86,14 @@ const BaseSpecsProvider = ({ children, baseSpecs }: BaseSpecsProviderProps) => {
}, [baseSpecs]) }, [baseSpecs])
useEffect(() => { useEffect(() => {
if (!itemsToAdd.length) { if (!itemsToAdd.length || !shownSidebar) {
return return
} }
addItems(itemsToAdd, { addItems(itemsToAdd, {
section: SidebarItemSections.DEFAULT, sidebar_id: shownSidebar.sidebar_id,
}) })
}, [itemsToAdd]) }, [itemsToAdd, shownSidebar?.sidebar_id])
useEffect(() => { useEffect(() => {
return () => { return () => {
@@ -3,7 +3,7 @@
import { createContext, useEffect } from "react" import { createContext, useEffect } from "react"
import { useSidebar } from "docs-ui" import { useSidebar } from "docs-ui"
import { useArea } from "./area" import { useArea } from "./area"
import { SidebarItemLink } from "types" import { Sidebar } from "types"
const PageTitleContext = createContext(null) const PageTitleContext = createContext(null)
@@ -27,7 +27,7 @@ const PageTitleProvider = ({ children }: PageTitleProviderProps) => {
// find the child that matches the active path // find the child that matches the active path
const item = activeItem?.children?.find( const item = activeItem?.children?.find(
(i) => i.type === "link" && i.path === activePath (i) => i.type === "link" && i.path === activePath
) as SidebarItemLink ) as Sidebar.SidebarItemLink
if (item) { if (item) {
document.title = `${item.title} - ${titleSuffix}` document.title = `${item.title} - ${titleSuffix}`
} }
+5 -3
View File
@@ -20,10 +20,12 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
isLoading={isLoading} isLoading={isLoading}
setIsLoading={setIsLoading} setIsLoading={setIsLoading}
shouldHandleHashChange={true} shouldHandleHashChange={true}
shouldHandlePathChange={false}
scrollableElement={scrollableElement} scrollableElement={scrollableElement}
initialItems={config.sidebar} sidebars={config.sidebars}
persistState={false} persistCategoryState={false}
projectName="api" disableActiveTransition={false}
isSidebarStatic={false}
> >
{children} {children}
</UiSidebarProvider> </UiSidebarProvider>
@@ -1,9 +1,9 @@
import type { SidebarItem } from "types"
import type { Operation, PathsObject } from "@/types/openapi" import type { Operation, PathsObject } from "@/types/openapi"
import type { OpenAPIV3 } from "openapi-types" import type { OpenAPIV3 } from "openapi-types"
import dynamic from "next/dynamic" import dynamic from "next/dynamic"
import type { MethodLabelProps } from "@/components/MethodLabel" import type { MethodLabelProps } from "@/components/MethodLabel"
import getSectionId from "./get-section-id" import getSectionId from "./get-section-id"
import { Sidebar } from "types"
const MethodLabel = dynamic<MethodLabelProps>( const MethodLabel = dynamic<MethodLabelProps>(
async () => import("../components/MethodLabel") async () => import("../components/MethodLabel")
@@ -11,8 +11,8 @@ const MethodLabel = dynamic<MethodLabelProps>(
export default function getTagChildSidebarItems( export default function getTagChildSidebarItems(
paths: PathsObject paths: PathsObject
): SidebarItem[] { ): Sidebar.SidebarItem[] {
const items: SidebarItem[] = [] const items: Sidebar.SidebarItem[] = []
Object.entries(paths).forEach(([, operations]) => { Object.entries(paths).forEach(([, operations]) => {
Object.entries(operations).map(([method, operation]) => { Object.entries(operations).map(([method, operation]) => {
const definedOperation = operation as Operation const definedOperation = operation as Operation
+1 -7
View File
@@ -8,13 +8,7 @@ export default function RootLayout({
children: React.ReactNode children: React.ReactNode
}) { }) {
return ( return (
<TightLayout <TightLayout ProvidersComponent={Providers} footerComponent={<Footer />}>
sidebarProps={{
expandItems: true,
}}
ProvidersComponent={Providers}
footerComponent={<Footer />}
>
{children} {children}
</TightLayout> </TightLayout>
) )
+1 -7
View File
@@ -6,13 +6,7 @@ import Footer from "../components/Footer"
const NotFoundPage = () => { const NotFoundPage = () => {
return ( return (
<TightLayout <TightLayout footerComponent={<Footer />} ProvidersComponent={Providers}>
sidebarProps={{
expandItems: true,
}}
footerComponent={<Footer />}
ProvidersComponent={Providers}
>
{/* @ts-ignore React v19 doesn't recognize MDX import as component */} {/* @ts-ignore React v19 doesn't recognize MDX import as component */}
<NotFoundContent /> <NotFoundContent />
</TightLayout> </TightLayout>
+11 -3
View File
@@ -1,6 +1,6 @@
import { DocsConfig } from "types" import { DocsConfig, Sidebar } from "types"
import { sidebarConfig } from "./sidebar"
import { globalConfig } from "docs-ui" import { globalConfig } from "docs-ui"
import { generatedSidebars } from "../generated/sidebar.mjs"
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000"
@@ -9,10 +9,18 @@ export const config: DocsConfig = {
titleSuffix: "Medusa v2 Documentation", titleSuffix: "Medusa v2 Documentation",
baseUrl, baseUrl,
basePath: process.env.NEXT_PUBLIC_BASE_PATH, basePath: process.env.NEXT_PUBLIC_BASE_PATH,
sidebar: sidebarConfig, sidebars: generatedSidebars as Sidebar.Sidebar[],
project: { project: {
title: "Documentation", title: "Documentation",
key: "book", key: "book",
}, },
logo: `${process.env.NEXT_PUBLIC_BASE_PATH}/images/logo.png`, logo: `${process.env.NEXT_PUBLIC_BASE_PATH}/images/logo.png`,
breadcrumbOptions: {
startItems: [
{
title: "Documentation",
link: "/",
},
],
},
} }
-8
View File
@@ -1,8 +0,0 @@
import type { SidebarConfig } from "@/types"
import { generatedSidebar } from "../generated/sidebar.mjs"
import { SidebarItem } from "types"
export const sidebarConfig: SidebarConfig = {
default: generatedSidebar as SidebarItem[],
mobile: [],
}
+22 -8
View File
@@ -1,7 +1,12 @@
export const generatedSidebar = [ export const generatedSidebars = [
{
"sidebar_id": "docs",
"title": "Get Started",
"items": [
{ {
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"initialOpen": false,
"type": "category", "type": "category",
"title": "1. Get Started", "title": "1. Get Started",
"children": [ "children": [
@@ -42,6 +47,7 @@ export const generatedSidebar = [
{ {
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"initialOpen": false,
"type": "category", "type": "category",
"title": "2. Customization Tutorial", "title": "2. Customization Tutorial",
"children": [ "children": [
@@ -226,6 +232,7 @@ export const generatedSidebar = [
{ {
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"initialOpen": false,
"type": "category", "type": "category",
"title": "3. Framework", "title": "3. Framework",
"children": [ "children": [
@@ -905,6 +912,7 @@ export const generatedSidebar = [
{ {
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"initialOpen": false,
"type": "category", "type": "category",
"title": "4. Admin Development", "title": "4. Admin Development",
"children": [ "children": [
@@ -983,6 +991,8 @@ export const generatedSidebar = [
"number": "4." "number": "4."
}, },
{ {
"loaded": true,
"isPathHref": true,
"type": "category", "type": "category",
"title": "5. Storefront", "title": "5. Storefront",
"children": [ "children": [
@@ -994,16 +1004,15 @@ export const generatedSidebar = [
"title": "Storefront Development", "title": "Storefront Development",
"chapterTitle": "5. Storefront", "chapterTitle": "5. Storefront",
"children": [], "children": [],
"childrenSameLevel": true,
"number": "5." "number": "5."
} }
], ],
"loaded": true,
"initialOpen": false "initialOpen": false
}, },
{ {
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"initialOpen": false,
"type": "category", "type": "category",
"title": "6. Configurations", "title": "6. Configurations",
"children": [ "children": [
@@ -1034,6 +1043,7 @@ export const generatedSidebar = [
{ {
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"initialOpen": false,
"type": "category", "type": "category",
"title": "7. Debugging & Testing", "title": "7. Debugging & Testing",
"children": [ "children": [
@@ -1124,6 +1134,8 @@ export const generatedSidebar = [
"number": "7." "number": "7."
}, },
{ {
"loaded": true,
"isPathHref": true,
"type": "category", "type": "category",
"title": "8. Production", "title": "8. Production",
"children": [ "children": [
@@ -1156,16 +1168,15 @@ export const generatedSidebar = [
"number": "8.2." "number": "8.2."
} }
], ],
"childrenSameLevel": true,
"number": "8." "number": "8."
} }
], ],
"loaded": true,
"initialOpen": false "initialOpen": false
}, },
{ {
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"initialOpen": false,
"type": "category", "type": "category",
"title": "9. Upgrade", "title": "9. Upgrade",
"children": [ "children": [
@@ -1196,6 +1207,7 @@ export const generatedSidebar = [
{ {
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"initialOpen": false,
"type": "category", "type": "category",
"title": "10. Resources", "title": "10. Resources",
"children": [ "children": [
@@ -1209,7 +1221,7 @@ export const generatedSidebar = [
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"type": "link", "type": "link",
"path": "/resources/contribution-guidelines/docs", "path": "/learn/resources/contribution-guidelines/docs",
"title": "Docs", "title": "Docs",
"children": [], "children": [],
"chapterTitle": "10.1.1. Docs", "chapterTitle": "10.1.1. Docs",
@@ -1219,7 +1231,7 @@ export const generatedSidebar = [
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"type": "link", "type": "link",
"path": "/resources//contribution-guidelines/admin-translations", "path": "/learn/resources//contribution-guidelines/admin-translations",
"title": "Admin Translations", "title": "Admin Translations",
"children": [], "children": [],
"chapterTitle": "10.1.2. Admin Translations", "chapterTitle": "10.1.2. Admin Translations",
@@ -1233,7 +1245,7 @@ export const generatedSidebar = [
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
"type": "link", "type": "link",
"path": "/resources/usage", "path": "/learn/resources/usage",
"title": "Usage", "title": "Usage",
"children": [], "children": [],
"chapterTitle": "10.2. Usage", "chapterTitle": "10.2. Usage",
@@ -1244,3 +1256,5 @@ export const generatedSidebar = [
"number": "10." "number": "10."
} }
] ]
}
]
+2 -2
View File
@@ -10,7 +10,7 @@ import {
} from "remark-rehype-plugins" } from "remark-rehype-plugins"
import path from "path" import path from "path"
import redirects from "./utils/redirects.mjs" import redirects from "./utils/redirects.mjs"
import { generatedSidebar } from "./generated/sidebar.mjs" import { generatedSidebars } from "./generated/sidebar.mjs"
const withMDX = mdx({ const withMDX = mdx({
extension: /\.mdx?$/, extension: /\.mdx?$/,
@@ -82,7 +82,7 @@ const withMDX = mdx({
[ [
pageNumberRehypePlugin, pageNumberRehypePlugin,
{ {
sidebar: generatedSidebar, sidebar: generatedSidebars[0].items,
}, },
], ],
], ],
+1 -6
View File
@@ -15,13 +15,8 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
return ( return (
<UiSidebarProvider <UiSidebarProvider
shouldHandlePathChange={true}
shouldHandleHashChange={false}
scrollableElement={scrollableElement} scrollableElement={scrollableElement}
initialItems={config.sidebar} sidebars={config.sidebars}
staticSidebarItems={true}
disableActiveTransition={true}
projectName="docs"
> >
{children} {children}
</UiSidebarProvider> </UiSidebarProvider>
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -1,6 +1,6 @@
import "dotenv/config" import "dotenv/config"
import path from "path" import path from "path"
import { sidebar } from "../sidebar.mjs" import { sidebars } from "../sidebar.mjs"
import { import {
generateEditedDates, generateEditedDates,
generateLlmsFull, generateLlmsFull,
@@ -15,7 +15,7 @@ import {
async function main() { async function main() {
await generateEditedDates() await generateEditedDates()
await generateSidebar(sidebar, { await generateSidebar(sidebars, {
addNumbering: true, addNumbering: true,
}) })
const baseUrl = const baseUrl =
+12 -8
View File
@@ -1,7 +1,9 @@
import { sidebarAttachHrefCommonOptions } from "./utils/sidebar-attach-common-options.mjs" /** @type {import("types").Sidebar.Sidebar[]} */
export const sidebars = [
/** @type {import('@/types').SidebarItem[]} */ {
export const sidebar = sidebarAttachHrefCommonOptions([ sidebar_id: "docs",
title: "Get Started",
items: [
{ {
type: "category", type: "category",
title: "Get Started", title: "Get Started",
@@ -633,21 +635,23 @@ export const sidebar = sidebarAttachHrefCommonOptions([
children: [ children: [
{ {
type: "link", type: "link",
path: "/resources/contribution-guidelines/docs", path: "/learn/resources/contribution-guidelines/docs",
title: "Docs", title: "Docs",
}, },
{ {
type: "link", type: "link",
path: "/resources//contribution-guidelines/admin-translations", path: "/learn/resources//contribution-guidelines/admin-translations",
title: "Admin Translations", title: "Admin Translations",
}, },
], ],
}, },
{ {
type: "link", type: "link",
path: "/resources/usage", path: "/learn/resources/usage",
title: "Usage", title: "Usage",
}, },
], ],
}, },
]) ],
},
]
-8
View File
@@ -1,8 +0,0 @@
import { SidebarSectionItems, SidebarItem as SidebarItemType } from "types"
export declare type SidebarItem = SidebarItemType & {
isSoon: boolean
number?: string
}
export declare type SidebarConfig = SidebarSectionItems
@@ -1,31 +0,0 @@
/** @type {Partial<import("@/types").SidebarItem[]>} */
const commonOptions = {
loaded: true,
isPathHref: true,
}
/**
*
* @param {import("@/types").SidebarItem[]} sidebar
* @param {boolean} nested
* @returns {import("@/types").SidebarItem[]}
*/
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
})
}
@@ -16,7 +16,7 @@ Refer to the [Medusa UI documentation](!ui!) for a full list of components.
Use these components to set the layout of your UI route. Use these components to set the layout of your UI route.
<ChildDocs showItems={["Layouts"]} onlyTopLevel={false} /> <ChildDocs showItems={["Layouts"]} onlyTopLevel={false} hideTitle />
--- ---
@@ -24,4 +24,4 @@ Use these components to set the layout of your UI route.
Use these components in your widgets and UI routes. Use these components in your widgets and UI routes.
<ChildDocs showItems={["Components"]} onlyTopLevel={false} /> <ChildDocs showItems={["Components"]} onlyTopLevel={false} hideTitle />
Whitespace-only changes.
+1 -7
View File
@@ -63,13 +63,7 @@ export default function RootLayout({
htmlClassName={clsx(inter.variable, robotoMono.variable)} htmlClassName={clsx(inter.variable, robotoMono.variable)}
gaId={process.env.NEXT_PUBLIC_GA_ID} gaId={process.env.NEXT_PUBLIC_GA_ID}
> >
<TightLayout <TightLayout ProvidersComponent={Providers} footerComponent={<Footer />}>
sidebarProps={{
expandItems: true,
}}
ProvidersComponent={Providers}
footerComponent={<Footer />}
>
{children} {children}
</TightLayout> </TightLayout>
</BareboneLayout> </BareboneLayout>
+1 -1
View File
@@ -8,4 +8,4 @@ export const metadata = {
This section of the documentation provides recipes for common use cases with example implementations. This section of the documentation provides recipes for common use cases with example implementations.
<ChildDocs onlyTopLevel /> <ChildDocs onlyTopLevel hideItems={["Overview"]} />
@@ -20,4 +20,4 @@ You can build your storefront from scratch, or built it on top of the [Next.js S
--- ---
<ChildDocs hideItems={["General"]} /> <ChildDocs hideItems={["General", "Overview"]} />
@@ -12,4 +12,4 @@ The following troubleshooting guides are intended for technical users. If you're
</Note> </Note>
<ChildDocs /> <ChildDocs hideItems={["Overview"]} />
@@ -12,7 +12,7 @@ export const CommerceModuleSections = () => {
showItems: ["Server Guides"], showItems: ["Server Guides"],
defaultItemsPerRow: 2, defaultItemsPerRow: 2,
}) })
if (serverGuideItems?.default.length) { if (serverGuideItems?.length) {
guideComponents.push(serverGuidesComponent) guideComponents.push(serverGuidesComponent)
} }
const { items: storefrontGuideItems, component: storefrontGuidesComponent } = const { items: storefrontGuideItems, component: storefrontGuidesComponent } =
@@ -20,7 +20,7 @@ export const CommerceModuleSections = () => {
showItems: ["Storefront Guides"], showItems: ["Storefront Guides"],
defaultItemsPerRow: 2, defaultItemsPerRow: 2,
}) })
if (storefrontGuideItems?.default.length) { if (storefrontGuideItems?.length) {
guideComponents.push(storefrontGuidesComponent) guideComponents.push(storefrontGuidesComponent)
} }
const { items: adminGuideItems, component: adminGuidesComponent } = const { items: adminGuideItems, component: adminGuidesComponent } =
@@ -28,7 +28,7 @@ export const CommerceModuleSections = () => {
showItems: ["Admin Guides"], showItems: ["Admin Guides"],
defaultItemsPerRow: 2, defaultItemsPerRow: 2,
}) })
if (adminGuideItems?.default.length) { if (adminGuideItems?.length) {
guideComponents.push(adminGuidesComponent) guideComponents.push(adminGuidesComponent)
} }
const { items: userGuideItems, component: userGuidesComponent } = const { items: userGuideItems, component: userGuidesComponent } =
@@ -36,14 +36,14 @@ export const CommerceModuleSections = () => {
showItems: ["User Guides"], showItems: ["User Guides"],
defaultItemsPerRow: 2, defaultItemsPerRow: 2,
}) })
if (userGuideItems?.default.length) { if (userGuideItems?.length) {
guideComponents.push(userGuidesComponent) guideComponents.push(userGuidesComponent)
} }
const { items: jsSdkItems, component: jsSdkComponent } = useChildDocs({ const { items: jsSdkItems, component: jsSdkComponent } = useChildDocs({
showItems: ["JS SDK"], showItems: ["JS SDK"],
itemsPerRow: 2, itemsPerRow: 2,
}) })
if (jsSdkItems?.default.length) { if (jsSdkItems?.length) {
referenceComponents.push(jsSdkComponent) referenceComponents.push(jsSdkComponent)
} }
const { items: referenceItems, component: referencesComponent } = const { items: referenceItems, component: referencesComponent } =
@@ -51,7 +51,7 @@ export const CommerceModuleSections = () => {
showItems: ["References"], showItems: ["References"],
defaultItemsPerRow: 2, defaultItemsPerRow: 2,
}) })
if (referenceItems?.default.length) { if (referenceItems?.length) {
referenceComponents.push(referencesComponent) referenceComponents.push(referencesComponent)
} }
+9 -7
View File
@@ -1,5 +1,5 @@
import { DocsConfig, SidebarItem } from "types" import { DocsConfig, Sidebar } from "types"
import { generatedSidebar } from "../generated/sidebar.mjs" import { generatedSidebars } from "../generated/sidebar.mjs"
import { globalConfig } from "docs-ui" import { globalConfig } from "docs-ui"
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000"
@@ -9,16 +9,18 @@ export const config: DocsConfig = {
titleSuffix: "Medusa Development Resources", titleSuffix: "Medusa Development Resources",
baseUrl, baseUrl,
basePath: process.env.NEXT_PUBLIC_BASE_PATH, basePath: process.env.NEXT_PUBLIC_BASE_PATH,
sidebar: { sidebars: generatedSidebars as Sidebar.Sidebar[],
default: generatedSidebar as SidebarItem[],
mobile: [],
},
project: { project: {
title: "Development Resources", title: "Development Resources",
key: "resources", key: "resources",
}, },
breadcrumbOptions: { breadcrumbOptions: {
showCategories: true, startItems: [
{
title: "Documentation",
link: baseUrl,
},
],
}, },
logo: `${process.env.NEXT_PUBLIC_BASE_PATH}/images/logo.png`, logo: `${process.env.NEXT_PUBLIC_BASE_PATH}/images/logo.png`,
} }
+3 -3
View File
@@ -123,7 +123,7 @@ export const generatedEditDates = {
"app/recipes/pos/page.mdx": "2025-02-26T12:42:52.949Z", "app/recipes/pos/page.mdx": "2025-02-26T12:42:52.949Z",
"app/recipes/subscriptions/examples/standard/page.mdx": "2025-03-03T15:02:56.854Z", "app/recipes/subscriptions/examples/standard/page.mdx": "2025-03-03T15:02:56.854Z",
"app/recipes/subscriptions/page.mdx": "2025-02-26T12:31:49.933Z", "app/recipes/subscriptions/page.mdx": "2025-02-26T12:31:49.933Z",
"app/recipes/page.mdx": "2024-07-11T15:56:41+00:00", "app/recipes/page.mdx": "2025-03-07T07:48:28.203Z",
"app/service-factory-reference/methods/create/page.mdx": "2024-07-31T17:01:33+03:00", "app/service-factory-reference/methods/create/page.mdx": "2024-07-31T17:01:33+03:00",
"app/service-factory-reference/methods/delete/page.mdx": "2024-07-31T17:01:33+03:00", "app/service-factory-reference/methods/delete/page.mdx": "2024-07-31T17:01:33+03:00",
"app/service-factory-reference/methods/list/page.mdx": "2024-07-31T17:01:33+03:00", "app/service-factory-reference/methods/list/page.mdx": "2024-07-31T17:01:33+03:00",
@@ -177,7 +177,7 @@ export const generatedEditDates = {
"app/storefront-development/regions/store-retrieve-region/page.mdx": "2024-12-19T16:36:22.800Z", "app/storefront-development/regions/store-retrieve-region/page.mdx": "2024-12-19T16:36:22.800Z",
"app/storefront-development/regions/page.mdx": "2024-06-09T15:19:09+02:00", "app/storefront-development/regions/page.mdx": "2024-06-09T15:19:09+02:00",
"app/storefront-development/tips/page.mdx": "2024-12-19T16:36:32.938Z", "app/storefront-development/tips/page.mdx": "2024-12-19T16:36:32.938Z",
"app/storefront-development/page.mdx": "2024-12-10T09:23:20.666Z", "app/storefront-development/page.mdx": "2025-03-07T07:49:27.809Z",
"app/troubleshooting/cors-errors/page.mdx": "2024-05-03T17:36:38+03:00", "app/troubleshooting/cors-errors/page.mdx": "2024-05-03T17:36:38+03:00",
"app/troubleshooting/create-medusa-app-errors/page.mdx": "2024-07-11T10:29:13+03:00", "app/troubleshooting/create-medusa-app-errors/page.mdx": "2024-07-11T10:29:13+03:00",
"app/troubleshooting/database-errors/page.mdx": "2024-05-03T17:36:38+03:00", "app/troubleshooting/database-errors/page.mdx": "2024-05-03T17:36:38+03:00",
@@ -2101,7 +2101,7 @@ export const generatedEditDates = {
"app/admin-components/components/json-view-section/page.mdx": "2024-10-07T11:15:58.833Z", "app/admin-components/components/json-view-section/page.mdx": "2024-10-07T11:15:58.833Z",
"app/admin-components/components/section-row/page.mdx": "2024-10-07T11:15:58.832Z", "app/admin-components/components/section-row/page.mdx": "2024-10-07T11:15:58.832Z",
"app/admin-components/components/table/page.mdx": "2025-03-03T14:53:37.952Z", "app/admin-components/components/table/page.mdx": "2025-03-03T14:53:37.952Z",
"app/admin-components/page.mdx": "2024-10-07T11:09:49.493Z", "app/admin-components/page.mdx": "2025-03-07T08:00:46.960Z",
"app/admin-components/layouts/single-column/page.mdx": "2024-10-07T11:16:06.435Z", "app/admin-components/layouts/single-column/page.mdx": "2024-10-07T11:16:06.435Z",
"app/admin-components/layouts/two-column/page.mdx": "2024-10-07T11:16:10.092Z", "app/admin-components/layouts/two-column/page.mdx": "2024-10-07T11:16:10.092Z",
"app/admin-components/components/forms/page.mdx": "2024-10-09T12:48:04.229Z", "app/admin-components/components/forms/page.mdx": "2024-10-09T12:48:04.229Z",
@@ -787,6 +787,10 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/examples/guides/custom-item-price/page.mdx", "filePath": "/www/apps/resources/app/examples/guides/custom-item-price/page.mdx",
"pathname": "/examples/guides/custom-item-price" "pathname": "/examples/guides/custom-item-price"
}, },
{
"filePath": "/www/apps/resources/app/examples/guides/quote-management/page.mdx",
"pathname": "/examples/guides/quote-management"
},
{ {
"filePath": "/www/apps/resources/app/examples/page.mdx", "filePath": "/www/apps/resources/app/examples/page.mdx",
"pathname": "/examples" "pathname": "/examples"
File diff suppressed because it is too large. Load diff
+1 -6
View File
@@ -14,13 +14,8 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
return ( return (
<UiSidebarProvider <UiSidebarProvider
shouldHandlePathChange={true}
shouldHandleHashChange={false}
scrollableElement={scrollableElement} scrollableElement={scrollableElement}
initialItems={config.sidebar} sidebars={config.sidebars}
staticSidebarItems={true}
disableActiveTransition={true}
projectName="resources"
> >
{children} {children}
</UiSidebarProvider> </UiSidebarProvider>
+3 -3
View File
@@ -5,9 +5,9 @@ import { sidebar } from "../sidebar.mjs"
async function main() { async function main() {
await generateSidebar(sidebar) await generateSidebar(sidebar)
await generateSlugChanges() // await generateSlugChanges()
await generateFilesMap() // await generateFilesMap()
await generateEditedDates() // await generateEditedDates()
} }
void main() void main()
+34 -58
View File
@@ -24,24 +24,21 @@ import { storefrontGuidesSidebar } from "./sidebars/storefront.mjs"
import { taxSidebar } from "./sidebars/tax.mjs" import { taxSidebar } from "./sidebars/tax.mjs"
import { troubleshootingSidebar } from "./sidebars/troubleshooting.mjs" import { troubleshootingSidebar } from "./sidebars/troubleshooting.mjs"
import { userSidebar } from "./sidebars/user.mjs" import { userSidebar } from "./sidebars/user.mjs"
import { sidebarAttachHrefCommonOptions } from "./utils/sidebar-attach-common-options.mjs"
import { examplesSidebar } from "./sidebars/examples.mjs" import { examplesSidebar } from "./sidebars/examples.mjs"
/** @type {import('types').RawSidebarItem[]} */ /** @type {import("types").Sidebar.RawSidebar[]} */
export const sidebar = sidebarAttachHrefCommonOptions([ export const sidebar = [
{
sidebar_id: "resources",
title: "Development Resources",
items: [
{ {
type: "link", type: "link",
path: "/", path: "/",
title: "Overview", title: "Overview",
}, },
...examplesSidebar, ...examplesSidebar,
{ ...recipesSidebar,
type: "link",
path: "/recipes",
title: "Recipes",
isChildSidebar: true,
children: recipesSidebar,
},
{ {
type: "separator", type: "separator",
}, },
@@ -72,36 +69,10 @@ export const sidebar = sidebarAttachHrefCommonOptions([
...userSidebar, ...userSidebar,
], ],
}, },
{ ...architecturalModulesSidebar,
type: "link", ...integrationsSidebar,
path: "/architectural-modules", ...pluginsSidebar,
title: "Architectural Modules", ...storefrontGuidesSidebar,
isChildSidebar: true,
sort_sidebar: "alphabetize",
children: architecturalModulesSidebar,
},
{
type: "link",
path: "/integrations",
title: "Integrations",
isChildSidebar: true,
sort_sidebar: "alphabetize",
children: integrationsSidebar,
},
{
type: "ref",
path: "/plugins",
title: "Plugins",
isChildSidebar: true,
children: pluginsSidebar,
},
{
type: "link",
path: "/storefront-development",
title: "Storefront Development",
isChildSidebar: true,
children: storefrontGuidesSidebar,
},
{ {
type: "separator", type: "separator",
}, },
@@ -115,16 +86,18 @@ export const sidebar = sidebarAttachHrefCommonOptions([
title: "General", title: "General",
children: [ children: [
{ {
type: "link", type: "sidebar",
path: "/references/medusa-config", sidebar_id: "deployment-guides",
title: "Medusa Configurations", title: "Deployment Guides",
}, children: [
{ {
type: "link", type: "link",
path: "/deployment", path: "/deployment",
title: "Deployment Guides", title: "Overview",
isChildSidebar: true, },
children: [ {
type: "separator",
},
{ {
type: "link", type: "link",
title: "Medusa Cloud", title: "Medusa Cloud",
@@ -156,13 +129,7 @@ export const sidebar = sidebarAttachHrefCommonOptions([
}, },
], ],
}, },
{ ...troubleshootingSidebar,
type: "link",
path: "/troubleshooting",
title: "Troubleshooting Guides",
isChildSidebar: true,
children: troubleshootingSidebar,
},
], ],
}, },
{ {
@@ -174,12 +141,19 @@ export const sidebar = sidebarAttachHrefCommonOptions([
path: "/admin-widget-injection-zones", path: "/admin-widget-injection-zones",
title: "Admin Widget Injection Zones", title: "Admin Widget Injection Zones",
}, },
{
type: "sidebar",
sidebar_id: "admin-components",
title: "Admin Components",
children: [
{ {
type: "link", type: "link",
path: "/admin-components", path: "/admin-components",
title: "Admin Components", title: "Overview",
isChildSidebar: true, },
children: [ {
type: "separator",
},
{ {
type: "category", type: "category",
title: "Layouts", title: "Layouts",
@@ -215,4 +189,6 @@ export const sidebar = sidebarAttachHrefCommonOptions([
title: "References", title: "References",
children: referencesSidebar, children: referencesSidebar,
}, },
]) ],
},
]
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const apiKeySidebar = [ export const apiKeySidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "api-key",
title: "API Key Module", title: "API Key Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -131,12 +131,19 @@ export const apiKeySidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/api-key", sidebar_id: "api-key-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "API Key Module's Main Service Reference", childSidebarTitle: "API Key Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/api-key",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -147,12 +154,19 @@ export const apiKeySidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/api-key/models", sidebar_id: "api-key-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "API Key Module Data Models Reference", childSidebarTitle: "API Key Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/api-key/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
@@ -1,5 +1,18 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const architecturalModulesSidebar = [ export const architecturalModulesSidebar = [
{
type: "sidebar",
sidebar_id: "architectural-modules",
title: "Architectural Modules",
children: [
{
type: "link",
path: "/architectural-modules",
title: "Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Cache Modules", title: "Cache Modules",
@@ -159,4 +172,6 @@ export const architecturalModulesSidebar = [
}, },
], ],
}, },
],
},
] ]
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const authSidebar = [ export const authSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "auth",
title: "Auth Module", title: "Auth Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -173,12 +173,19 @@ export const authSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/auth", sidebar_id: "auth-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Auth Module's Main Service Reference", childSidebarTitle: "Auth Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/auth",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -188,12 +195,19 @@ export const authSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/auth/models", sidebar_id: "auth-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Auth Module Data Models Reference", childSidebarTitle: "Auth Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/auth/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const cartSidebar = [ export const cartSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "cart",
title: "Cart Module", title: "Cart Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -148,12 +148,19 @@ export const cartSidebar = [
title: "Events Reference", title: "Events Reference",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/cart", sidebar_id: "cart-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Cart Module's Main Service Reference", childSidebarTitle: "Cart Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/cart",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -163,12 +170,19 @@ export const cartSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/cart/models", sidebar_id: "cart-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Cart Module Data Models Reference", childSidebarTitle: "Cart Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/cart/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const currencySidebar = [ export const currencySidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "currency",
title: "Currency Module", title: "Currency Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -99,12 +99,19 @@ export const currencySidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/currency", sidebar_id: "currency-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Currency Module's Main Service Reference", childSidebarTitle: "Currency Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/currency",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -114,12 +121,19 @@ export const currencySidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/currency/models", sidebar_id: "currency-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Currency Module Data Models Reference", childSidebarTitle: "Currency Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/currency/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const customerSidebar = [ export const customerSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "customer",
title: "Customer Module", title: "Customer Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -143,12 +143,19 @@ export const customerSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/customer", sidebar_id: "customer-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Customer Module's Main Service Reference", childSidebarTitle: "Customer Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/customer",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -158,12 +165,19 @@ export const customerSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/customer/models", sidebar_id: "customer-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Customer Module Data Models Reference", childSidebarTitle: "Customer Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/customer/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+4 -12
View File
@@ -1,13 +1,12 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const examplesSidebar = [ export const examplesSidebar = [
{ {
type: "link", type: "sidebar",
path: "/examples", sidebar_id: "examples",
title: "Examples", title: "Examples",
isChildSidebar: true,
children: [ children: [
{ {
type: "ref", type: "link",
path: "/examples", path: "/examples",
title: "Example Snippets", title: "Example Snippets",
}, },
@@ -32,13 +31,6 @@ export const examplesSidebar = [
autogenerate_tags: "example+server", autogenerate_tags: "example+server",
autogenerate_as_ref: true, autogenerate_as_ref: true,
sort_sidebar: "alphabetize", sort_sidebar: "alphabetize",
children: [
{
type: "link",
title: "Custom Item Price",
path: "/examples/guides/custom-item-price",
},
],
}, },
{ {
type: "category", type: "category",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const fulfillmentSidebar = [ export const fulfillmentSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "fulfillment",
title: "Fulfillment Module", title: "Fulfillment Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -170,12 +170,19 @@ export const fulfillmentSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/fulfillment", sidebar_id: "fulfillment-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Fulfillment Module's Main Service Reference", childSidebarTitle: "Fulfillment Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/fulfillment",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -185,12 +192,19 @@ export const fulfillmentSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/fulfillment/models", sidebar_id: "fulfillment-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Fulfillment Module Data Models Reference", childSidebarTitle: "Fulfillment Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/fulfillment/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+16 -1
View File
@@ -1,5 +1,18 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const integrationsSidebar = [ export const integrationsSidebar = [
{
type: "sidebar",
sidebar_id: "integrations",
title: "Integrations",
children: [
{
type: "link",
path: "/integrations",
title: "Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Auth", title: "Auth",
@@ -76,4 +89,6 @@ export const integrationsSidebar = [
}, },
], ],
}, },
],
},
] ]
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const inventorySidebar = [ export const inventorySidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "inventory",
title: "Inventory Module", title: "Inventory Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -143,12 +143,19 @@ export const inventorySidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/inventory-next", sidebar_id: "inventory-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Inventory Module's Main Service Reference", childSidebarTitle: "Inventory Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/inventory-next",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -158,12 +165,19 @@ export const inventorySidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/inventory-next/models", sidebar_id: "inventory-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Inventory Module Data Models Reference", childSidebarTitle: "Inventory Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/inventory-next/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const orderSidebar = [ export const orderSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "order",
title: "Order Module", title: "Order Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -181,12 +181,19 @@ export const orderSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/order", sidebar_id: "order-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Order Module's Main Service Reference", childSidebarTitle: "Order Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/order",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -196,12 +203,19 @@ export const orderSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/order/models", sidebar_id: "order-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Order Module Data Models Reference", childSidebarTitle: "Order Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/order/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const paymentSidebar = [ export const paymentSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "payment",
title: "Payment Module", title: "Payment Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -185,12 +185,19 @@ export const paymentSidebar = [
title: "Events Reference", title: "Events Reference",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/payment", sidebar_id: "payment-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Payment Module's Main Service Reference", childSidebarTitle: "Payment Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/payment",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -200,12 +207,19 @@ export const paymentSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/payment/models", sidebar_id: "payment-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Payment Module Data Models Reference", childSidebarTitle: "Payment Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/payment/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+8 -1
View File
@@ -1,5 +1,10 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const pluginsSidebar = [ export const pluginsSidebar = [
{
type: "sidebar",
sidebar_id: "plugins",
title: "Plugins",
children: [
{ {
type: "link", type: "link",
title: "Overview", title: "Overview",
@@ -17,4 +22,6 @@ export const pluginsSidebar = [
}, },
], ],
}, },
],
},
] ]
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const pricingSidebar = [ export const pricingSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "pricing",
title: "Pricing Module", title: "Pricing Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -146,12 +146,19 @@ export const pricingSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/pricing", sidebar_id: "pricing-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Pricing Module's Main Service Reference", childSidebarTitle: "Pricing Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/pricing",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -161,12 +168,19 @@ export const pricingSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/pricing/models", sidebar_id: "pricing-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Pricing Module Data Models Reference", childSidebarTitle: "Pricing Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/pricing/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const productSidebar = [ export const productSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "product",
title: "Product Module", title: "Product Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -160,12 +160,19 @@ export const productSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/product", sidebar_id: "product-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Product Module's Main Service Reference", childSidebarTitle: "Product Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/product",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -175,12 +182,19 @@ export const productSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/product/models", sidebar_id: "product-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Product Module Data Models Reference", childSidebarTitle: "Product Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/product/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const promotionSidebar = [ export const promotionSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "promotion",
title: "Promotion Module", title: "Promotion Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -153,12 +153,19 @@ export const promotionSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/promotion", sidebar_id: "promotion-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Promotion Module's Main Service Reference", childSidebarTitle: "Promotion Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/promotion",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -169,12 +176,19 @@ export const promotionSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/promotion/models", sidebar_id: "promotion-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Promotion Module Data Models Reference", childSidebarTitle: "Promotion Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/promotion/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+16 -1
View File
@@ -1,5 +1,18 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const recipesSidebar = [ export const recipesSidebar = [
{
type: "sidebar",
sidebar_id: "recipes",
title: "Recipes",
children: [
{
type: "link",
path: "/recipes",
title: "Overview",
},
{
type: "separator",
},
{ {
type: "link", type: "link",
path: "/recipes/marketplace", path: "/recipes/marketplace",
@@ -100,4 +113,6 @@ export const recipesSidebar = [
path: "/recipes/pos", path: "/recipes/pos",
title: "POS", title: "POS",
}, },
],
},
] ]
+61 -21
View File
@@ -1,12 +1,19 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const referencesSidebar = [ export const referencesSidebar = [
{
type: "sidebar",
sidebar_id: "workflows-sdk-reference",
title: "Workflows SDK",
childSidebarTitle: "Workflows SDK Reference",
children: [
{ {
type: "link", type: "link",
path: "/references/workflows", path: "/references/workflows",
title: "Workflows SDK", title: "Reference Overview",
childSidebarTitle: "Workflows SDK Reference", },
isChildSidebar: true, {
children: [ type: "separator",
},
{ {
type: "category", type: "category",
title: "Functions", title: "Functions",
@@ -15,12 +22,19 @@ export const referencesSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/data-model", sidebar_id: "dml-reference",
title: "Data Model Language", title: "Data Model Language",
childSidebarTitle: "Data Model Language Reference", childSidebarTitle: "Data Model Language Reference",
isChildSidebar: true,
children: [ children: [
{
type: "link",
path: "/references/data-model",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "link", type: "link",
path: "/references/data-model/define", path: "/references/data-model/define",
@@ -52,12 +66,19 @@ export const referencesSidebar = [
}, },
], ],
}, },
{
type: "sidebar",
sidebar_id: "service-factory-reference",
title: "Service Factory",
children: [
{ {
type: "link", type: "link",
path: "/service-factory-reference", path: "/service-factory-reference",
title: "Service Factory", title: "Reference Overview",
isChildSidebar: true, },
children: [ {
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -71,25 +92,44 @@ export const referencesSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/helper-steps", sidebar_id: "helper-steps-reference",
title: "Helper Steps", title: "Helper Steps",
isChildSidebar: true, children: [
autogenerate_path: "/references/helper_steps/functions",
},
{ {
type: "link", type: "link",
path: "/references/helper-steps",
title: "Reference Overview",
},
{
type: "separator",
},
{
type: "category",
title: "Steps",
autogenerate_path: "/references/helper_steps/functions",
},
],
},
{
type: "sidebar",
sidebar_id: "core-flows",
title: "Core Workflows", title: "Core Workflows",
path: "/medusa-workflows-reference",
isChildSidebar: true,
custom_autogenerate: "core-flows", custom_autogenerate: "core-flows",
}, },
{ {
type: "link", type: "sidebar",
sidebar_id: "test-tools-reference",
title: "Testing Framework", title: "Testing Framework",
path: "/test-tools-reference",
isChildSidebar: true,
children: [ children: [
{
type: "link",
path: "/test-tools-reference",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Functions", title: "Functions",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const regionSidebar = [ export const regionSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "region",
title: "Region Module", title: "Region Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -131,12 +131,19 @@ export const regionSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/region", sidebar_id: "region-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Region Module's Main Service Reference", childSidebarTitle: "Region Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/region",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -146,12 +153,19 @@ export const regionSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/region/models", sidebar_id: "region-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Region Module Data Models Reference", childSidebarTitle: "Region Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/region/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+20 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const salesChannelSidebar = [ export const salesChannelSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "sales-channel",
title: "Sales Channel Module", title: "Sales Channel Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -138,12 +138,16 @@ export const salesChannelSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/sales-channel", sidebar_id: "sales-channel-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Sales Channel Module's Main Service Reference", childSidebarTitle: "Sales Channel Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/sales-channel",
title: "Reference Overview",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -153,12 +157,19 @@ export const salesChannelSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/sales-channel/models", sidebar_id: "sales-channel-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Sales Channel Module Data Models Reference", childSidebarTitle: "Sales Channel Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/sales-channel/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+15 -10
View File
@@ -1,4 +1,4 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const sdkToolsSidebar = [ export const sdkToolsSidebar = [
{ {
type: "link", type: "link",
@@ -6,10 +6,9 @@ export const sdkToolsSidebar = [
title: "create-medusa-app", title: "create-medusa-app",
}, },
{ {
type: "link", type: "sidebar",
path: "/medusa-cli", sidebar_id: "medusa-cli",
title: "Medusa CLI", title: "Medusa CLI",
isChildSidebar: true,
childSidebarTitle: "Medusa CLI Reference", childSidebarTitle: "Medusa CLI Reference",
children: [ children: [
{ {
@@ -28,12 +27,19 @@ export const sdkToolsSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/js-sdk", sidebar_id: "js-sdk",
title: "JS SDK", title: "JS SDK",
isChildSidebar: true,
childSidebarTitle: "JS SDK Reference", childSidebarTitle: "JS SDK Reference",
children: [ children: [
{
type: "link",
path: "/js-sdk",
title: "Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Auth", title: "Auth",
@@ -55,10 +61,9 @@ export const sdkToolsSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/nextjs-starter", sidebar_id: "nextjs-starter",
title: "Next.js Starter Storefront", title: "Next.js Starter Storefront",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const stockLocationSidebar = [ export const stockLocationSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "stock-location",
title: "Stock Location Module", title: "Stock Location Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -133,12 +133,19 @@ export const stockLocationSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/stock-location-next", sidebar_id: "stock-location-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Stock Location Module's Main Service Reference", childSidebarTitle: "Stock Location Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/stock-location-next",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -148,12 +155,19 @@ export const stockLocationSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/stock-location-next/models", sidebar_id: "stock-location-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Stock Location Module Data Models Reference", childSidebarTitle: "Stock Location Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/stock-location-next/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const storeSidebar = [ export const storeSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "store",
title: "Store Module", title: "Store Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -126,12 +126,19 @@ export const storeSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/store", sidebar_id: "store-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Store Module's Main Service Reference", childSidebarTitle: "Store Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/store",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -141,12 +148,19 @@ export const storeSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/store/models", sidebar_id: "store-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Store Module Data Models Reference", childSidebarTitle: "Store Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/store/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
+16 -1
View File
@@ -1,5 +1,18 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const storefrontGuidesSidebar = [ export const storefrontGuidesSidebar = [
{
type: "sidebar",
sidebar_id: "storefront-development",
title: "Storefront Development",
children: [
{
type: "link",
path: "/storefront-development",
title: "Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "General", title: "General",
@@ -257,4 +270,6 @@ export const storefrontGuidesSidebar = [
}, },
], ],
}, },
],
},
] ]
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const taxSidebar = [ export const taxSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "tax",
title: "Tax Module", title: "Tax Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -148,12 +148,19 @@ export const taxSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/tax", sidebar_id: "tax-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "Tax Module's Main Service Reference", childSidebarTitle: "Tax Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/tax",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -162,12 +169,19 @@ export const taxSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/tax/models", sidebar_id: "tax-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "Tax Module Data Models Reference", childSidebarTitle: "Tax Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/tax/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
@@ -1,5 +1,18 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const troubleshootingSidebar = [ export const troubleshootingSidebar = [
{
type: "sidebar",
sidebar_id: "troubleshooting",
title: "Troubleshooting",
children: [
{
type: "link",
path: "/troubleshooting",
title: "Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Installation", title: "Installation",
@@ -97,4 +110,6 @@ export const troubleshootingSidebar = [
}, },
], ],
}, },
],
},
] ]
+23 -9
View File
@@ -1,9 +1,9 @@
/** @type {import('types').RawSidebarItem[]} */ /** @type {import('types').Sidebar.SidebarItem[]} */
export const userSidebar = [ export const userSidebar = [
{ {
type: "category", type: "sidebar",
sidebar_id: "user",
title: "User Module", title: "User Module",
isChildSidebar: true,
children: [ children: [
{ {
type: "link", type: "link",
@@ -131,12 +131,19 @@ export const userSidebar = [
title: "Admin Widget Zones", title: "Admin Widget Zones",
}, },
{ {
type: "link", type: "sidebar",
path: "/references/user", sidebar_id: "user-service-reference",
title: "Main Service Reference", title: "Main Service Reference",
isChildSidebar: true,
childSidebarTitle: "User Module's Main Service Reference", childSidebarTitle: "User Module's Main Service Reference",
children: [ children: [
{
type: "link",
path: "/references/user",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Methods", title: "Methods",
@@ -146,12 +153,19 @@ export const userSidebar = [
], ],
}, },
{ {
type: "link", type: "sidebar",
path: "/references/user/models", sidebar_id: "user-models-reference",
title: "Data Models Reference", title: "Data Models Reference",
isChildSidebar: true,
childSidebarTitle: "User Module Data Models Reference", childSidebarTitle: "User Module Data Models Reference",
children: [ children: [
{
type: "link",
path: "/references/user/models",
title: "Reference Overview",
},
{
type: "separator",
},
{ {
type: "category", type: "category",
title: "Data Models", title: "Data Models",
-6
View File
@@ -1,6 +0,0 @@
import { SidebarItemType as UiSidebarItemType } from "docs-ui"
export declare type SidebarItemType = UiSidebarItemType & {
autogenerate_path?: string
children?: SidebarItemType[]
}
@@ -1,24 +0,0 @@
/** @type {Partial<import("../types").RawSidebarItem>} */
const commonOptions = {
loaded: true,
isPathHref: true,
}
/**
*
* @param {import("types").RawSidebarItem[]} sidebar
* @returns {import("types").RawSidebarItem[]}
*/
export function sidebarAttachHrefCommonOptions(sidebar) {
return sidebar.map((item) => {
if (item.type === "separator") {
return item
}
return {
...commonOptions,
...item,
children: sidebarAttachHrefCommonOptions(item.children || []),
}
})
}
+4 -4
View File
@@ -1,8 +1,8 @@
import { MetadataRoute } from "next" import { MetadataRoute } from "next"
import { docsConfig } from "@/config/docs" import { sidebars } from "@/config/sidebar"
import { absoluteUrl } from "@/lib/absolute-url" import { absoluteUrl } from "@/lib/absolute-url"
import { SidebarItem } from "types" import { Sidebar } from "types"
export default function sitemap(): MetadataRoute.Sitemap { export default function sitemap(): MetadataRoute.Sitemap {
const now = new Date() const now = new Date()
@@ -12,7 +12,7 @@ export default function sitemap(): MetadataRoute.Sitemap {
lastModified?: string | Date lastModified?: string | Date
}> = [] }> = []
function pushItems(newItems: SidebarItem[]) { function pushItems(newItems: Sidebar.SidebarItem[]) {
newItems.forEach((item) => { newItems.forEach((item) => {
if (item.type !== "link") { if (item.type !== "link") {
return return
@@ -29,7 +29,7 @@ export default function sitemap(): MetadataRoute.Sitemap {
}) })
} }
pushItems(docsConfig.sidebar.default) sidebars.forEach((sidebar) => pushItems(sidebar.items))
return items return items
} }
+1 -8
View File
@@ -60,14 +60,7 @@ export default function RootLayout({
htmlClassName={clsx(inter.variable, robotoMono.variable)} htmlClassName={clsx(inter.variable, robotoMono.variable)}
gaId={process.env.NEXT_PUBLIC_GA_ID} gaId={process.env.NEXT_PUBLIC_GA_ID}
> >
<TightLayout <TightLayout ProvidersComponent={Providers}>{children}</TightLayout>
sidebarProps={{
expandItems: true,
}}
ProvidersComponent={Providers}
>
{children}
</TightLayout>
</BareboneLayout> </BareboneLayout>
) )
} }
+156 -200
View File
@@ -1,226 +1,182 @@
export const colors = { export const colors = {
dark: { dark: {
"--fg-on-color": "rgba(255, 255, 255, 1)",
"--border-danger": "rgba(190, 18, 60, 1)",
"--border-interactive": "rgba(96, 165, 250, 1)",
"--fg-interactive-hover": "rgba(59, 130, 246, 1)",
"--fg-error": "rgba(251, 113, 133, 1)",
"--bg-interactive": "rgba(96, 165, 250, 1)",
"--border-error": "rgba(244, 63, 94, 1)",
"--button-danger": "rgba(159, 18, 57, 1)",
"--button-danger-gradient-from": "rgba(255, 255, 255, 1)",
"--button-danger-gradient-to": "rgba(255, 255, 255, 0)",
"--fg-interactive": "rgba(96, 165, 250, 1)",
"--tag-red-border": "rgba(136, 19, 55, 1)",
"--tag-red-bg": "rgba(76, 5, 25, 1)",
"--tag-blue-text": "rgba(96, 165, 250, 1)",
"--tag-orange-text": "rgba(251, 191, 36, 1)",
"--tag-green-text": "rgba(52, 211, 153, 1)",
"--tag-orange-border": "rgba(120, 53, 15, 1)",
"--tag-green-border": "rgba(6, 78, 59, 1)",
"--tag-red-text": "rgba(251, 113, 133, 1)",
"--tag-green-bg-hover": "rgba(6, 78, 59, 1)",
"--tag-purple-bg-hover": "rgba(76, 29, 149, 1)",
"--tag-red-bg-hover": "rgba(136, 19, 55, 1)",
"--border-transparent": "rgba(255, 255, 255, 0)",
"--tag-orange-icon": "rgba(245, 158, 11, 1)",
"--tag-purple-bg": "rgba(46, 16, 100, 1)",
"--tag-blue-bg": "rgba(23, 37, 84, 1)",
"--tag-green-bg": "rgba(2, 44, 34, 1)",
"--tag-blue-border": "rgba(30, 58, 138, 1)",
"--tag-purple-border": "rgba(76, 29, 149, 1)",
"--tag-blue-bg-hover": "rgba(30, 42, 138, 1)",
"--tag-orange-bg": "rgba(69, 26, 3, 1)",
"--tag-orange-bg-hover": "rgba(120, 53, 15, 1)",
"--tag-blue-icon": "rgba(59, 130, 246, 1)",
"--tag-red-icon": "rgba(244, 63, 94, 1)",
"--tag-purple-icon": "rgba(139, 92, 246, 1)",
"--tag-purple-text": "rgba(167, 139, 250, 1)",
"--tag-green-icon": "rgba(16, 185, 129, 1)",
"--button-danger-pressed": "rgba(225, 29, 72, 1)", "--button-danger-pressed": "rgba(225, 29, 72, 1)",
"--button-danger-pressed-gradient-from": "rgba(255, 255, 255, 1)", "--bg-base-pressed": "rgba(63, 63, 70, 1)",
"--button-danger-pressed-gradient-to": "rgba(255, 255, 255, 0)", "--bg-component-hover": "rgba(255, 255, 255, 0.1)",
"--button-danger-hover": "rgba(190, 18, 60, 1)", "--border-interactive": "rgba(96, 165, 250, 1)",
"--button-danger-hover-gradient-from": "rgba(255, 255, 255, 1)", "--button-neutral": "rgba(255, 255, 255, 0.04)",
"--button-danger-hover-gradient-to": "rgba(255, 255, 255, 0)", "--tag-orange-border": "rgba(124, 45, 18, 1)",
"--button-transparent": "rgba(0, 0, 0, 0.01)", "--tag-blue-text": "rgba(147, 197, 253, 1)",
"--code-bg-base": "rgba(9, 9, 11, 1)",
"--button-neutral": "rgba(39, 39, 42, 1)",
"--button-neutral-gradient-from": "rgba(255, 255, 255, 1)",
"--button-neutral-gradient-to": "rgba(255, 255, 255, 0)",
"--button-transparent-hover": "rgba(39, 39, 42, 1)",
"--code-fg-subtle": "rgba(161, 161, 170, 1)",
"--tag-neutral-bg-hover": "rgba(63, 63, 70, 1)",
"--contrast-border-base": "rgba(82, 82, 91, 1)",
"--button-neutral-pressed": "rgba(82, 82, 91, 1)",
"--button-neutral-pressed-gradient-from": "rgba(255, 255, 255, 1)",
"--button-neutral-pressed-gradient-to": "rgba(255, 255, 255, 0)",
"--tag-neutral-bg": "rgba(39, 39, 42, 1)",
"--bg-highlight": "rgba(23, 37, 84, 1)", "--bg-highlight": "rgba(23, 37, 84, 1)",
"--border-base": "rgba(255, 255, 255, 0.1)",
"--code-fg-base": "rgba(250, 250, 250, 1)",
"--tag-neutral-icon": "rgba(113, 113, 122, 1)", "--tag-neutral-icon": "rgba(113, 113, 122, 1)",
"--bg-switch-off-hover": "rgba(82, 82, 91, 1)", "--bg-switch-off-hover": "rgba(82, 82, 91, 1)",
"--bg-base": "rgba(24, 24, 27, 1)", "--fg-on-color": "rgba(255, 255, 255, 1)",
"--button-inverted-pressed": "rgba(161, 161, 170, 1)", "--button-inverted-pressed": "rgba(161, 161, 170, 1)",
"--button-inverted-pressed-gradient-from": "rgba(255, 255, 255, 1)", "--fg-interactive-hover": "rgba(147, 197, 253, 1)",
"--button-inverted-pressed-gradient-to": "rgba(255, 255, 255, 0)", "--fg-error": "rgba(251, 113, 133, 1)",
"--button-neutral-hover": "rgba(63, 63, 70, 1)",
"--button-neutral-hover-gradient-from": "rgba(255, 255, 255, 1)",
"--button-neutral-hover-gradient-to": "rgba(255, 255, 255, 0)",
"--bg-switch-off": "rgba(63, 63, 70, 1)", "--bg-switch-off": "rgba(63, 63, 70, 1)",
"--border-strong": "rgba(255, 255, 255, 0.15)", "--border-strong": "rgba(255, 255, 255, 0.16)",
"--border-error": "rgba(251, 113, 133, 1)",
"--fg-subtle": "rgba(161, 161, 170, 1)", "--fg-subtle": "rgba(161, 161, 170, 1)",
"--bg-highlight-hover": "rgba(30, 58, 138, 1)", "--bg-highlight-hover": "rgba(30, 58, 138, 1)",
"--button-inverted": "rgba(82, 82, 91, 1)", "--button-inverted": "rgba(82, 82, 91, 1)",
"--button-inverted-gradient-from": "rgba(255, 255, 255, 1)", "--tag-orange-text": "rgba(253, 186, 116, 1)",
"--button-inverted-gradient-to": "rgba(255, 255, 255, 0)", "--fg-base": "rgba(244, 244, 245, 1)",
"--fg-base": "rgba(250, 250, 250, 1)", "--fg-disabled": "rgba(82, 82, 91, 1)",
"--code-border": "rgba(39, 39, 42, 1)", "--button-danger": "rgba(159, 18, 57, 1)",
"--contrast-bg-subtle": "rgba(39, 39, 42, 1)", "--tag-neutral-border": "rgba(255, 255, 255, 0.06)",
"--contrast-bg-base-hover": "rgba(82, 82, 91, 1)", "--tag-blue-border": "rgba(30, 58, 138, 1)",
"--bg-base-hover": "rgba(39, 39, 42, 1)", "--tag-neutral-text": "rgba(212, 212, 216, 1)",
"--bg-subtle-hover": "rgba(24, 24, 27, 1)", "--tag-purple-border": "rgba(91, 33, 182, 1)",
"--fg-disabled": "rgba(63, 63, 70, 1)", "--tag-green-text": "rgba(52, 211, 153, 1)",
"--bg-subtle": "rgba(9, 9, 11, 1)",
"--tag-neutral-border": "rgba(63, 63, 70, 1)",
"--bg-subtle-pressed": "rgba(39, 39, 42, 1)",
"--tag-neutral-text": "rgba(161, 161, 170, 1)",
"--fg-muted": "rgba(82, 82, 91, 1)",
"--bg-overlay": "rgba(9, 9, 11, 0.7)",
"--button-inverted-hover": "rgba(113, 113, 122, 1)", "--button-inverted-hover": "rgba(113, 113, 122, 1)",
"--button-inverted-hover-gradient-from": "rgba(255, 255, 255, 1)", "--bg-component-pressed": "rgba(255, 255, 255, 0.16)",
"--button-inverted-hover-gradient-to": "rgba(255, 255, 255, 0)", "--contrast-border-bot": "rgba(255, 255, 255, 0.08)",
"--fg-on-inverted": "rgba(9, 9, 11, 1)", "--tag-blue-icon": "rgba(96, 165, 250, 1)",
"--code-bg-subtle": "rgba(24, 24, 27, 1)", "--bg-field": "rgba(255, 255, 255, 0.04)",
"--tag-neutral-bg": "rgba(255, 255, 255, 0.08)",
"--tag-green-border": "rgba(6, 78, 59, 1)",
"--tag-red-icon": "rgba(251, 113, 133, 1)",
"--tag-red-text": "rgba(253, 164, 175, 1)",
"--tag-purple-icon": "rgba(167, 139, 250, 1)",
"--bg-interactive": "rgba(96, 165, 250, 1)",
"--bg-field-hover": "rgba(255, 255, 255, 0.08)",
"--border-transparent": "rgba(255, 255, 255, 0)",
"--tag-orange-icon": "rgba(251, 146, 60, 1)",
"--tag-purple-bg": "rgba(46, 16, 101, 1)",
"--bg-base-hover": "rgba(39, 39, 42, 1)",
"--tag-blue-bg": "rgba(23, 37, 84, 1)",
"--tag-green-bg": "rgba(2, 44, 34, 1)",
"--tag-purple-text": "rgba(196, 181, 253, 1)",
"--tag-red-border": "rgba(136, 19, 55, 1)",
"--border-danger": "rgba(190, 18, 60, 1)",
"--tag-green-icon": "rgba(16, 185, 129, 1)",
"--tag-red-bg": "rgba(76, 5, 25, 1)",
"--fg-interactive": "rgba(96, 165, 250, 1)",
"--tag-orange-bg": "rgba(67, 20, 7, 1)",
"--button-danger-hover": "rgba(190, 18, 60, 1)",
"--bg-component": "rgba(39, 39, 42, 1)", "--bg-component": "rgba(39, 39, 42, 1)",
"--border-loud": "rgba(250, 250, 250, 1)",
"--bg-base-pressed": "rgba(63, 63, 70, 1)",
"--bg-disabled": "rgba(39, 39, 42, 1)", "--bg-disabled": "rgba(39, 39, 42, 1)",
"--contrast-bg-highlight": "rgba(82, 82, 91, 1)", "--button-transparent": "rgba(255, 255, 255, 0)",
"--button-transparent-pressed": "rgba(63, 63, 70, 1)", "--border-menu-bot": "rgba(255, 255, 255, 0.08)",
"--code-fg-muted": "rgba(82, 82, 91, 1)", "--tag-purple-bg-hover": "rgba(91, 33, 182, 1)",
"--contrast-fg-secondary": "rgba(161, 161, 170, 1)", "--tag-orange-bg-hover": "rgba(124, 45, 18, 1)",
"--contrast-bg-base-pressed": "rgba(113, 113, 122, 1)", "--tag-blue-bg-hover": "rgba(30, 58, 138, 1)",
"--contrast-fg-primary": "rgba(250, 250, 250, 1)", "--tag-red-bg-hover": "rgba(136, 19, 55, 1)",
"--contrast-bg-base": "rgba(63, 63, 70, 1)", "--tag-green-bg-hover": "rgba(6, 78, 59, 1)",
"--bg-component-pressed": "rgba(82, 82, 91, 1)", "--border-menu-top": "rgba(33, 33, 36, 1)",
"--bg-component-hover": "rgba(63, 63, 70, 1)", "--bg-base": "rgba(33, 33, 36, 1)",
"--bg-field": "rgba(39, 39, 42, 1)", "--contrast-border-top": "rgba(33, 33, 36, 1)",
"--bg-field-component": "rgba(24, 24, 27, 1)", "--bg-field-component": "rgba(33, 33, 36, 1)",
"--bg-field-component-hover": "rgba(24, 24, 27, 1)", "--bg-subtle-hover": "rgba(33, 33, 36, 1)",
"--bg-field-hover": "rgba(39, 39, 42, 1)", "--bg-subtle": "rgba(24, 24, 27, 1)",
"--fg-on-inverted": "rgba(24, 24, 27, 1)",
"--bg-overlay": "rgba(24, 24, 27, 0.72)",
"--button-transparent-hover": "rgba(255, 255, 255, 0.08)",
"--contrast-fg-secondary": "rgba(255, 255, 255, 0.56)",
"--contrast-border-base": "rgba(255, 255, 255, 0.16)",
"--contrast-bg-base-pressed": "rgba(82, 82, 91, 1)",
"--button-neutral-pressed": "rgba(255, 255, 255, 0.12)",
"--border-base": "rgba(255, 255, 255, 0.08)",
"--contrast-fg-primary": "rgba(255, 255, 255, 0.88)",
"--button-neutral-hover": "rgba(255, 255, 255, 0.08)",
"--contrast-bg-base": "rgba(39, 39, 42, 1)",
"--tag-neutral-bg-hover": "rgba(255, 255, 255, 0.12)",
"--contrast-bg-subtle": "rgba(255, 255, 255, 0.04)",
"--contrast-bg-base-hover": "rgba(63, 63, 70, 1)",
"--bg-field-component-hover": "rgba(39, 39, 42, 1)",
"--bg-subtle-pressed": "rgba(39, 39, 42, 1)",
"--button-transparent-pressed": "rgba(255, 255, 255, 0.12)",
"--fg-muted": "rgba(113, 113, 122, 1)",
}, },
light: { light: {
"--tag-green-bg": "rgba(209, 250, 229, 1)",
"--border-interactive": "rgba(59, 130, 246, 1)",
"--bg-highlight": "rgba(239, 246, 255, 1)",
"--tag-red-bg": "rgba(255, 228, 230, 1)",
"--tag-orange-bg": "rgba(254, 244, 199, 1)",
"--bg-base": "rgba(255, 255, 255, 1)",
"--tag-green-icon": "rgba(5, 150, 105, 1)",
"--tag-purple-bg-hover": "rgba(221, 214, 254, 1)",
"--tag-blue-border": "rgba(191, 219, 254, 1)",
"--tag-orange-icon": "rgba(217, 119, 6, 1)",
"--tag-purple-bg": "rgba(237, 233, 254, 1)",
"--tag-purple-text": "rgba(109, 40, 217, 1)",
"--tag-blue-bg": "rgba(219, 234, 254, 1)",
"--tag-blue-icon": "rgba(37, 99, 235, 1)",
"--border-error": "rgba(225, 29, 72, 1)",
"--fg-on-inverted": "rgba(255, 255, 255, 1)",
"--fg-on-color": "rgba(255, 255, 255, 1)",
"--fg-interactive-hover": "rgba(37, 99, 235, 1)",
"--fg-interactive": "rgba(59, 130, 246, 1)",
"--fg-error": "rgba(225, 29, 72, 1)",
"--border-danger": "rgba(190, 18, 60, 1)",
"--fg-muted": "rgba(161, 161, 170, 1)",
"--bg-subtle-pressed": "rgba(228, 228, 231, 1)",
"--tag-green-bg-hover": "rgba(167, 243, 208, 1)",
"--tag-blue-bg-hover": "rgba(191, 219, 254, 1)",
"--tag-red-icon": "rgba(225, 29, 72, 1)",
"--tag-red-bg-hover": "rgba(254, 205, 211, 1)",
"--tag-red-text": "rgba(190, 18, 60, 1)",
"--tag-purple-icon": "rgba(124, 58, 237, 1)",
"--tag-blue-text": "rgba(29, 78, 216, 1)",
"--tag-orange-bg-hover": "rgba(253, 230, 138, 1)",
"--tag-purple-border": "rgba(221, 214, 254, 1)",
"--tag-orange-text": "rgba(180, 83, 9, 1)",
"--tag-orange-border": "rgba(253, 230, 138, 1)",
"--tag-red-border": "rgba(254, 205, 211, 1)",
"--tag-green-border": "rgba(167, 243, 208, 1)",
"--tag-green-text": "rgba(4, 120, 87, 1)",
"--button-danger": "rgba(225, 29, 72, 1)",
"--button-danger-gradient-from": "rgba(255, 255, 255, 1)",
"--button-danger-gradient-to": "rgba(255, 255, 255, 0)",
"--button-danger-pressed": "rgba(159, 18, 57, 1)",
"--button-danger-pressed-gradient-from": "rgba(255, 255, 255, 1)",
"--button-danger-pressed-gradient-to": "rgba(255, 255, 255, 0)",
"--button-danger-hover": "rgba(190, 18, 60, 1)",
"--button-danger-hover-gradient-from": "rgba(255, 255, 255, 1)",
"--button-danger-hover-gradient-to": "rgba(255, 255, 255, 0)",
"--bg-interactive": "rgba(59, 130, 246, 1)",
"--bg-highlight-hover": "rgba(219, 234, 254, 1)",
"--button-transparent": "rgba(255, 255, 255, 0.01)",
"--bg-overlay": "rgba(9, 9, 11, 0.4)",
"--tag-neutral-border": "rgba(228, 228, 231, 1)", "--tag-neutral-border": "rgba(228, 228, 231, 1)",
"--border-loud": "rgba(9, 9, 11, 1)", "--tag-neutral-icon": "rgba(161, 161, 170, 1)",
"--contrast-fg-primary": "rgba(250, 250, 250, 1)", "--bg-switch-off-hover": "rgba(212, 212, 216, 1)",
"--border-menu-bot": "rgba(255, 255, 255, 1)",
"--border-menu-top": "rgba(228, 228, 231, 1)",
"--bg-subtle-hover": "rgba(244, 244, 245, 1)",
"--contrast-fg-primary": "rgba(255, 255, 255, 0.88)",
"--bg-switch-off": "rgba(228, 228, 231, 1)", "--bg-switch-off": "rgba(228, 228, 231, 1)",
"--contrast-bg-base-pressed": "rgba(63, 63, 70, 1)", "--contrast-bg-base-pressed": "rgba(63, 63, 70, 1)",
"--bg-field-component-hover": "rgba(250, 250, 250, 1)",
"--bg-base-pressed": "rgba(228, 228, 231, 1)", "--bg-base-pressed": "rgba(228, 228, 231, 1)",
"--tag-neutral-text": "rgba(82, 82, 91, 1)", "--tag-neutral-text": "rgba(82, 82, 91, 1)",
"--button-transparent-hover": "rgba(244, 244, 245, 1)", "--tag-red-text": "rgba(159, 18, 57, 1)",
"--contrast-bg-base": "rgba(24, 24, 27, 1)", "--contrast-bg-base": "rgba(24, 24, 27, 1)",
"--fg-disabled": "rgba(212, 212, 216, 1)",
"--bg-field": "rgba(250, 250, 250, 1)",
"--border-strong": "rgba(212, 212, 216, 1)", "--border-strong": "rgba(212, 212, 216, 1)",
"--bg-field-hover": "rgba(244, 244, 245, 1)", "--contrast-border-base": "rgba(255, 255, 255, 0.15)",
"--contrast-border-base": "rgba(82, 82, 91, 1)", "--bg-field": "rgba(250, 250, 250, 1)",
"--fg-base": "rgba(9, 9, 11, 1)", "--tag-blue-text": "rgba(30, 64, 175, 1)",
"--contrast-bg-subtle": "rgba(39, 39, 42, 1)", "--button-inverted-pressed": "rgba(82, 82, 91, 1)",
"--contrast-fg-secondary": "rgba(161, 161, 170, 1)", "--border-interactive": "rgba(59, 130, 246, 1)",
"--code-fg-subtle": "rgba(161, 161, 170, 1)",
"--tag-neutral-bg": "rgba(244, 244, 245, 1)",
"--button-transparent-pressed": "rgba(228, 228, 231, 1)",
"--tag-neutral-bg-hover": "rgba(228, 228, 231, 1)",
"--code-fg-muted": "rgba(113, 113, 122, 1)",
"--contrast-bg-highlight": "rgba(63, 63, 70, 1)",
"--tag-neutral-icon": "rgba(113, 113, 122, 1)",
"--border-base": "rgba(228, 228, 231, 1)",
"--code-bg-base": "rgba(24, 24, 27, 1)",
"--button-neutral": "rgba(255, 255, 255, 1)",
"--button-neutral-gradient-from": "rgba(9, 9, 11, 0)",
"--button-neutral-gradient-to": "rgba(9, 9, 11, 1)",
"--code-bg-subtle": "rgba(39, 39, 42, 1)",
"--button-neutral-hover": "rgba(244, 244, 245, 1)",
"--button-neutral-hover-gradient-from": "rgba(9, 9, 11, 0)",
"--button-neutral-hover-gradient-to": "rgba(9, 9, 11, 1)",
"--contrast-bg-base-hover": "rgba(39, 39, 42, 1)",
"--bg-subtle": "rgba(250, 250, 250, 1)",
"--bg-switch-off-hover": "rgba(212, 212, 216, 1)",
"--code-fg-base": "rgba(250, 250, 250, 1)",
"--bg-disabled": "rgba(244, 244, 245, 1)",
"--code-border": "rgba(63, 63, 70, 1)",
"--fg-subtle": "rgba(82, 82, 91, 1)",
"--bg-subtle-hover": "rgba(244, 244, 245, 1)",
"--button-neutral-pressed": "rgba(228, 228, 231, 1)",
"--button-neutral-pressed-gradient-from": "rgba(9, 9, 11, 0)",
"--button-neutral-pressed-gradient-to": "rgba(9, 9, 11, 1)",
"--border-transparent": "rgba(9, 9, 11, 0)",
"--button-inverted": "rgba(9, 9, 11, 1)",
"--button-inverted-gradient-from": "rgba(255, 255, 255, 1)",
"--button-inverted-gradient-to": "rgba(255, 255, 255, 0)",
"--button-inverted-pressed": "rgba(39, 39, 42, 1)",
"--button-inverted-pressed-gradient-from": "rgba(255, 255, 255, 1)",
"--button-inverted-pressed-gradient-to": "rgba(255, 255, 255, 0)",
"--button-inverted-hover": "rgba(24, 24, 27, 1)",
"--button-inverted-hover-gradient-from": "rgba(255, 255, 255, 1)",
"--button-inverted-hover-gradient-to": "rgba(255, 255, 255, 0)",
"--bg-component-hover": "rgba(244, 244, 245, 1)",
"--bg-field-component": "rgba(255, 255, 255, 1)",
"--bg-field-component-hover": "rgba(250, 250, 250, 1)",
"--bg-component-pressed": "rgba(228, 228, 231, 1)",
"--bg-component": "rgba(250, 250, 250, 1)",
"--bg-base-hover": "rgba(244, 244, 245, 1)", "--bg-base-hover": "rgba(244, 244, 245, 1)",
"--contrast-bg-subtle": "rgba(39, 39, 42, 1)",
"--bg-highlight": "rgba(239, 246, 255, 1)",
"--contrast-fg-secondary": "rgba(255, 255, 255, 0.56)",
"--tag-red-bg": "rgba(255, 228, 230, 1)",
"--button-transparent": "rgba(255, 255, 255, 0)",
"--button-danger-pressed": "rgba(159, 18, 57, 1)",
"--fg-on-color": "rgba(255, 255, 255, 1)",
"--button-inverted-hover": "rgba(63, 63, 70, 1)",
"--bg-field-component": "rgba(255, 255, 255, 1)",
"--tag-orange-text": "rgba(154, 52, 18, 1)",
"--tag-green-icon": "rgba(16, 185, 129, 1)",
"--border-base": "rgba(228, 228, 231, 1)",
"--bg-base": "rgba(255, 255, 255, 1)",
"--tag-orange-border": "rgba(254, 215, 170, 1)",
"--tag-red-border": "rgba(254, 205, 211, 1)",
"--tag-green-border": "rgba(167, 243, 208, 1)",
"--tag-green-text": "rgba(6, 95, 70, 1)",
"--button-neutral": "rgba(255, 255, 255, 1)",
"--tag-blue-border": "rgba(191, 219, 254, 1)",
"--fg-interactive-hover": "rgba(37, 99, 235, 1)",
"--tag-orange-icon": "rgba(249, 115, 22, 1)",
"--button-neutral-hover": "rgba(244, 244, 245, 1)",
"--fg-interactive": "rgba(59, 130, 246, 1)",
"--bg-component-pressed": "rgba(228, 228, 231, 1)",
"--tag-purple-bg": "rgba(237, 233, 254, 1)",
"--contrast-bg-base-hover": "rgba(39, 39, 42, 1)",
"--bg-component": "rgba(250, 250, 250, 1)",
"--bg-subtle": "rgba(250, 250, 250, 1)",
"--tag-purple-text": "rgba(91, 33, 182, 1)",
"--contrast-border-bot": "rgba(255, 255, 255, 0.1)",
"--button-inverted": "rgba(39, 39, 42, 1)",
"--tag-red-icon": "rgba(244, 63, 94, 1)",
"--button-transparent-hover": "rgba(244, 244, 245, 1)",
"--button-neutral-pressed": "rgba(228, 228, 231, 1)",
"--tag-purple-icon": "rgba(167, 139, 250, 1)",
"--bg-field-hover": "rgba(244, 244, 245, 1)",
"--fg-on-inverted": "rgba(255, 255, 255, 1)",
"--bg-interactive": "rgba(59, 130, 246, 1)",
"--border-danger": "rgba(190, 18, 60, 1)",
"--button-transparent-pressed": "rgba(228, 228, 231, 1)",
"--tag-purple-border": "rgba(221, 214, 254, 1)",
"--bg-highlight-hover": "rgba(219, 234, 254, 1)",
"--border-error": "rgba(225, 29, 72, 1)",
"--button-danger": "rgba(225, 29, 72, 1)",
"--tag-blue-bg": "rgba(219, 234, 254, 1)",
"--border-transparent": "rgba(255, 255, 255, 0)",
"--button-danger-hover": "rgba(190, 18, 60, 1)",
"--bg-subtle-pressed": "rgba(228, 228, 231, 1)",
"--fg-error": "rgba(225, 29, 72, 1)",
"--bg-component-hover": "rgba(244, 244, 245, 1)",
"--bg-disabled": "rgba(244, 244, 245, 1)",
"--tag-blue-icon": "rgba(96, 165, 250, 1)",
"--fg-subtle": "rgba(82, 82, 91, 1)",
"--tag-orange-bg-hover": "rgba(254, 215, 170, 1)",
"--tag-green-bg-hover": "rgba(167, 243, 208, 1)",
"--tag-red-bg-hover": "rgba(254, 205, 211, 1)",
"--tag-purple-bg-hover": "rgba(221, 214, 254, 1)",
"--tag-neutral-bg-hover": "rgba(228, 228, 231, 1)",
"--tag-blue-bg-hover": "rgba(191, 219, 254, 1)",
"--tag-green-bg": "rgba(209, 250, 229, 1)",
"--tag-neutral-bg": "rgba(244, 244, 245, 1)",
"--tag-orange-bg": "rgba(255, 237, 213, 1)",
"--fg-base": "rgba(24, 24, 27, 1)",
"--contrast-border-top": "rgba(24, 24, 27, 1)",
"--bg-overlay": "rgba(24, 24, 27, 0.4)",
"--fg-disabled": "rgba(161, 161, 170, 1)",
"--fg-muted": "rgba(113, 113, 122, 1)",
}, },
} }
@@ -1,12 +1,10 @@
import { SidebarSectionItems } from "types" import { Sidebar } from "types"
type DocsConfig = { export const sidebars: Sidebar.Sidebar[] = [
sidebar: SidebarSectionItems {
} sidebar_id: "ui",
title: "Medusa UI",
export const docsConfig: DocsConfig = { items: [
sidebar: {
default: [
{ {
type: "link", type: "link",
title: "Introduction", title: "Introduction",
@@ -364,6 +362,5 @@ export const docsConfig: DocsConfig = {
], ],
}, },
], ],
mobile: [],
}, },
} ]
+8 -6
View File
@@ -1,5 +1,6 @@
import { globalConfig } from "docs-ui" import { globalConfig } from "docs-ui"
import { DocsConfig } from "types" import { DocsConfig } from "types"
import { sidebars } from "./sidebar"
type SiteConfig = { type SiteConfig = {
name: string name: string
@@ -16,17 +17,18 @@ export const siteConfig: SiteConfig = {
basePath: process.env.NEXT_PUBLIC_BASE_PATH, basePath: process.env.NEXT_PUBLIC_BASE_PATH,
url: `${baseUrl}/${process.env.NEXT_PUBLIC_BASE_PATH}`, url: `${baseUrl}/${process.env.NEXT_PUBLIC_BASE_PATH}`,
description: "Primitives for building Medusa applications.", description: "Primitives for building Medusa applications.",
// sidebar is defined in docs.tsx sidebars,
sidebar: {
default: [],
mobile: [],
},
project: { project: {
title: "Medusa UI", title: "Medusa UI",
key: "ui", key: "ui",
}, },
breadcrumbOptions: { breadcrumbOptions: {
showCategories: true, startItems: [
{
title: "Documentation",
link: baseUrl,
},
],
}, },
logo: `${process.env.NEXT_PUBLIC_BASE_PATH}/images/logo.png`, logo: `${process.env.NEXT_PUBLIC_BASE_PATH}/images/logo.png`,
version: { version: {
+2 -5
View File
@@ -2,7 +2,7 @@ import {
SidebarProvider as UiSidebarProvider, SidebarProvider as UiSidebarProvider,
useScrollController, useScrollController,
} from "docs-ui" } from "docs-ui"
import { docsConfig } from "@/config/docs" import { sidebars } from "@/config/sidebar"
type SidebarProviderProps = { type SidebarProviderProps = {
children?: React.ReactNode children?: React.ReactNode
@@ -13,11 +13,8 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
return ( return (
<UiSidebarProvider <UiSidebarProvider
initialItems={docsConfig.sidebar} sidebars={sidebars}
shouldHandlePathChange={true}
scrollableElement={scrollableElement} scrollableElement={scrollableElement}
disableActiveTransition={true}
projectName="ui"
> >
{children} {children}
</UiSidebarProvider> </UiSidebarProvider>
-8
View File
@@ -1,8 +0,0 @@
export interface SidebarNavItem {
title: string
href?: string
disabled?: boolean
external?: boolean
label?: string
items?: SidebarNavItem[]
}
+1 -7
View File
@@ -64,13 +64,7 @@ export default function RootLayout({
htmlClassName={clsx(inter.variable, robotoMono.variable)} htmlClassName={clsx(inter.variable, robotoMono.variable)}
gaId={process.env.NEXT_PUBLIC_GA_ID} gaId={process.env.NEXT_PUBLIC_GA_ID}
> >
<TightLayout <TightLayout ProvidersComponent={Providers} footerComponent={<Footer />}>
sidebarProps={{
expandItems: true,
}}
ProvidersComponent={Providers}
footerComponent={<Footer />}
>
{children} {children}
<Feedback className="my-2" /> <Feedback className="my-2" />
<EditButton /> <EditButton />
+11 -9
View File
@@ -1,5 +1,5 @@
import { DocsConfig, SidebarItem } from "types" import { DocsConfig, Sidebar } from "types"
import { generatedSidebar as sidebar } from "@/generated/sidebar.mjs" import { generatedSidebars } from "@/generated/sidebar.mjs"
import { globalConfig } from "docs-ui" import { globalConfig } from "docs-ui"
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000"
@@ -9,16 +9,18 @@ export const config: DocsConfig = {
titleSuffix: "Medusa Admin User Guide", titleSuffix: "Medusa Admin User Guide",
baseUrl, baseUrl,
basePath: process.env.NEXT_PUBLIC_BASE_PATH, basePath: process.env.NEXT_PUBLIC_BASE_PATH,
sidebar: { sidebars: generatedSidebars as Sidebar.Sidebar[],
default: sidebar as SidebarItem[],
mobile: [],
},
project: { project: {
title: "User Guide", title: "User Guide",
key: "user-guide", key: "user-guide",
}, },
breadcrumbOptions: {
showCategories: true,
},
logo: `${process.env.NEXT_PUBLIC_BASE_PATH}/images/logo.png`, logo: `${process.env.NEXT_PUBLIC_BASE_PATH}/images/logo.png`,
breadcrumbOptions: {
startItems: [
{
title: "Documentation",
link: baseUrl,
},
],
},
} }
+7 -1
View File
@@ -1,4 +1,8 @@
export const generatedSidebar = [ export const generatedSidebars = [
{
"sidebar_id": "user-guide",
"title": "User Guide",
"items": [
{ {
"loaded": true, "loaded": true,
"isPathHref": true, "isPathHref": true,
@@ -507,3 +511,5 @@ export const generatedSidebar = [
] ]
} }
] ]
}
]
+1 -6
View File
@@ -14,13 +14,8 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
return ( return (
<UiSidebarProvider <UiSidebarProvider
shouldHandlePathChange={true}
shouldHandleHashChange={false}
scrollableElement={scrollableElement} scrollableElement={scrollableElement}
initialItems={config.sidebar} sidebars={config.sidebars}
staticSidebarItems={true}
disableActiveTransition={true}
projectName="user-guide"
> >
{children} {children}
</UiSidebarProvider> </UiSidebarProvider>
+9 -7
View File
@@ -1,9 +1,9 @@
import { sidebarAttachHrefCommonOptions } from "build-scripts" /** @type {import('types').Sidebar.RawSidebar[]} */
export const sidebar = [
// TODO check the order of items based on the Medusa Admin's sidebar {
sidebar_id: "user-guide",
/** @type {import('types').RawSidebarItemType[]} */ title: "User Guide",
export const sidebar = sidebarAttachHrefCommonOptions([ items: [
{ {
type: "link", type: "link",
path: "/", path: "/",
@@ -317,4 +317,6 @@ export const sidebar = sidebarAttachHrefCommonOptions([
}, },
], ],
}, },
]) ],
},
]
@@ -1,13 +1,14 @@
import type { RawSidebarItem, SidebarItem } from "types"
import { existsSync, mkdirSync, readdirSync, statSync } from "fs" import { existsSync, mkdirSync, readdirSync, statSync } from "fs"
import path from "path" import path from "path"
import { getSidebarItemLink, sidebarAttachHrefCommonOptions } from "./index.js" import { getSidebarItemLink, sidebarAttachCommonOptions } from "./index.js"
import getCoreFlowsRefSidebarChildren from "./utils/get-core-flows-ref-sidebar-children.js" import getCoreFlowsRefSidebarChildren from "./utils/get-core-flows-ref-sidebar-children.js"
import { parseTags } from "./utils/parse-tags.js" import { parseTags } from "./utils/parse-tags.js"
import numberSidebarItems from "./utils/number-sidebar-items.js" import numberSidebarItems from "./utils/number-sidebar-items.js"
import { sortSidebarItems } from "./utils/sidebar-sorting.js" import { sortSidebarItems } from "./utils/sidebar-sorting.js"
import { Sidebar } from "types"
import { validateSidebarUniqueIds } from "./utils/validate-sidebar-unique-ids.js"
export type ItemsToAdd = SidebarItem & { export type ItemsToAdd = Sidebar.SidebarItem & {
sidebar_position?: number sidebar_position?: number
} }
@@ -52,9 +53,7 @@ async function getAutogeneratedSidebarItems(
loaded: true, loaded: true,
}) })
} else { } else {
items.push( items.push(...newItems)
...(sidebarAttachHrefCommonOptions(newItems) as ItemsToAdd[])
)
} }
continue continue
} }
@@ -96,7 +95,7 @@ async function getAutogeneratedSidebarItems(
async function getAutogeneratedTagSidebarItems( async function getAutogeneratedTagSidebarItems(
tags: string, tags: string,
type: "link" | "ref", type: "link" | "ref",
existingChildren?: RawSidebarItem[] existingChildren?: Sidebar.RawSidebarItem[]
): Promise<ItemsToAdd[]> { ): Promise<ItemsToAdd[]> {
const items: ItemsToAdd[] = [] const items: ItemsToAdd[] = []
@@ -105,13 +104,15 @@ async function getAutogeneratedTagSidebarItems(
items.push( items.push(
...parsedTags ...parsedTags
.filter((tagItem) => { .filter((tagItem) => {
return existingChildren?.every((existingItem) => { return existingChildren
? existingChildren.every((existingItem) => {
if (existingItem.type !== "link" && existingItem.type !== "ref") { if (existingItem.type !== "link" && existingItem.type !== "ref") {
return true return true
} }
return existingItem.path !== tagItem.path return existingItem.path !== tagItem.path
}) })
: true
}) })
.map( .map(
(tagItem) => (tagItem) =>
@@ -122,10 +123,12 @@ async function getAutogeneratedTagSidebarItems(
) )
) )
return sidebarAttachHrefCommonOptions([...(existingChildren || []), ...items]) return sidebarAttachCommonOptions([...(existingChildren || []), ...items])
} }
async function checkItem(item: RawSidebarItem): Promise<RawSidebarItem> { async function checkItem(
item: Sidebar.RawSidebarItem
): Promise<Sidebar.RawSidebarItem> {
if (!item.type) { if (!item.type) {
throw new Error( throw new Error(
`ERROR: The following item doesn't have a type: ${JSON.stringify( `ERROR: The following item doesn't have a type: ${JSON.stringify(
@@ -138,14 +141,26 @@ async function checkItem(item: RawSidebarItem): Promise<RawSidebarItem> {
if (item.type === "separator") { if (item.type === "separator") {
return item return item
} }
if (item.type === "sidebar" && !item.sidebar_id) {
throw new Error(
`ERROR: The following sidebar item doesn't have a sidebar_id: ${JSON.stringify(
item,
undefined,
2
)}`
)
}
if (item.autogenerate_path) { if (item.autogenerate_path) {
item.children = ( item.children = [
await getAutogeneratedSidebarItems(item.autogenerate_path) ...(item.children || []),
).map((child) => { ...(await getAutogeneratedSidebarItems(item.autogenerate_path)).map(
(child) => {
delete child.sidebar_position delete child.sidebar_position
return child return child
}) }
),
]
} else if (item.autogenerate_tags) { } else if (item.autogenerate_tags) {
item.children = await getAutogeneratedTagSidebarItems( item.children = await getAutogeneratedTagSidebarItems(
item.autogenerate_tags, item.autogenerate_tags,
@@ -156,13 +171,16 @@ async function checkItem(item: RawSidebarItem): Promise<RawSidebarItem> {
item.custom_autogenerate && item.custom_autogenerate &&
Object.hasOwn(customGenerators, item.custom_autogenerate) Object.hasOwn(customGenerators, item.custom_autogenerate)
) { ) {
item.children = await customGenerators[item.custom_autogenerate]() item.children = [
...(item.children || []),
...(await customGenerators[item.custom_autogenerate]()),
]
} else if (item.children) { } else if (item.children) {
item.children = await checkItems(item.children) item.children = await checkItems(item.children)
} }
item.children = sortSidebarItems({ item.children = sortSidebarItems({
items: item.children as RawSidebarItem[], items: item.children as Sidebar.RawSidebarItem[],
type: item.sort_sidebar, type: item.sort_sidebar,
}) })
@@ -170,10 +188,10 @@ async function checkItem(item: RawSidebarItem): Promise<RawSidebarItem> {
} }
async function checkItems( async function checkItems(
items: RawSidebarItem[], items: Sidebar.RawSidebarItem[],
options?: GenerateSidebarOptions options?: GenerateSidebarOptions
): Promise<RawSidebarItem[]> { ): Promise<Sidebar.RawSidebarItem[]> {
const updatedItems = ( let updatedItems = (
await Promise.all(items.map(async (item) => await checkItem(item))) await Promise.all(items.map(async (item) => await checkItem(item)))
).filter((item) => { ).filter((item) => {
if (item.type !== "category" && item.type !== "sub-category") { if (item.type !== "category" && item.type !== "sub-category") {
@@ -184,20 +202,29 @@ async function checkItems(
}) })
if (options?.addNumbering) { if (options?.addNumbering) {
return numberSidebarItems(updatedItems) updatedItems = numberSidebarItems(updatedItems)
} }
return updatedItems return sidebarAttachCommonOptions(updatedItems)
} }
export async function generateSidebar( export async function generateSidebar(
sidebar: RawSidebarItem[], sidebars: Sidebar.RawSidebar[],
options?: GenerateSidebarOptions options?: GenerateSidebarOptions
): Promise<void> { ): Promise<void> {
const path = await import("path") const path = await import("path")
const { writeFileSync } = await import("fs") const { writeFileSync } = await import("fs")
const normalizedSidebar = await checkItems(sidebar, options) const normalizedSidebars: Sidebar.RawSidebar[] = []
validateSidebarUniqueIds(sidebars)
for (const sidebarItem of sidebars) {
normalizedSidebars.push({
...sidebarItem,
items: await checkItems(sidebarItem.items, options),
})
}
const generatedDirPath = path.resolve("generated") const generatedDirPath = path.resolve("generated")
@@ -208,8 +235,8 @@ export async function generateSidebar(
// write normalized sidebar // write normalized sidebar
writeFileSync( writeFileSync(
path.resolve(generatedDirPath, "sidebar.mjs"), path.resolve(generatedDirPath, "sidebar.mjs"),
`export const generatedSidebar = ${JSON.stringify( `export const generatedSidebars = ${JSON.stringify(
normalizedSidebar, normalizedSidebars,
null, null,
2 2
)}`, )}`,
@@ -1,6 +1,6 @@
import { getFrontMatter, findPageTitle } from "docs-utils" import { getFrontMatter, findPageTitle } from "docs-utils"
import { ItemsToAdd, sidebarAttachHrefCommonOptions } from "../index.js" import { ItemsToAdd, sidebarAttachCommonOptions } from "../index.js"
import { InteractiveSidebarItem } from "types" import { Sidebar } from "types"
export async function getSidebarItemLink({ export async function getSidebarItemLink({
filePath, filePath,
@@ -16,7 +16,7 @@ export async function getSidebarItemLink({
return return
} }
const newItem = sidebarAttachHrefCommonOptions([ const newItem = sidebarAttachCommonOptions([
{ {
type: "link", type: "link",
path: path:
@@ -25,7 +25,7 @@ export async function getSidebarItemLink({
title: frontmatter.sidebar_label || findPageTitle(filePath) || "", title: frontmatter.sidebar_label || findPageTitle(filePath) || "",
description: frontmatter.sidebar_description || "", description: frontmatter.sidebar_description || "",
}, },
])[0] as InteractiveSidebarItem ])[0] as Sidebar.InteractiveSidebarItem
return { return {
...newItem, ...newItem,
@@ -1,15 +1,15 @@
import { InteractiveSidebarItem, SidebarItem, SidebarItemCategory } from "types" import { Sidebar } from "types"
export default function numberSidebarItems( export default function numberSidebarItems(
sidebarItems: SidebarItem[], sidebarItems: Sidebar.SidebarItem[],
numbering = [1] numbering = [1]
): SidebarItem[] { ): Sidebar.SidebarItem[] {
if (!numbering.length) { if (!numbering.length) {
numbering.push(1) numbering.push(1)
} }
const isTopItems = numbering.length === 1 const isTopItems = numbering.length === 1
const numberedItems: SidebarItem[] = [] const numberedItems: Sidebar.SidebarItem[] = []
let parentItem: InteractiveSidebarItem | undefined let parentItem: Sidebar.InteractiveSidebarItem | undefined
sidebarItems.forEach((item) => { sidebarItems.forEach((item) => {
if (item.type === "separator") { if (item.type === "separator") {
;(parentItem?.children || numberedItems).push(item) ;(parentItem?.children || numberedItems).push(item)
@@ -29,6 +29,7 @@ export default function numberSidebarItems(
numberedItems.push( numberedItems.push(
item.type === "category" item.type === "category"
? { ? {
initialOpen: false,
...item, ...item,
title: item.chapterTitle, title: item.chapterTitle,
} }
@@ -43,7 +44,7 @@ export default function numberSidebarItems(
parentItem = numberedItems[ parentItem = numberedItems[
numberedItems.length - 1 numberedItems.length - 1
] as SidebarItemCategory ] as Sidebar.SidebarItemCategory
} }
if (item.children) { if (item.children) {
@@ -1,13 +1,13 @@
import { RawSidebarItem } from "types" import { Sidebar } from "types"
const commonOptions: Partial<RawSidebarItem> = { const commonOptions: Partial<Sidebar.RawSidebarItem> = {
loaded: true, loaded: true,
isPathHref: true, isPathHref: true,
} }
export function sidebarAttachHrefCommonOptions( export function sidebarAttachCommonOptions(
sidebar: RawSidebarItem[] sidebar: Sidebar.RawSidebarItem[]
): RawSidebarItem[] { ): Sidebar.RawSidebarItem[] {
return sidebar.map((item) => { return sidebar.map((item) => {
if (item.type === "separator") { if (item.type === "separator") {
return item return item
@@ -16,7 +16,7 @@ export function sidebarAttachHrefCommonOptions(
return { return {
...commonOptions, ...commonOptions,
...item, ...item,
children: sidebarAttachHrefCommonOptions(item.children || []), children: sidebarAttachCommonOptions(item.children || []),
} }
}) })
} }
@@ -1,14 +1,14 @@
import { InteractiveSidebarItem, RawSidebarItem, SidebarSortType } from "types" import { Sidebar } from "types"
type Options = { type Options = {
items: RawSidebarItem[] items: Sidebar.RawSidebarItem[]
type?: SidebarSortType type?: Sidebar.SidebarSortType
} }
export const sortSidebarItems = ({ export const sortSidebarItems = ({
items, items,
type = "none", type = "none",
}: Options): RawSidebarItem[] => { }: Options): Sidebar.RawSidebarItem[] => {
switch (type) { switch (type) {
case "alphabetize": case "alphabetize":
return alphabetizeSidebarItems(items) return alphabetizeSidebarItems(items)
@@ -17,9 +17,11 @@ export const sortSidebarItems = ({
} }
} }
const alphabetizeSidebarItems = (items: RawSidebarItem[]): RawSidebarItem[] => { const alphabetizeSidebarItems = (
const segments: RawSidebarItem[][] = [] items: Sidebar.RawSidebarItem[]
let currentSegment: RawSidebarItem[] = [] ): Sidebar.RawSidebarItem[] => {
const segments: Sidebar.RawSidebarItem[][] = []
let currentSegment: Sidebar.RawSidebarItem[] = []
items.forEach((item) => { items.forEach((item) => {
if (item.type === "separator") { if (item.type === "separator") {
@@ -41,7 +43,7 @@ const alphabetizeSidebarItems = (items: RawSidebarItem[]): RawSidebarItem[] => {
.map((segment) => { .map((segment) => {
return segment[0].type === "separator" return segment[0].type === "separator"
? segment ? segment
: (segment as InteractiveSidebarItem[]).sort((a, b) => : (segment as Sidebar.InteractiveSidebarItem[]).sort((a, b) =>
a.title.localeCompare(b.title) a.title.localeCompare(b.title)
) )
}) })
@@ -0,0 +1,22 @@
import { Sidebar } from "types"
export const validateSidebarUniqueIds = (
sidebars: (Sidebar.RawSidebar | Sidebar.SidebarItemSidebar)[],
sidebarIds = new Set<string>()
): void => {
for (const sidebar of sidebars) {
if (sidebarIds.has(sidebar.sidebar_id)) {
throw new Error(`Duplicate sidebar item id found: ${sidebar.sidebar_id}`)
}
sidebarIds.add(sidebar.sidebar_id)
const children = (
"items" in sidebar ? sidebar.items : sidebar.children || []
).filter(
(child) => child.type === "sidebar"
) as Sidebar.SidebarItemSidebar[]
validateSidebarUniqueIds(children, sidebarIds)
}
}
@@ -3,94 +3,53 @@
import React, { useMemo } from "react" import React, { useMemo } from "react"
import clsx from "clsx" import clsx from "clsx"
import Link from "next/link" import Link from "next/link"
import { SidebarItemLink } from "types" import { useSidebar, useSiteConfig } from "../../providers"
import {
CurrentItemsState,
isSidebarItemLink,
useSidebar,
useSiteConfig,
} from "../../providers"
import { Button } from "../Button" import { Button } from "../Button"
import { TriangleRightMini } from "@medusajs/icons" import { TriangleRightMini } from "@medusajs/icons"
import { Sidebar } from "types"
type BreadcrumbItems = {
title: string
link: string
}[]
export const Breadcrumbs = () => { export const Breadcrumbs = () => {
const { currentItems, activeItem: sidebarActiveItem } = useSidebar() const { sidebarHistory, getSidebarFirstLinkChild, getSidebar } = useSidebar()
const { const {
config: { breadcrumbOptions, project, baseUrl, basePath }, config: { breadcrumbOptions },
} = useSiteConfig() } = useSiteConfig()
const getLinkPath = (item?: SidebarItemLink): string | undefined => { const getLinkPath = (item: Sidebar.SidebarItemLink): string => {
if (!item) {
return
}
return item.isPathHref ? item.path : `#${item.path}` return item.isPathHref ? item.path : `#${item.path}`
} }
const getBreadcrumbsOfItem = (
item: CurrentItemsState
): Map<string, string> => {
let tempBreadcrumbItems: Map<string, string> = new Map()
if (item.previousSidebar) {
tempBreadcrumbItems = getBreadcrumbsOfItem(item.previousSidebar)
}
const parentPath = isSidebarItemLink(item.parentItem)
? getLinkPath(item.parentItem)
: (item.parentItem?.type === "category" &&
breadcrumbOptions?.showCategories) ||
item.parentItem?.type === "sub-category"
? "#"
: undefined
const firstItemPath = isSidebarItemLink(item.default[0])
? getLinkPath(item.default[0])
: (item.default[0].type === "category" &&
breadcrumbOptions?.showCategories) ||
item.default[0].type === "sub-category"
? "#"
: undefined
const breadcrumbPath = parentPath || firstItemPath || "/"
tempBreadcrumbItems.set(
breadcrumbPath,
item.parentItem?.childSidebarTitle ||
item.parentItem?.chapterTitle ||
item.parentItem?.title ||
""
)
return tempBreadcrumbItems
}
const breadcrumbItems = useMemo(() => { const breadcrumbItems = useMemo(() => {
const tempBreadcrumbItems: Map<string, string> = new Map() const items: BreadcrumbItems = []
tempBreadcrumbItems.set(`${baseUrl}${basePath}`, project.title) if (breadcrumbOptions?.startItems) {
items.push(...breadcrumbOptions.startItems)
if (currentItems) {
getBreadcrumbsOfItem(currentItems).forEach((value, key) =>
tempBreadcrumbItems.set(key, value)
)
} }
if (sidebarActiveItem) { sidebarHistory.forEach((sidebar_id) => {
if ( const sidebar = getSidebar(sidebar_id)
sidebarActiveItem.parentItem &&
(sidebarActiveItem.parentItem.type !== "category" || if (!sidebar) {
breadcrumbOptions?.showCategories) return
) {
tempBreadcrumbItems.set(
isSidebarItemLink(sidebarActiveItem.parentItem)
? getLinkPath(sidebarActiveItem.parentItem) || "#"
: "#",
sidebarActiveItem.parentItem.chapterTitle ||
sidebarActiveItem.parentItem.title ||
""
)
}
} }
return tempBreadcrumbItems const sidebarFirstChild = getSidebarFirstLinkChild(sidebar)
}, [currentItems, sidebarActiveItem, breadcrumbOptions])
if (!sidebarFirstChild) {
return
}
items.push({
title: sidebar.title,
link: getLinkPath(sidebarFirstChild),
})
})
return items
}, [sidebarHistory, breadcrumbOptions])
return ( return (
<div <div
@@ -100,7 +59,7 @@ export const Breadcrumbs = () => {
"mb-docs_1 flex-wrap" "mb-docs_1 flex-wrap"
)} )}
> >
{Array.from(breadcrumbItems).map(([link, title], index) => ( {breadcrumbItems.map(({ title, link }, index) => (
<React.Fragment key={link}> <React.Fragment key={link}>
{index > 0 && <TriangleRightMini />} {index > 0 && <TriangleRightMini />}
<Button <Button
@@ -1,17 +1,26 @@
"use client" "use client"
import React from "react" import React, { useMemo } from "react"
import clsx from "clsx" import clsx from "clsx"
import { InteractiveSidebarItem } from "types"
import { ArrowUturnLeft } from "@medusajs/icons" import { ArrowUturnLeft } from "@medusajs/icons"
import { useSidebar } from "../../.." import { useSidebar } from "../../../providers"
type SidebarTitleProps = { export const SidebarChild = () => {
item: InteractiveSidebarItem const { goBack, shownSidebar } = useSidebar()
const title = useMemo(() => {
if (!shownSidebar) {
return ""
} }
export const SidebarChild = ({ item }: SidebarTitleProps) => { return "childSidebarTitle" in shownSidebar
const { goBack } = useSidebar() ? shownSidebar.childSidebarTitle || shownSidebar.title
: shownSidebar.title
}, [shownSidebar])
if (!shownSidebar) {
return <></>
}
return ( return (
<div className="px-docs_0.75"> <div className="px-docs_0.75">
@@ -25,9 +34,7 @@ export const SidebarChild = ({ item }: SidebarTitleProps) => {
tabIndex={-1} tabIndex={-1}
> >
<ArrowUturnLeft /> <ArrowUturnLeft />
<span className="truncate flex-1"> <span className="truncate flex-1">{title}</span>
{item.childSidebarTitle || item.title}
</span>
</div> </div>
</div> </div>
) )
@@ -3,34 +3,37 @@
// @refresh reset // @refresh reset
import React, { useEffect, useMemo, useState } from "react" import React, { useEffect, useMemo, useState } from "react"
import { SidebarItemCategory as SidebarItemCategoryType } from "types" import { Sidebar } from "types"
import { Loading, SidebarItem, useSidebar } from "../../../.." import { Loading, SidebarItem, useSidebar } from "../../../.."
import clsx from "clsx" import clsx from "clsx"
import { MinusMini, PlusMini } from "@medusajs/icons" import { MinusMini, PlusMini } from "@medusajs/icons"
export type SidebarItemCategory = { export type SidebarItemCategoryProps = {
item: SidebarItemCategoryType item: Sidebar.SidebarItemCategory
expandItems?: boolean
} & React.AllHTMLAttributes<HTMLDivElement> } & React.AllHTMLAttributes<HTMLDivElement>
export const SidebarItemCategory = ({ export const SidebarItemCategory = ({
item, item,
expandItems = true,
className, className,
}: SidebarItemCategory) => { }: SidebarItemCategoryProps) => {
const [showLoading, setShowLoading] = useState(false) const [showLoading, setShowLoading] = useState(false)
const [open, setOpen] = useState( const [open, setOpen] = useState(
item.initialOpen !== undefined ? item.initialOpen : expandItems item.initialOpen !== undefined ? item.initialOpen : true
) )
const { const {
isChildrenActive, isItemActive,
updatePersistedCategoryState, updatePersistedCategoryState,
getPersistedCategoryState, getPersistedCategoryState,
persistState, persistCategoryState,
} = useSidebar() } = useSidebar()
const itemShowLoading = useMemo(() => { const itemShowLoading = useMemo(() => {
return !item.loaded || (item.showLoadingIfEmpty && !item.children?.length) return !item.loaded || (item.showLoadingIfEmpty && !item.children?.length)
}, [item]) }, [item])
const isActive = useMemo(() => {
return isItemActive({
item,
})
}, [isItemActive, item])
useEffect(() => { useEffect(() => {
if (open && itemShowLoading) { if (open && itemShowLoading) {
@@ -45,22 +48,20 @@ export const SidebarItemCategory = ({
}, [itemShowLoading, showLoading]) }, [itemShowLoading, showLoading])
useEffect(() => { useEffect(() => {
const isActive = isChildrenActive(item)
if (isActive && !open) { if (isActive && !open) {
setOpen(true) setOpen(true)
} }
}, [isChildrenActive, item.children]) }, [isActive, item.children])
useEffect(() => { useEffect(() => {
if (!persistState) { if (!persistCategoryState) {
return return
} }
const persistedOpen = getPersistedCategoryState(item.title) const persistedOpen = getPersistedCategoryState(item.title)
if (persistedOpen !== undefined) { if (persistedOpen !== undefined && !isActive) {
setOpen(persistedOpen) setOpen(persistedOpen)
} }
}, [persistState]) }, [persistCategoryState])
const handleOpen = () => { const handleOpen = () => {
item.onOpen?.() item.onOpen?.()
@@ -90,7 +91,7 @@ export const SidebarItemCategory = ({
if (!open) { if (!open) {
handleOpen() handleOpen()
} }
if (persistState) { if (persistCategoryState) {
updatePersistedCategoryState(item.title, !open) updatePersistedCategoryState(item.title, !open)
} }
setOpen((prev) => !prev) setOpen((prev) => !prev)
@@ -133,7 +134,7 @@ export const SidebarItemCategory = ({
<SidebarItem <SidebarItem
item={childItem} item={childItem}
key={index} key={index}
expandItems={expandItems} isParentCategoryOpen={open}
/> />
))} ))}
</ul> </ul>
@@ -2,8 +2,8 @@
// @refresh reset // @refresh reset
import React, { useEffect, useMemo, useRef } from "react" import React, { useCallback, useEffect, useMemo, useRef } from "react"
import { SidebarItemLink as SidebarItemlinkType } from "types" import { Sidebar } from "types"
import { import {
checkSidebarItemVisibility, checkSidebarItemVisibility,
SidebarItem, SidebarItem,
@@ -14,27 +14,36 @@ import clsx from "clsx"
import Link from "next/link" import Link from "next/link"
export type SidebarItemLinkProps = { export type SidebarItemLinkProps = {
item: SidebarItemlinkType item: Sidebar.SidebarItemLink
nested?: boolean nested?: boolean
isParentCategoryOpen?: boolean
} & React.AllHTMLAttributes<HTMLLIElement> } & React.AllHTMLAttributes<HTMLLIElement>
export const SidebarItemLink = ({ export const SidebarItemLink = ({
item, item,
className, className,
nested = false, nested = false,
isParentCategoryOpen,
}: SidebarItemLinkProps) => { }: SidebarItemLinkProps) => {
const { const {
isLinkActive, isItemActive,
setMobileSidebarOpen: setSidebarOpen, setMobileSidebarOpen: setSidebarOpen,
disableActiveTransition, disableActiveTransition,
sidebarRef, sidebarRef,
sidebarTopHeight, sidebarTopHeight,
} = useSidebar() } = useSidebar()
const { isMobile } = useMobile() const { isMobile } = useMobile()
const active = useMemo(() => isLinkActive(item, true), [isLinkActive, item]) const active = useMemo(
() =>
isItemActive({
item,
checkLinkChildren: false,
}),
[isItemActive, item]
)
const ref = useRef<HTMLLIElement>(null) const ref = useRef<HTMLLIElement>(null)
const newTopCalculator = useMemo(() => { const getNewTopCalculator = useCallback(() => {
if (!sidebarRef.current || !ref.current) { if (!sidebarRef.current || !ref.current) {
return 0 return 0
} }
@@ -48,10 +57,19 @@ export const SidebarItemLink = ({
sidebarRef.current.scrollTop - sidebarRef.current.scrollTop -
10 // remove extra margin just in case 10 // remove extra margin just in case
) )
}, [sidebarTopHeight, sidebarRef, ref]) }, [sidebarTopHeight, sidebarRef.current, ref.current])
useEffect(() => { useEffect(() => {
if (active && ref.current && sidebarRef.current && !isMobile) { if (
!active ||
!ref.current ||
!sidebarRef.current ||
isMobile ||
!isParentCategoryOpen
) {
return
}
const isVisible = checkSidebarItemVisibility( const isVisible = checkSidebarItemVisibility(
(ref.current.children.item(0) as HTMLElement) || ref.current, (ref.current.children.item(0) as HTMLElement) || ref.current,
!disableActiveTransition !disableActiveTransition
@@ -65,16 +83,17 @@ export const SidebarItemLink = ({
}) })
} else { } else {
sidebarRef.current.scrollTo({ sidebarRef.current.scrollTo({
top: newTopCalculator, top: getNewTopCalculator(),
}) })
} }
}
}, [ }, [
active, active,
sidebarRef.current, sidebarRef.current,
disableActiveTransition, disableActiveTransition,
isMobile, isMobile,
newTopCalculator, ref.current,
getNewTopCalculator,
isParentCategoryOpen,
]) ])
useEffect(() => { useEffect(() => {
@@ -84,11 +103,7 @@ export const SidebarItemLink = ({
}, [active, isMobile]) }, [active, isMobile])
const hasChildren = useMemo(() => { const hasChildren = useMemo(() => {
return ( return !item.hideChildren && (item.children?.length || 0) > 0
!item.isChildSidebar &&
!item.hideChildren &&
(item.children?.length || 0) > 0
)
}, [item.children]) }, [item.children])
const isTitleOneWord = useMemo( const isTitleOneWord = useMemo(
@@ -147,6 +162,7 @@ export const SidebarItemLink = ({
item={childItem} item={childItem}
key={index} key={index}
nested={!item.childrenSameLevel} nested={!item.childrenSameLevel}
isParentCategoryOpen={isParentCategoryOpen}
/> />
))} ))}
</ul> </ul>
@@ -0,0 +1,63 @@
"use client"
// @refresh reset
import React, { useMemo } from "react"
import { Sidebar } from "types"
import { useSidebar } from "../../../.."
import clsx from "clsx"
import Link from "next/link"
export type SidebarItemSidebarProps = {
item: Sidebar.SidebarItemSidebar
nested?: boolean
} & React.AllHTMLAttributes<HTMLLIElement>
export const SidebarItemSidebar = ({
item,
className,
nested = false,
}: SidebarItemSidebarProps) => {
const { getSidebarFirstLinkChild: getSidebarFirstChild } = useSidebar()
const isTitleOneWord = useMemo(
() => item.title.split(" ").length === 1,
[item.title]
)
const firstChild = useMemo(() => getSidebarFirstChild(item), [item])
return (
<li>
<span className="block px-docs_0.75">
<Link
href={
firstChild?.isPathHref ? firstChild.path : `#${firstChild?.path}`
}
className={clsx(
"py-docs_0.25 px-docs_0.5",
"block w-full rounded-docs_sm",
!isTitleOneWord && "break-words",
!nested && "text-medusa-fg-subtle",
nested && "text-medusa-fg-muted",
"hover:bg-medusa-bg-base-hover lg:hover:bg-medusa-bg-subtle-hover",
"text-compact-small-plus",
"flex justify-between items-center gap-[6px]",
className
)}
{...firstChild?.linkProps}
>
<span
className={clsx(
isTitleOneWord && "truncate",
nested && "inline-block pl-docs_1.5"
)}
>
{item.title}
</span>
{item.additionalElms}
</Link>
</span>
</li>
)
}
@@ -2,90 +2,25 @@
// @refresh reset // @refresh reset
import React, { useEffect, useMemo, useRef } from "react" import React, { useMemo, useRef } from "react"
import { SidebarItemSubCategory as SidebarItemSubCategoryType } from "types" import { Sidebar } from "types"
import { import { SidebarItem } from "../../../.."
checkSidebarItemVisibility,
SidebarItem,
useMobile,
useSidebar,
} from "../../../.."
import clsx from "clsx" import clsx from "clsx"
export type SidebarItemLinkProps = { export type SidebarItemSubCategoryProps = {
item: SidebarItemSubCategoryType item: Sidebar.SidebarItemSubCategory
nested?: boolean nested?: boolean
isParentCategoryOpen?: boolean
} & React.AllHTMLAttributes<HTMLLIElement> } & React.AllHTMLAttributes<HTMLLIElement>
export const SidebarItemSubCategory = ({ export const SidebarItemSubCategory = ({
item, item,
className, className,
nested = false, nested = false,
}: SidebarItemLinkProps) => { isParentCategoryOpen,
const { isLinkActive, disableActiveTransition, sidebarRef } = useSidebar() }: SidebarItemSubCategoryProps) => {
const { isMobile } = useMobile()
const active = useMemo(
() => !isMobile && isLinkActive(item, true),
[isLinkActive, item, isMobile]
)
const ref = useRef<HTMLLIElement>(null) const ref = useRef<HTMLLIElement>(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(() => { const hasChildren = useMemo(() => {
return !item.hideChildren && (item.children?.length || 0) > 0 return !item.hideChildren && (item.children?.length || 0) > 0
}, [item.children]) }, [item.children])
@@ -103,15 +38,8 @@ export const SidebarItemSubCategory = ({
"py-docs_0.25 px-docs_0.5", "py-docs_0.25 px-docs_0.5",
"block w-full", "block w-full",
!isTitleOneWord && "break-words", !isTitleOneWord && "break-words",
active && [
"rounded-docs_sm",
"shadow-borders-base dark:shadow-borders-base-dark",
"text-medusa-fg-base",
],
!active && [
!nested && "text-medusa-fg-subtle", !nested && "text-medusa-fg-subtle",
nested && "text-medusa-fg-muted", nested && "text-medusa-fg-muted",
],
"text-compact-small-plus", "text-compact-small-plus",
className className
)} )}
@@ -140,6 +68,7 @@ export const SidebarItemSubCategory = ({
item={childItem} item={childItem}
key={index} key={index}
nested={!item.childrenSameLevel} nested={!item.childrenSameLevel}
isParentCategoryOpen={isParentCategoryOpen}
/> />
))} ))}
</ul> </ul>
@@ -1,17 +1,18 @@
"use client" "use client"
import React from "react" import React from "react"
import { SidebarItem as SidebarItemType } from "types" import { Sidebar } from "types"
import { SidebarItemCategory } from "./Category"
import { SidebarItemLink } from "./Link" import { SidebarItemLink } from "./Link"
import { SidebarItemSubCategory } from "./SubCategory" import { SidebarItemSubCategory } from "./SubCategory"
import { DottedSeparator } from "../.." import { DottedSeparator } from "../.."
import { SidebarItemCategory } from "./Category"
import { SidebarItemSidebar } from "./Sidebar"
export type SidebarItemProps = { export type SidebarItemProps = {
item: SidebarItemType item: Sidebar.SidebarItem
nested?: boolean nested?: boolean
expandItems?: boolean
hasNextItems?: boolean hasNextItems?: boolean
isParentCategoryOpen?: boolean
} & React.AllHTMLAttributes<HTMLElement> } & React.AllHTMLAttributes<HTMLElement>
export const SidebarItem = ({ export const SidebarItem = ({
@@ -33,6 +34,8 @@ export const SidebarItem = ({
case "ref": case "ref":
case "external": case "external":
return <SidebarItemLink item={item} {...props} /> return <SidebarItemLink item={item} {...props} />
case "sidebar":
return <SidebarItemSidebar item={item} {...props} />
case "separator": case "separator":
return <DottedSeparator /> return <DottedSeparator />
} }
@@ -2,17 +2,14 @@
import React from "react" import React from "react"
import { SidebarChild } from "../Child" import { SidebarChild } from "../Child"
import { InteractiveSidebarItem } from "types"
import { SidebarTopMobileClose } from "./MobileClose" import { SidebarTopMobileClose } from "./MobileClose"
import { DottedSeparator } from "../../.." import { DottedSeparator, useSidebar } from "../../.."
import clsx from "clsx" import clsx from "clsx"
export type SidebarTopProps = { export const SidebarTop = React.forwardRef<HTMLDivElement>(
parentItem?: InteractiveSidebarItem function SidebarTop(props, ref) {
} const { sidebarHistory } = useSidebar()
export const SidebarTop = React.forwardRef<HTMLDivElement, SidebarTopProps>(
function SidebarTop({ parentItem }, ref) {
return ( return (
<div <div
className={clsx( className={clsx(
@@ -23,9 +20,9 @@ export const SidebarTop = React.forwardRef<HTMLDivElement, SidebarTopProps>(
> >
<SidebarTopMobileClose /> <SidebarTopMobileClose />
<div> <div>
{parentItem && ( {sidebarHistory.length > 1 && (
<> <>
<SidebarChild item={parentItem} /> <SidebarChild />
<DottedSeparator wrapperClassName="!my-0" /> <DottedSeparator wrapperClassName="!my-0" />
</> </>
)} )}
@@ -1,39 +1,35 @@
"use client" "use client"
import React, { Suspense, useMemo, useRef } from "react" import React, { Suspense, useMemo, useRef } from "react"
import { isSidebarItemLink, useSidebar } from "@/providers" import { useSidebar } from "@/providers"
import clsx from "clsx" import clsx from "clsx"
import { Loading } from "@/components" import { Loading } from "@/components"
import { SidebarItem } from "./Item" import { SidebarItem } from "./Item"
// @ts-expect-error can't install the types package because it doesn't support React v19 // @ts-expect-error can't install the types package because it doesn't support React v19
import { CSSTransition, SwitchTransition } from "react-transition-group" import { CSSTransition, SwitchTransition } from "react-transition-group"
import { SidebarTop, SidebarTopProps } from "./Top" import { SidebarTop } from "./Top"
import { useClickOutside, useKeyboardShortcut } from "@/hooks" import { useClickOutside, useKeyboardShortcut } from "@/hooks"
import useResizeObserver from "@react-hook/resize-observer" import useResizeObserver from "@react-hook/resize-observer"
import { isSidebarItemLink } from "../../utils/sidebar-utils"
export type SidebarProps = { export type SidebarProps = {
className?: string className?: string
expandItems?: boolean
sidebarTopProps?: Omit<SidebarTopProps, "parentItem">
} }
export const Sidebar = ({ export const Sidebar = ({ className = "" }: SidebarProps) => {
className = "",
expandItems = true,
sidebarTopProps,
}: SidebarProps) => {
const sidebarWrapperRef = useRef(null) const sidebarWrapperRef = useRef(null)
const sidebarTopRef = useRef<HTMLDivElement>(null) const sidebarTopRef = useRef<HTMLDivElement>(null)
const { const {
items, sidebars,
currentItems, shownSidebar,
mobileSidebarOpen, mobileSidebarOpen,
setMobileSidebarOpen, setMobileSidebarOpen,
staticSidebarItems, isSidebarStatic,
sidebarRef, sidebarRef,
desktopSidebarOpen, desktopSidebarOpen,
setDesktopSidebarOpen, setDesktopSidebarOpen,
setSidebarTopHeight, setSidebarTopHeight,
sidebarHistory,
} = useSidebar() } = useSidebar()
useClickOutside({ useClickOutside({
elmRef: sidebarWrapperRef, elmRef: sidebarWrapperRef,
@@ -51,15 +47,16 @@ export const Sidebar = ({
}, },
}) })
const sidebarItems = useMemo(
() => currentItems || items,
[items, currentItems]
)
useResizeObserver(sidebarTopRef as React.RefObject<HTMLElement>, () => { useResizeObserver(sidebarTopRef as React.RefObject<HTMLElement>, () => {
setSidebarTopHeight(sidebarTopRef.current?.clientHeight || 0) setSidebarTopHeight(sidebarTopRef.current?.clientHeight || 0)
}) })
const sidebarItems = useMemo(() => {
return shownSidebar && "items" in shownSidebar
? shownSidebar.items
: shownSidebar?.children || []
}, [shownSidebar])
return ( return (
<> <>
{mobileSidebarOpen && ( {mobileSidebarOpen && (
@@ -94,7 +91,11 @@ export const Sidebar = ({
<ul className={clsx("h-full w-full", "flex flex-col")}> <ul className={clsx("h-full w-full", "flex flex-col")}>
<SwitchTransition> <SwitchTransition>
<CSSTransition <CSSTransition
key={sidebarItems.parentItem?.title || "home"} key={
sidebarHistory.length
? sidebarHistory[sidebarHistory.length - 1]
: sidebars[0].sidebar_id
}
nodeRef={sidebarRef} nodeRef={sidebarRef}
classNames={{ classNames={{
enter: "animate-fadeInLeft animate-fast", enter: "animate-fadeInLeft animate-fast",
@@ -110,32 +111,12 @@ export const Sidebar = ({
ref={sidebarRef} ref={sidebarRef}
id="sidebar" id="sidebar"
> >
<SidebarTop <SidebarTop ref={sidebarTopRef} />
{...sidebarTopProps}
parentItem={sidebarItems.parentItem}
ref={sidebarTopRef}
/>
{/* MOBILE SIDEBAR - keeping this in case we need it in the future */}
{/* <div className={clsx("lg:hidden")}>
{!sidebarItems.mobile.length && !staticSidebarItems && (
<Loading className="px-0" />
)}
{sidebarItems.mobile.map((item, index) => (
<SidebarItem
item={item}
key={index}
expandItems={expandItems}
hasNextItems={index !== sidebarItems.default.length - 1}
/>
))}
{sidebarItems.mobile.length > 0 && <DottedSeparator />}
</div> */}
{/* DESKTOP SIDEBAR */}
<div className="pt-docs_0.75"> <div className="pt-docs_0.75">
{!sidebarItems.default.length && !staticSidebarItems && ( {!sidebarItems.length && !isSidebarStatic && (
<Loading className="px-0" /> <Loading className="px-docs_0.75" />
)} )}
{sidebarItems.default.map((item, index) => { {sidebarItems.map((item, index) => {
const itemKey = const itemKey =
item.type === "separator" item.type === "separator"
? index ? index
@@ -155,10 +136,7 @@ export const Sidebar = ({
> >
<SidebarItem <SidebarItem
item={item} item={item}
expandItems={expandItems} hasNextItems={index !== sidebarItems.length - 1}
hasNextItems={
index !== sidebarItems.default.length - 1
}
/> />
</Suspense> </Suspense>
) )
@@ -9,17 +9,17 @@ import {
H3, H3,
H4, H4,
Hr, Hr,
isSidebarItemLink,
LocalSearch, LocalSearch,
MarkdownContent, MarkdownContent,
SearchInput, SearchInput,
useIsBrowser, useIsBrowser,
useSidebar, useSidebar,
} from "../.." } from "../.."
import { InteractiveSidebarItem, SidebarItem, SidebarItemLink } from "types" import { Sidebar } from "types"
import slugify from "slugify" import slugify from "slugify"
import { MDXComponents } from "../.." import { MDXComponents } from "../.."
import { ChevronDoubleRight, ExclamationCircle } from "@medusajs/icons" import { ChevronDoubleRight, ExclamationCircle } from "@medusajs/icons"
import { isSidebarItemLink } from "../../utils/sidebar-utils"
type HeadingComponent = ( type HeadingComponent = (
props: React.HTMLAttributes<HTMLHeadingElement> props: React.HTMLAttributes<HTMLHeadingElement>
@@ -60,11 +60,11 @@ export const useChildDocs = ({
...searchProps ...searchProps
} = { enable: false }, } = { enable: false },
}: UseChildDocsProps) => { }: UseChildDocsProps) => {
const { currentItems, activeItem } = useSidebar() const { shownSidebar, activeItem } = useSidebar()
const { isBrowser } = useIsBrowser() const { isBrowser } = useIsBrowser()
const [searchQuery, setSearchQuery] = useState("") const [searchQuery, setSearchQuery] = useState("")
const [localSearch, setLocalSearch] = useState< const [localSearch, setLocalSearch] = useState<
LocalSearch<SidebarItemLink> | undefined LocalSearch<Sidebar.SidebarItemLink> | undefined
>() >()
const TitleHeaderComponent = useCallback( const TitleHeaderComponent = useCallback(
(level: number): HeadingComponent => { (level: number): HeadingComponent => {
@@ -91,7 +91,7 @@ export const useChildDocs = ({
: "all" : "all"
}, [showItems, hideItems]) }, [showItems, hideItems])
const filterCondition = (item: SidebarItem): boolean => { const filterCondition = (item: Sidebar.SidebarItem): boolean => {
if (item.type === "separator") { if (item.type === "separator") {
return false return false
} }
@@ -111,8 +111,10 @@ export const useChildDocs = ({
} }
} }
const filterItems = (items: SidebarItem[]): InteractiveSidebarItem[] => { const filterItems = (
return (items.filter(filterCondition) as InteractiveSidebarItem[]) items: Sidebar.SidebarItem[]
): Sidebar.InteractiveSidebarItem[] => {
return (items.filter(filterCondition) as Sidebar.InteractiveSidebarItem[])
.map((item) => Object.assign({}, item)) .map((item) => Object.assign({}, item))
.map((item) => { .map((item) => {
if (item.children && filterType === "hide") { if (item.children && filterType === "hide") {
@@ -124,19 +126,19 @@ export const useChildDocs = ({
} }
const filterNonInteractiveItems = ( const filterNonInteractiveItems = (
items: SidebarItem[] | undefined items: Sidebar.SidebarItem[] | undefined
): InteractiveSidebarItem[] => { ): Sidebar.InteractiveSidebarItem[] => {
return ( return (
(items?.filter( (items?.filter(
(item) => item.type !== "separator" (item) => item.type !== "separator"
) as InteractiveSidebarItem[]) || [] ) as Sidebar.InteractiveSidebarItem[]) || []
) )
} }
const getChildrenForLevel = ( const getChildrenForLevel = (
item: InteractiveSidebarItem, item: Sidebar.InteractiveSidebarItem,
currentLevel = 1 currentLevel = 1
): InteractiveSidebarItem[] | undefined => { ): Sidebar.InteractiveSidebarItem[] | undefined => {
if (currentLevel === childLevel) { if (currentLevel === childLevel) {
return filterNonInteractiveItems(item.children) return filterNonInteractiveItems(item.children)
} }
@@ -144,7 +146,7 @@ export const useChildDocs = ({
return return
} }
const childrenResult: InteractiveSidebarItem[] = [] const childrenResult: Sidebar.InteractiveSidebarItem[] = []
filterNonInteractiveItems(item.children).forEach((child) => { filterNonInteractiveItems(item.children).forEach((child) => {
const childChildren = getChildrenForLevel(child, currentLevel + 1) const childChildren = getChildrenForLevel(child, currentLevel + 1)
@@ -162,34 +164,24 @@ export const useChildDocs = ({
const filteredItems = useMemo(() => { const filteredItems = useMemo(() => {
let targetItems = let targetItems =
type === "sidebar" type === "sidebar"
? currentItems ? shownSidebar && "items" in shownSidebar
? Object.assign({}, currentItems) ? shownSidebar.items
: undefined : shownSidebar?.children || []
: { : [...(activeItem?.children || [])]
default: [...(activeItem?.children || [])],
}
if (filterType !== "all" && targetItems) { if (filterType !== "all" && targetItems) {
targetItems = { targetItems = filterItems(targetItems)
...targetItems,
default: filterItems(targetItems.default),
}
} }
return targetItems return filterNonInteractiveItems(targetItems)
? { }, [shownSidebar, type, activeItem, filterType])
...targetItems,
default: filterNonInteractiveItems(targetItems?.default),
}
: undefined
}, [currentItems, type, activeItem, filterType])
const searchableItems = useMemo(() => { const searchableItems = useMemo(() => {
const searchableItems: SidebarItemLink[] = [] const searchableItems: Sidebar.SidebarItemLink[] = []
if (!enableSearch) { if (!enableSearch) {
return searchableItems return searchableItems
} }
if (onlyTopLevel) { if (onlyTopLevel) {
filteredItems?.default?.forEach((item) => { filteredItems.forEach((item) => {
if (isSidebarItemLink(item)) { if (isSidebarItemLink(item)) {
searchableItems.push(item) searchableItems.push(item)
} else { } else {
@@ -197,16 +189,16 @@ export const useChildDocs = ({
isSidebarItemLink(child) isSidebarItemLink(child)
) )
if (firstChild) { if (firstChild) {
searchableItems.push(firstChild as SidebarItemLink) searchableItems.push(firstChild as Sidebar.SidebarItemLink)
} }
} }
}) })
} else { } else {
filteredItems?.default?.forEach((item) => { filteredItems?.forEach((item) => {
const childItems: SidebarItemLink[] = const childItems: Sidebar.SidebarItemLink[] =
(getChildrenForLevel(item)?.filter((childItem) => { (getChildrenForLevel(item)?.filter((childItem) => {
return isSidebarItemLink(childItem) return isSidebarItemLink(childItem)
}) as SidebarItemLink[]) || [] }) as Sidebar.SidebarItemLink[]) || []
searchableItems.push(...childItems) searchableItems.push(...childItems)
}) })
} }
@@ -224,7 +216,7 @@ export const useChildDocs = ({
} }
setLocalSearch( setLocalSearch(
getLocalSearch<SidebarItemLink>({ getLocalSearch<Sidebar.SidebarItemLink>({
docs: searchableItems, docs: searchableItems,
searchableFields: ["title", "description"], searchableFields: ["title", "description"],
options: { options: {
@@ -263,7 +255,7 @@ export const useChildDocs = ({
localStorage.setItem(`${storageKey}-query`, searchQuery) localStorage.setItem(`${storageKey}-query`, searchQuery)
}, [isBrowser, searchQuery, storageKey, enableSearch]) }, [isBrowser, searchQuery, storageKey, enableSearch])
const getTopLevelElms = (items?: InteractiveSidebarItem[]) => { const getTopLevelElms = (items?: Sidebar.InteractiveSidebarItem[]) => {
return ( return (
<CardList <CardList
items={ items={
@@ -274,7 +266,7 @@ export const useChildDocs = ({
? ( ? (
childItem.children.find((item) => childItem.children.find((item) =>
isSidebarItemLink(item) isSidebarItemLink(item)
) as SidebarItemLink ) as Sidebar.SidebarItemLink
)?.path )?.path
: "#" : "#"
return { return {
@@ -292,7 +284,7 @@ export const useChildDocs = ({
} }
const getAllLevelsElms = ( const getAllLevelsElms = (
items?: InteractiveSidebarItem[], items?: Sidebar.InteractiveSidebarItem[],
headerLevel = titleLevel headerLevel = titleLevel
) => { ) => {
return items?.map((item, key) => { return items?.map((item, key) => {
@@ -405,8 +397,8 @@ export const useChildDocs = ({
{!searchQuery && ( {!searchQuery && (
<> <>
{onlyTopLevel {onlyTopLevel
? getTopLevelElms(filteredItems?.default) ? getTopLevelElms(filteredItems)
: getAllLevelsElms(filteredItems?.default)} : getAllLevelsElms(filteredItems)}
</> </>
)} )}
</> </>
@@ -1,9 +1,8 @@
"use client" "use client"
import React, { useEffect } from "react" import React, { useEffect } from "react"
import { useSidebar } from "../providers/Sidebar"
import clsx from "clsx" import clsx from "clsx"
import { MainNav, useIsBrowser, useLayout } from ".." import { MainNav, useIsBrowser, useLayout, useSidebar } from ".."
export type MainContentLayoutProps = { export type MainContentLayoutProps = {
mainWrapperClasses?: string mainWrapperClasses?: string
@@ -1,15 +1,10 @@
"use client" "use client"
import React, { import React, { createContext, useContext, useEffect, useState } from "react"
createContext,
useContext,
useEffect,
useMemo,
useState,
} from "react"
import { isSidebarItemLink, useSidebar } from "../Sidebar"
import { usePrevious } from "@uidotdev/usehooks" import { usePrevious } from "@uidotdev/usehooks"
import { InteractiveSidebarItem, SidebarItem } from "types" import { useSidebar } from "../Sidebar"
import { isSidebarItemLink } from "../../utils/sidebar-utils"
import { Sidebar } from "types"
export type Page = { export type Page = {
title: string title: string
@@ -27,8 +22,8 @@ export const PaginationContext = createContext<PaginationContextType | null>(
null null
) )
type SidebarItemWithParent = InteractiveSidebarItem & { type SidebarItemWithParent = Sidebar.InteractiveSidebarItem & {
parent?: SidebarItem parent?: Sidebar.InteractiveSidebarItem
} }
type SearchItemsResult = { type SearchItemsResult = {
@@ -42,14 +37,13 @@ export type PaginationProviderProps = {
} }
export const PaginationProvider = ({ children }: PaginationProviderProps) => { export const PaginationProvider = ({ children }: PaginationProviderProps) => {
const { items, activePath } = useSidebar() const { shownSidebar, activePath } = useSidebar()
const combinedItems = useMemo(() => [...items.default], [items])
const previousActivePath = usePrevious(activePath) const previousActivePath = usePrevious(activePath)
const [nextPage, setNextPage] = useState<Page | undefined>() const [nextPage, setNextPage] = useState<Page | undefined>()
const [prevPage, setPrevPage] = useState<Page | undefined>() const [prevPage, setPrevPage] = useState<Page | undefined>()
const getFirstChild = ( const getFirstChild = (
item: InteractiveSidebarItem item: Sidebar.InteractiveSidebarItem
): SidebarItemWithParent | undefined => { ): SidebarItemWithParent | undefined => {
const children = getChildrenWithPages(item) const children = getChildrenWithPages(item)
if (!children?.length) { if (!children?.length) {
@@ -65,7 +59,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => {
} }
const getChildrenWithPages = ( const getChildrenWithPages = (
item: InteractiveSidebarItem item: Sidebar.InteractiveSidebarItem
): SidebarItemWithParent[] | undefined => { ): SidebarItemWithParent[] | undefined => {
return item.children?.filter( return item.children?.filter(
(childItem) => (childItem) =>
@@ -76,7 +70,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => {
} }
const getPrevItem = ( const getPrevItem = (
items: SidebarItem[], items: Sidebar.SidebarItem[],
index: number index: number
): SidebarItemWithParent | undefined => { ): SidebarItemWithParent | undefined => {
let foundItem: SidebarItemWithParent | undefined let foundItem: SidebarItemWithParent | undefined
@@ -106,7 +100,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => {
} }
const getNextItem = ( const getNextItem = (
items: SidebarItem[], items: Sidebar.SidebarItem[],
index: number index: number
): SidebarItemWithParent | undefined => { ): SidebarItemWithParent | undefined => {
let foundItem: SidebarItemWithParent | undefined let foundItem: SidebarItemWithParent | undefined
@@ -133,7 +127,9 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => {
return foundItem return foundItem
} }
const searchItems = (currentItems: SidebarItem[]): SearchItemsResult => { const searchItems = (
currentItems: Sidebar.SidebarItem[]
): SearchItemsResult => {
const result: SearchItemsResult = { const result: SearchItemsResult = {
foundActive: false, foundActive: false,
} }
@@ -182,7 +178,11 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => {
useEffect(() => { useEffect(() => {
if (activePath !== previousActivePath) { if (activePath !== previousActivePath) {
const result = searchItems(combinedItems) const sidebarItems =
shownSidebar && "items" in shownSidebar
? shownSidebar.items
: shownSidebar?.children || []
const result = searchItems(sidebarItems)
setPrevPage( setPrevPage(
result.prevItem result.prevItem
? { ? {
@@ -190,10 +190,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => {
link: isSidebarItemLink(result.prevItem) link: isSidebarItemLink(result.prevItem)
? result.prevItem.path ? result.prevItem.path
: "", : "",
parentTitle: parentTitle: result.prevItem.parent?.title,
result.prevItem.parent?.type !== "separator"
? result.prevItem.parent?.title
: undefined,
} }
: undefined : undefined
) )
@@ -204,10 +201,7 @@ export const PaginationProvider = ({ children }: PaginationProviderProps) => {
link: isSidebarItemLink(result.nextItem) link: isSidebarItemLink(result.nextItem)
? result.nextItem.path ? result.nextItem.path
: "", : "",
parentTitle: parentTitle: result.nextItem?.parent?.title,
result.nextItem.parent?.type !== "separator"
? result.nextItem.parent?.title
: undefined,
} }
: undefined : undefined
) )
@@ -1,7 +1,6 @@
"use client" "use client"
import React, { import React, {
ReactNode,
createContext, createContext,
useCallback, useCallback,
useContext, useContext,
@@ -11,224 +10,180 @@ import React, {
useRef, useRef,
useState, useState,
} from "react" } from "react"
import { usePathname, useRouter } from "next/navigation" import { Sidebar } from "types"
import { getScrolledTop } from "@/utils"
import { import {
SidebarItemSections, areSidebarItemsEqual,
SidebarItem, findSidebarItem,
SidebarSectionItems, getSidebarItemWithHistory,
SidebarItemLink, isSidebarItemLink,
InteractiveSidebarItem, } from "../../utils/sidebar-utils"
SidebarItemCategory, import { useSiteConfig } from "../SiteConifg"
SidebarItemLinkWithParent,
InteractiveSidebarItemTypes,
} from "types"
import { useIsBrowser } from "../BrowserProvider" import { useIsBrowser } from "../BrowserProvider"
import { getScrolledTop } from "../../utils"
import { usePathname, useRouter } from "next/navigation"
export type CurrentItemsState = SidebarSectionItems & { export type SidebarActionOptions = {
previousSidebar?: CurrentItemsState sidebar_id: string
/**
* When specified, the items are added as children of the parent item
*/
parent?: {
type: Sidebar.InteractiveSidebarItemTypes
path: string
title: string
/**
* Whether to change the loaded state of the parent item
*/
changeLoaded?: boolean
}
/**
* The position to insert the items at
*/
indexPosition?: number
/**
* If enabled, the items are filtered to not add items that already exist
*/
ignoreExisting?: boolean
} }
export type SidebarStyleOptions = { export type SidebarStyleOptions = {
/**
* Useful for projects that have nested sidebars.
*/
disableActiveTransition?: boolean disableActiveTransition?: boolean
} }
export type SidebarContextType = { export type SidebarContextType = {
items: SidebarSectionItems sidebars: Sidebar.Sidebar[]
currentItems: CurrentItemsState | undefined /**
* The sidebar that is currently shown
*/
shownSidebar: Sidebar.Sidebar | Sidebar.SidebarItemSidebar | undefined
activePath: string | null activePath: string | null
activeItem: SidebarItemLinkWithParent | undefined activeItem: Sidebar.SidebarItemLink | null
setActivePath: (path: string | null) => void setActivePath: (path: string | null) => void
isLinkActive: (item: SidebarItem, checkChildren?: boolean) => boolean /**
isChildrenActive: (item: SidebarItemCategory) => boolean * Check if an item is active. This includes checking its child items,
addItems: (items: SidebarItem[], options?: ActionOptionsType) => void * so for UI links that have children, the `checkLinkChildren` option should be set to `false`
removeItems: (items: SidebarItem[]) => void * to ensure that the link isn't shown as active if a child link is active.
findItemInSection: ( */
section: SidebarItem[], isItemActive: (options: {
item: Partial<SidebarItem>, item: Sidebar.InteractiveSidebarItem
checkChildren?: boolean checkLinkChildren?: boolean
) => SidebarItem | undefined }) => boolean
addItems: (
items: Sidebar.SidebarItem[],
options?: SidebarActionOptions
) => void
removeItems: (options: {
items: Sidebar.SidebarItem[]
sidebar_id: string
}) => void
mobileSidebarOpen: boolean mobileSidebarOpen: boolean
setMobileSidebarOpen: React.Dispatch<React.SetStateAction<boolean>> setMobileSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>
desktopSidebarOpen: boolean desktopSidebarOpen: boolean
setDesktopSidebarOpen: React.Dispatch<React.SetStateAction<boolean>> setDesktopSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>
staticSidebarItems?: boolean // Whether the items in the sidebar are static or are added dynamically
// TODO look into generating the sidebar item of the API reference
isSidebarStatic: boolean
/**
* Whether the active path should change when the hash changes
* This is only used by the API reference
*/
shouldHandleHashChange: boolean shouldHandleHashChange: boolean
sidebarRef: React.RefObject<HTMLDivElement | null> sidebarRef: React.RefObject<HTMLDivElement | null>
/**
* Go back in the sidebar history
*/
goBack: () => void goBack: () => void
/**
* The height of the top part of the sidebar
*/
sidebarTopHeight: number sidebarTopHeight: number
setSidebarTopHeight: React.Dispatch<React.SetStateAction<number>> setSidebarTopHeight: React.Dispatch<React.SetStateAction<number>>
/**
* Reset the sidebar to its initial state (the sidebars passed as a prop)
*/
resetItems: () => void resetItems: () => void
isItemLoaded: (path: string) => boolean
updatePersistedCategoryState: (title: string, opened: boolean) => void updatePersistedCategoryState: (title: string, opened: boolean) => void
getPersistedCategoryState: (title: string) => boolean | undefined getPersistedCategoryState: (title: string) => boolean | undefined
persistState: boolean persistCategoryState: boolean
isSidebarShown: boolean isSidebarShown: boolean
sidebarHistory: string[]
/**
* Get the first link child of a sidebar
*/
getSidebarFirstLinkChild: (
sidebar: Sidebar.Sidebar | Sidebar.SidebarItemSidebar
) => Sidebar.SidebarItemLink | undefined
getSidebar: (
sidebar_id: string
) => Sidebar.Sidebar | Sidebar.SidebarItemSidebar
} & SidebarStyleOptions } & SidebarStyleOptions
export const SidebarContext = createContext<SidebarContextType | null>(null) export const SidebarContext = createContext<SidebarContextType | null>(null)
export type ActionOptionsType = {
section?: SidebarItemSections
parent?: {
type: InteractiveSidebarItemTypes
path: string
title: string
changeLoaded?: boolean
}
indexPosition?: number
ignoreExisting?: boolean
}
export type ActionType = export type ActionType =
| { | {
type: "add" | "update" type: "add" | "update"
items: SidebarItem[] items: Sidebar.SidebarItem[]
options?: ActionOptionsType options?: SidebarActionOptions
} }
| { | {
type: "replace" type: "replace"
replacementItems: SidebarSectionItems sidebars: Sidebar.Sidebar[]
} }
| { | {
type: "remove" type: "remove"
items: SidebarItem[] items: Sidebar.SidebarItem[]
} sidebar_id: string
type LinksMap = Map<string, SidebarItemLinkWithParent>
export const isSidebarItemLink = (
item: SidebarItem | undefined,
checkRef = true
): item is SidebarItemLink => {
return (
item !== undefined &&
(item.type === "link" || (checkRef && item.type === "ref"))
)
}
const areItemsEqual = (
itemA: SidebarItem,
itemB: SidebarItem,
compareTitles = true
): boolean => {
if (
itemA.type === "separator" ||
itemB.type === "separator" ||
itemA.type !== itemB.type
) {
return false
}
const hasSameTitle = !compareTitles || itemA.title === itemB.title
const hasSamePath =
!isSidebarItemLink(itemA) ||
!isSidebarItemLink(itemB) ||
itemA.path === itemB.path
return hasSameTitle && hasSamePath
}
const findItem = (
section: SidebarItem[],
item: Partial<SidebarItem>,
checkChildren = true,
compareTitles = true
): SidebarItemLinkWithParent | undefined => {
let foundItem: SidebarItemLinkWithParent | undefined
section.some((i) => {
if (i.type === "separator") {
return false
}
if (areItemsEqual(item as SidebarItem, i, compareTitles)) {
foundItem = i as SidebarItemLink
} else if (checkChildren && i.children) {
foundItem = findItem(i.children, item, checkChildren, compareTitles)
if (foundItem && !foundItem.parentItem) {
foundItem.parentItem = i
}
}
return foundItem !== undefined
})
return foundItem
}
const getLinksMap = (
items: SidebarItem[],
initMap?: LinksMap,
parentItem?: InteractiveSidebarItem
): LinksMap => {
const map: LinksMap = initMap || new Map()
items.forEach((item) => {
if (item.type === "separator") {
return
}
if (isSidebarItemLink(item)) {
map.set(item.path, {
...item,
parentItem,
})
}
if (item.children?.length) {
getLinksMap(item.children, map, item)
}
})
return map
} }
export const reducer = ( export const reducer = (
state: SidebarSectionItems, state: Sidebar.Sidebar[],
actionData: ActionType actionData: ActionType
): SidebarSectionItems => { ): Sidebar.Sidebar[] => {
if (actionData.type === "replace") { if (actionData.type === "replace") {
return actionData.replacementItems return actionData.sidebars
} }
if (actionData.type === "remove") { if (actionData.type === "remove") {
const { sidebar_id, items: itemsToRemove } = actionData
return state.map((sidebar) => {
if (sidebar.sidebar_id === sidebar_id) {
return { return {
...state, ...sidebar,
default: state.default.filter((item) => { items: sidebar.items.filter((item) => {
if (item.type === "separator") { return !itemsToRemove.some((itemToRemove) =>
return true areSidebarItemsEqual({
} itemA: item,
itemB: itemToRemove,
const found = actionData.items.some((itemToRemove) => {
if (
itemToRemove.type === "separator" ||
itemToRemove.type !== item.type
) {
return false
}
if (
itemToRemove.type === "category" ||
itemToRemove.type === "sub-category"
) {
return itemToRemove.title === item.title
}
return (
itemToRemove.path === (item as SidebarItemLink).path &&
itemToRemove.title === (item as SidebarItemLink).title
)
}) })
)
return !found
}), }),
} }
} }
return sidebar
})
}
const { type, options } = actionData const { type, options } = actionData
let { items } = actionData let { items } = actionData
const { parent, ignoreExisting = false, indexPosition } = options || {} const { parent, ignoreExisting = false, indexPosition } = options || {}
const sectionName = SidebarItemSections.DEFAULT const sidebarIndex = state.findIndex(
const sectionItems = state[sectionName] (s) => s.sidebar_id === options?.sidebar_id
)
const sidebar = state[sidebarIndex]
if (!sidebar) {
return state
}
if (!ignoreExisting) { if (!ignoreExisting) {
items = items.filter((item) => !findItem(sectionItems, item)) items = items.filter(
(item) =>
findSidebarItem({ sidebarItems: sidebar.items, item }) === undefined
)
} }
if (!items.length) { if (!items.length) {
@@ -237,26 +192,38 @@ export const reducer = (
switch (type) { switch (type) {
case "add": case "add":
return { return [
...state, ...state.slice(0, sidebarIndex),
[sectionName]: {
...sidebar,
items:
indexPosition !== undefined indexPosition !== undefined
? [ ? [
...sectionItems.slice(0, indexPosition), ...sidebar.items.slice(0, indexPosition),
...items, ...items,
...sectionItems.slice(indexPosition), ...sidebar.items.slice(indexPosition),
]
: [...sidebar.items, ...items],
},
...state.slice(sidebarIndex + 1),
] ]
: [...sectionItems, ...items],
}
case "update": case "update":
// find item index // find item index
return { return [
...state, ...state.slice(0, sidebarIndex),
[sectionName]: sectionItems.map((i) => { {
...sidebar,
items: sidebar.items.map((i) => {
if (i.type === "separator") { if (i.type === "separator") {
return i return i
} }
if (parent && areItemsEqual(i, parent as SidebarItem)) { if (
parent &&
areSidebarItemsEqual({
itemA: i,
itemB: parent as Sidebar.InteractiveSidebarItem,
})
) {
return { return {
...i, ...i,
children: children:
@@ -276,75 +243,155 @@ export const reducer = (
} }
return i return i
}), }),
} },
...state.slice(sidebarIndex + 1),
]
default: default:
return state return state
} }
} }
export type SidebarProviderProps = { export type SidebarProviderProps = {
children?: ReactNode children?: React.ReactNode
isLoading?: boolean isLoading?: boolean
setIsLoading?: React.Dispatch<React.SetStateAction<boolean>> setIsLoading?: React.Dispatch<React.SetStateAction<boolean>>
initialItems?: SidebarSectionItems sidebars: Sidebar.Sidebar[]
shouldHandleHashChange?: boolean shouldHandleHashChange?: boolean
shouldHandlePathChange?: boolean shouldHandlePathChange?: boolean
scrollableElement?: Element | Window scrollableElement?: Element | Window
staticSidebarItems?: boolean isSidebarStatic?: boolean
resetOnCondition?: () => boolean persistCategoryState?: boolean
projectName: string disableActiveTransition?: boolean
persistState?: boolean
} & SidebarStyleOptions } & SidebarStyleOptions
export const SidebarProvider = ({ export const SidebarProvider = ({
children, children,
isLoading = false, isLoading,
setIsLoading, setIsLoading,
initialItems, sidebars: initialSidebars = [],
shouldHandleHashChange = false, shouldHandleHashChange = false,
shouldHandlePathChange = false, shouldHandlePathChange = true,
scrollableElement, scrollableElement,
staticSidebarItems = false, isSidebarStatic = true,
disableActiveTransition = false, persistCategoryState = true,
resetOnCondition, disableActiveTransition = true,
projectName,
persistState = true,
}: SidebarProviderProps) => { }: SidebarProviderProps) => {
const categoriesStorageKey = `${projectName}_categories` const {
config: { project },
} = useSiteConfig()
const categoriesStorageKey = `${project.title}_categories`
const hideSidebarStorageKey = `hide_sidebar` const hideSidebarStorageKey = `hide_sidebar`
const [items, dispatch] = useReducer(reducer, { const [sidebars, dispatch] = useReducer(reducer, initialSidebars)
default: initialItems?.default || [],
mobile: initialItems?.mobile || [],
})
const [currentItems, setCurrentItems] = useState<
CurrentItemsState | undefined
>()
const [activePath, setActivePath] = useState<string | null>("") const [activePath, setActivePath] = useState<string | null>("")
const linksMap: LinksMap = useMemo(() => {
return new Map([
...getLinksMap(items.mobile),
...getLinksMap(items.default),
])
}, [items])
const findItemInSection = useCallback(findItem, [])
const activeItem = useMemo(() => {
if (activePath === null) {
return undefined
}
return linksMap.get(activePath)
}, [activePath, linksMap])
const [mobileSidebarOpen, setMobileSidebarOpen] = useState<boolean>(false) const [mobileSidebarOpen, setMobileSidebarOpen] = useState<boolean>(false)
const [sidebarTopHeight, setSidebarTopHeight] = useState(0)
const [desktopSidebarOpen, setDesktopSidebarOpen] = useState(true) const [desktopSidebarOpen, setDesktopSidebarOpen] = useState(true)
const sidebarRef = useRef<HTMLDivElement>(null) const sidebarRef = useRef<HTMLDivElement>(null)
const [sidebarTopHeight, setSidebarTopHeight] = useState(0)
const pathname = usePathname() const pathname = usePathname()
const router = useRouter() const router = useRouter()
const { isBrowser } = useIsBrowser() const { isBrowser } = useIsBrowser()
const getResolvedScrollableElement = useCallback(() => {
const resolvedScrollableElement = useMemo(() => {
if (!isBrowser) {
return
}
return scrollableElement || window return scrollableElement || window
}, [scrollableElement]) }, [scrollableElement, isBrowser])
const activeMainSidebar = useMemo(() => {
if (!activePath) {
// set first sidebar as active
return sidebars[0]
}
return (
sidebars.find(
(s) =>
findSidebarItem({
sidebarItems: s.items,
item: { type: "link", path: activePath, title: "" },
}) !== undefined
) || sidebars[0]
)
}, [sidebars, activePath])
const { activeItem, sidebarHistory } = useMemo(() => {
if (!activePath) {
return {
activeItem: null,
sidebarHistory: [] as string[],
}
}
const result =
getSidebarItemWithHistory({
sidebarItems: activeMainSidebar.items,
item: { type: "link", path: activePath, title: "" },
compareTitles: false,
}) || null
return {
...result,
sidebarHistory: [
activeMainSidebar.sidebar_id,
...(result.sidebarHistory || []),
],
activeItem: (result.item as Sidebar.SidebarItemLink) || null,
}
}, [activePath, activeMainSidebar])
const getSidebar = useCallback(
(sidebar_id: string) => {
return (
sidebars.find((s) => s.sidebar_id === sidebar_id) ||
(findSidebarItem({
sidebarItems: activeMainSidebar.items || [],
item: { type: "sidebar", sidebar_id, title: "" },
compareTitles: false,
}) as Sidebar.SidebarItemSidebar)
)
},
[sidebars, activeMainSidebar]
)
const shownSidebar = useMemo(() => {
if (!sidebarHistory.length) {
return
}
return getSidebar(sidebarHistory[sidebarHistory.length - 1])
}, [activeMainSidebar, sidebarHistory, getSidebar])
const isItemActive: SidebarContextType["isItemActive"] = useCallback(
({ item, checkLinkChildren = true }): boolean => {
if (!activePath) {
return false
}
if (isSidebarItemLink(item)) {
if (item.path === activePath) {
return true
} else if (!checkLinkChildren) {
return false
}
}
return (
item.children?.some((child) => {
if (child.type === "separator") {
return false
}
return isItemActive({
item: child as Sidebar.InteractiveSidebarItem,
checkLinkChildren,
})
}) || false
)
},
[activePath]
)
const isSidebarShown = useMemo(() => { const isSidebarShown = useMemo(() => {
if (!isBrowser) { if (!isBrowser) {
return true return true
@@ -353,16 +400,10 @@ export const SidebarProvider = ({
return document.getElementsByTagName("aside").length > 0 return document.getElementsByTagName("aside").length > 0
}, [isBrowser]) }, [isBrowser])
const isItemLoaded = useCallback( const addItems = (
(path: string) => { newItems: Sidebar.SidebarItem[],
const item = linksMap.get(path) options?: SidebarActionOptions
) => {
return item?.loaded || false
},
[items, linksMap]
)
const addItems = (newItems: SidebarItem[], options?: ActionOptionsType) => {
dispatch({ dispatch({
type: options?.parent ? "update" : "add", type: options?.parent ? "update" : "add",
items: newItems, items: newItems,
@@ -370,123 +411,39 @@ export const SidebarProvider = ({
}) })
} }
const removeItems = (itemsToRemove: SidebarItem[]) => { const removeItems = ({
items,
sidebar_id,
}: {
items: Sidebar.SidebarItem[]
sidebar_id: string
}) => {
dispatch({ dispatch({
type: "remove", type: "remove",
items: itemsToRemove, items,
sidebar_id,
}) })
} }
const isLinkActive = useCallback(
(item: SidebarItem, checkChildren = false, checkRef = true): boolean => {
if (!isSidebarItemLink(item, checkRef)) {
return false
}
return (
item.path === activePath ||
(checkChildren && activePath?.split("_")[0] === item.path)
)
},
[activePath]
)
const isChildrenActive = useCallback(
(item: InteractiveSidebarItem): boolean => {
return (
item.children?.some((child) => {
if (isLinkActive(child, true)) {
return true
}
return child.type !== "separator" && child.children
? isChildrenActive(child)
: false
}) || false
)
},
[isLinkActive]
)
const init = () => {
const currentPath = location.hash.replace("#", "")
if (currentPath) {
setActivePath(currentPath)
}
}
const getCurrentSidebar = useCallback(
(searchItems: SidebarItem[]): InteractiveSidebarItem | undefined => {
let currentSidebar: InteractiveSidebarItem | undefined
searchItems.some((item) => {
if (item.type === "separator") {
return false
}
if (item.isChildSidebar && isLinkActive(item, false, false)) {
currentSidebar = item
return true
}
if (!item.children?.length) {
return false
}
const childSidebar =
getCurrentSidebar(item.children) ||
(activePath
? findItem(
item.children,
{
path: activePath,
type: "link",
},
true,
false
)
: undefined)
currentSidebar = childSidebar
? childSidebar.isChildSidebar
? childSidebar
: item
: undefined
return currentSidebar !== undefined
})
return currentSidebar
},
[isLinkActive, activePath]
)
const goBack = () => {
if (!currentItems) {
return
}
const previousSidebar = currentItems.previousSidebar || items
const backItem = previousSidebar.default.find(
(item) => isSidebarItemLink(item) && !item.isChildSidebar
) as SidebarItemLink
if (!backItem) {
return
}
setActivePath(backItem.path!)
setCurrentItems(previousSidebar)
router.replace(backItem.path!)
}
const resetItems = useCallback(() => { const resetItems = useCallback(() => {
dispatch({ dispatch({
type: "replace", type: "replace",
replacementItems: { sidebars: initialSidebars,
default: initialItems?.default || [],
mobile: initialItems?.mobile || [],
},
}) })
}, [initialItems]) }, [initialSidebars])
const init = () => {
const currentPath = location.hash.replace("#", "")
if (currentPath) {
setActivePath(currentPath)
} else {
const firstChild = getFirstLinkChild(activeMainSidebar.items)
if (firstChild) {
setActivePath(firstChild.path)
}
}
}
useEffect(() => { useEffect(() => {
if (shouldHandleHashChange) { if (shouldHandleHashChange) {
@@ -495,21 +452,17 @@ export const SidebarProvider = ({
}, [shouldHandleHashChange]) }, [shouldHandleHashChange])
useEffect(() => { useEffect(() => {
if (!shouldHandleHashChange) { if (!shouldHandleHashChange || !resolvedScrollableElement) {
return return
} }
const resolvedScrollableElement = getResolvedScrollableElement()
const handleScroll = () => { const handleScroll = () => {
if (getScrolledTop(resolvedScrollableElement) === 0) { if (getScrolledTop(resolvedScrollableElement) === 0) {
const firstItemPath = const firstChild = getFirstLinkChild(activeMainSidebar.items)
items.default.length && isSidebarItemLink(items.default[0])
? items.default[0].path if (firstChild) {
: "" setActivePath(firstChild.path)
setActivePath(firstItemPath) router.push(`#${firstChild.path}`, {
if (firstItemPath) {
router.push(`#${firstItemPath}`, {
scroll: false, scroll: false,
}) })
} }
@@ -521,7 +474,7 @@ export const SidebarProvider = ({
return () => { return () => {
resolvedScrollableElement.removeEventListener("scroll", handleScroll) resolvedScrollableElement.removeEventListener("scroll", handleScroll)
} }
}, [shouldHandleHashChange, getResolvedScrollableElement]) }, [shouldHandleHashChange, resolvedScrollableElement])
useEffect(() => { useEffect(() => {
if (!shouldHandleHashChange || !isBrowser) { if (!shouldHandleHashChange || !isBrowser) {
@@ -544,10 +497,10 @@ export const SidebarProvider = ({
}, [shouldHandleHashChange, isBrowser]) }, [shouldHandleHashChange, isBrowser])
useEffect(() => { useEffect(() => {
if (isLoading && items.default.length) { if (isLoading && sidebars.length) {
setIsLoading?.(false) setIsLoading?.(false)
} }
}, [items, isLoading, setIsLoading]) }, [sidebars, isLoading, setIsLoading])
useEffect(() => { useEffect(() => {
if (!shouldHandlePathChange) { if (!shouldHandlePathChange) {
@@ -559,47 +512,6 @@ export const SidebarProvider = ({
} }
}, [shouldHandlePathChange, pathname]) }, [shouldHandlePathChange, pathname])
useEffect(() => {
if (!activePath?.length) {
setCurrentItems(undefined)
return
}
const currentSidebar = getCurrentSidebar(items.default)
if (!currentSidebar) {
setCurrentItems(undefined)
return
}
if (
currentSidebar.isChildSidebar &&
currentSidebar.children &&
(!currentItems?.parentItem ||
!areItemsEqual(currentItems?.parentItem, currentSidebar))
) {
const { children, ...parentItem } = currentSidebar
const hasPreviousSidebar =
isSidebarItemLink(currentItems?.previousSidebar?.parentItem) &&
isSidebarItemLink(parentItem) &&
currentItems.previousSidebar.parentItem.path !== parentItem.path
setCurrentItems({
default: children,
mobile: items.mobile,
parentItem: parentItem,
previousSidebar: hasPreviousSidebar ? currentItems : undefined,
})
}
}, [getCurrentSidebar, activePath])
useEffect(() => {
if (resetOnCondition?.()) {
resetItems()
setActivePath(null)
}
}, [resetOnCondition, resetItems])
useEffect(() => { useEffect(() => {
if (!isBrowser) { if (!isBrowser) {
return return
@@ -627,12 +539,12 @@ export const SidebarProvider = ({
const storageData = JSON.parse( const storageData = JSON.parse(
localStorage.getItem(categoriesStorageKey) || "{}" localStorage.getItem(categoriesStorageKey) || "{}"
) )
if (!Object.hasOwn(storageData, projectName)) { if (!Object.hasOwn(storageData, project.title)) {
storageData[projectName] = {} storageData[project.title] = {}
} }
storageData[projectName] = { storageData[project.title] = {
...storageData[projectName], ...storageData[project.title],
[title]: opened, [title]: opened,
} }
@@ -644,42 +556,98 @@ export const SidebarProvider = ({
localStorage.getItem(categoriesStorageKey) || "{}" localStorage.getItem(categoriesStorageKey) || "{}"
) )
return !Object.hasOwn(storageData, projectName) || return !Object.hasOwn(storageData, project.title) ||
!Object.hasOwn(storageData[projectName], title) !Object.hasOwn(storageData[project.title], title)
? undefined ? undefined
: storageData[projectName][title] : storageData[project.title][title]
}
const getFirstLinkChild = useCallback(
(items: Sidebar.SidebarItem[]): Sidebar.SidebarItemLink | undefined => {
let foundItem: Sidebar.SidebarItemLink | undefined
items.some((item) => {
if (item.type === "link") {
foundItem = item
} else if ("children" in item && item.children) {
foundItem = getFirstLinkChild(item.children)
}
return foundItem !== undefined
})
return foundItem
},
[]
)
const getSidebarFirstLinkChild = useCallback(
(
sidebar: Sidebar.Sidebar | Sidebar.SidebarItemSidebar
): Sidebar.SidebarItemLink | undefined => {
const itemsToSearch =
"items" in sidebar ? sidebar.items : sidebar.children || []
return getFirstLinkChild(itemsToSearch)
},
[getFirstLinkChild]
)
const openSidebar = (sidebar_id: string) => {
const sidebar = getSidebar(sidebar_id)
if (!sidebar) {
return
}
const firstChild = getSidebarFirstLinkChild(sidebar)
if (firstChild) {
setActivePath(firstChild.path)
router.replace(
firstChild.isPathHref ? firstChild.path : `#${firstChild.path}`
)
}
}
const goBack = () => {
if (!sidebarHistory || sidebarHistory.length <= 1) {
openSidebar(activeMainSidebar.sidebar_id)
} else {
const lastSidebar = sidebarHistory[sidebarHistory.length - 2]
openSidebar(lastSidebar)
}
} }
return ( return (
<SidebarContext.Provider <SidebarContext.Provider
value={{ value={{
items, sidebars,
currentItems, shownSidebar,
activePath,
activeItem,
setActivePath,
isItemActive,
addItems, addItems,
removeItems, removeItems,
activePath,
setActivePath,
isLinkActive: isLinkActive,
isChildrenActive,
findItemInSection,
mobileSidebarOpen, mobileSidebarOpen,
setMobileSidebarOpen, setMobileSidebarOpen,
desktopSidebarOpen, desktopSidebarOpen,
setDesktopSidebarOpen, setDesktopSidebarOpen,
activeItem, isSidebarStatic,
staticSidebarItems,
disableActiveTransition,
shouldHandleHashChange, shouldHandleHashChange,
sidebarRef, sidebarRef,
goBack, goBack,
sidebarTopHeight, sidebarTopHeight,
setSidebarTopHeight, setSidebarTopHeight,
resetItems, resetItems,
isItemLoaded,
updatePersistedCategoryState, updatePersistedCategoryState,
getPersistedCategoryState, getPersistedCategoryState,
persistState, persistCategoryState,
isSidebarShown, isSidebarShown,
sidebarHistory,
getSidebarFirstLinkChild,
getSidebar,
disableActiveTransition,
}} }}
> >
{children} {children}
@@ -25,17 +25,11 @@ export const SiteConfigProvider = ({
Object.assign( Object.assign(
{ {
baseUrl: "", baseUrl: "",
sidebar: { sidebars: [],
default: [],
mobile: [],
},
project: { project: {
title: "", title: "",
key: "", key: "",
}, },
breadcrumbOptions: {
showCategories: true,
},
reportIssueLink: GITHUB_ISSUES_LINK, reportIssueLink: GITHUB_ISSUES_LINK,
logo: "", logo: "",
}, },
@@ -21,7 +21,8 @@ export const getLocalSearch = <T extends BaseSearchRecord = BaseSearchRecord>({
docs, docs,
searchableFields, searchableFields,
options, options,
}: GetLocalSearchInput<T>): LocalSearch<T> => { }: GetLocalSearchInput<T>): LocalSearch<T> | undefined => {
try {
const miniSearch = new MiniSearch({ const miniSearch = new MiniSearch({
fields: searchableFields, fields: searchableFields,
...options, ...options,
@@ -29,4 +30,7 @@ export const getLocalSearch = <T extends BaseSearchRecord = BaseSearchRecord>({
miniSearch.addAll(docs) miniSearch.addAll(docs)
return miniSearch as LocalSearch<T> return miniSearch as LocalSearch<T>
} catch (e) {
console.warn(e)
}
} }
+1 -1
View File
@@ -12,6 +12,6 @@ export * from "./is-elm-window"
export * from "./is-in-view" export * from "./is-in-view"
export * from "./learning-paths" export * from "./learning-paths"
export * from "./set-obj-value" export * from "./set-obj-value"
export * from "./sidebar-attach-href-common-options" export * from "./sidebar-utils"
export * from "./swr-fetcher" export * from "./swr-fetcher"
export * from "./workflow-diagram-utils" export * from "./workflow-diagram-utils"
Loaded 100 of 108 files, more files were not shown because too many files have changed in this diff. Show more