docs: prep for v2 documentation (#6710)
This PR includes documentation that preps for v2 docs (but doesn't introduce new docs). _Note: The number of file changes in the PR is due to find-and-replace within the `references` which is unavoidable. Let me know if I should move it to another PR._ ## Changes - Change Medusa version in base OAS used for v2. - Fix to docblock generator related to not catching all path parameters. - Added typedoc plugin that generates ER Diagrams, which will be used specifically for data model references in commerce modules. - Changed OAS tool to output references in `www/apps/api-reference/specs-v2` directory when the `--v2` option is used. - Added a version switcher to the API reference to switch between V1 and V2. This switcher is enabled by an environment variable, so it won't be visible/usable at the moment. - Upgraded docusaurus to v3.0.1 - Added new Vale rules to ensure correct spelling of Medusa Admin and module names. - Added new components to the `docs-ui` package that will be used in future documentation changes.
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
"use client"
|
||||
|
||||
import { useIsBrowser } from "@/hooks"
|
||||
import { getLearningPath } from "@/utils/learning-paths"
|
||||
import React, { createContext, useContext, useEffect, useState } from "react"
|
||||
import { LearningPathFinishType } from "@/components/LearningPath/Finish"
|
||||
import { useAnalytics } from "docs-ui"
|
||||
import { usePathname, useRouter } from "next/navigation"
|
||||
|
||||
export type LearningPathType = {
|
||||
name: string
|
||||
label: string
|
||||
description?: string
|
||||
steps: LearningPathStepType[]
|
||||
finish?: LearningPathFinishType
|
||||
notificationId?: string
|
||||
}
|
||||
|
||||
export type LearningPathStepType = {
|
||||
title?: string
|
||||
description?: string
|
||||
descriptionJSX?: JSX.Element
|
||||
path?: string
|
||||
}
|
||||
|
||||
export type LearningPathContextType = {
|
||||
path: LearningPathType | null
|
||||
setPath: (value: LearningPathType) => void
|
||||
currentStep: number
|
||||
setCurrentStep: (value: number) => void
|
||||
startPath: (path: LearningPathType) => void
|
||||
updatePath: (data: Pick<LearningPathType, "notificationId">) => void
|
||||
endPath: () => void
|
||||
nextStep: () => void
|
||||
hasNextStep: () => boolean
|
||||
previousStep: () => void
|
||||
hasPreviousStep: () => boolean
|
||||
goToStep: (stepIndex: number) => void
|
||||
isCurrentPath: () => boolean
|
||||
goToCurrentPath: () => void
|
||||
baseUrl?: string
|
||||
}
|
||||
|
||||
type LearningPathProviderProps = {
|
||||
children?: React.ReactNode
|
||||
baseUrl?: string
|
||||
}
|
||||
|
||||
const LearningPathContext = createContext<LearningPathContextType | null>(null)
|
||||
|
||||
export const LearningPathProvider: React.FC<LearningPathProviderProps> = ({
|
||||
children,
|
||||
baseUrl,
|
||||
}) => {
|
||||
const [path, setPath] = useState<LearningPathType | null>(null)
|
||||
const [currentStep, setCurrentStep] = useState(-1)
|
||||
const isBrowser = useIsBrowser()
|
||||
const pathname = usePathname()
|
||||
const router = useRouter()
|
||||
const { track } = useAnalytics()
|
||||
|
||||
const startPath = (path: LearningPathType) => {
|
||||
setPath(path)
|
||||
setCurrentStep(-1)
|
||||
if (isBrowser) {
|
||||
localStorage.setItem(
|
||||
"learning-path",
|
||||
JSON.stringify({
|
||||
pathName: path.name,
|
||||
currentStep: -1,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
track(`learning_path_${path.name}`, {
|
||||
url: pathname,
|
||||
state: `start`,
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (path && currentStep === -1) {
|
||||
nextStep()
|
||||
}
|
||||
}, [path])
|
||||
|
||||
const endPath = () => {
|
||||
const didFinish = currentStep === (path?.steps.length || 0) - 1
|
||||
const reachedIndex = currentStep === -1 ? 0 : currentStep
|
||||
track(`learning_path_${path?.name}`, {
|
||||
url: pathname,
|
||||
state: !didFinish ? `closed` : `end`,
|
||||
reachedStep:
|
||||
path?.steps[reachedIndex]?.title ||
|
||||
path?.steps[reachedIndex]?.description ||
|
||||
path?.steps[reachedIndex]?.descriptionJSX ||
|
||||
reachedIndex,
|
||||
})
|
||||
setPath(null)
|
||||
setCurrentStep(-1)
|
||||
if (isBrowser) {
|
||||
localStorage.removeItem("learning-path")
|
||||
}
|
||||
}
|
||||
|
||||
const hasNextStep = () => currentStep !== (path?.steps.length || 0) - 1
|
||||
|
||||
const nextStep = () => {
|
||||
if (!path || !hasNextStep()) {
|
||||
return
|
||||
}
|
||||
const nextStepIndex = currentStep + 1
|
||||
setCurrentStep(nextStepIndex)
|
||||
const newPath = path.steps[nextStepIndex].path
|
||||
if (isBrowser) {
|
||||
localStorage.setItem(
|
||||
"learning-path",
|
||||
JSON.stringify({
|
||||
pathName: path.name,
|
||||
currentStep: nextStepIndex,
|
||||
})
|
||||
)
|
||||
}
|
||||
if (pathname !== newPath && newPath) {
|
||||
router.push(newPath)
|
||||
}
|
||||
}
|
||||
|
||||
const hasPreviousStep = () => currentStep > 0
|
||||
|
||||
const previousStep = () => {
|
||||
if (!path || !hasPreviousStep()) {
|
||||
return
|
||||
}
|
||||
|
||||
const previousStepIndex = currentStep - 1
|
||||
setCurrentStep(previousStepIndex)
|
||||
const newPath = path.steps[previousStepIndex].path
|
||||
if (isBrowser) {
|
||||
localStorage.setItem(
|
||||
"learning-path",
|
||||
JSON.stringify({
|
||||
pathName: path.name,
|
||||
currentStep: previousStepIndex,
|
||||
})
|
||||
)
|
||||
}
|
||||
if (pathname !== newPath && newPath) {
|
||||
router.push(newPath)
|
||||
}
|
||||
}
|
||||
|
||||
const goToStep = (stepIndex: number) => {
|
||||
if (!path || stepIndex >= path.steps.length) {
|
||||
return
|
||||
}
|
||||
|
||||
setCurrentStep(stepIndex)
|
||||
const newPath = path.steps[stepIndex].path
|
||||
if (isBrowser) {
|
||||
localStorage.setItem(
|
||||
"learning-path",
|
||||
JSON.stringify({
|
||||
pathName: path.name,
|
||||
currentStep: stepIndex,
|
||||
})
|
||||
)
|
||||
}
|
||||
if (pathname !== newPath && newPath) {
|
||||
router.push(newPath)
|
||||
}
|
||||
}
|
||||
|
||||
const isCurrentPath = () => {
|
||||
if (!path || currentStep === -1) {
|
||||
return false
|
||||
}
|
||||
|
||||
return pathname === path.steps[currentStep].path
|
||||
}
|
||||
|
||||
const goToCurrentPath = () => {
|
||||
if (!path || currentStep === -1 || !path.steps[currentStep].path) {
|
||||
return
|
||||
}
|
||||
|
||||
router.push(path.steps[currentStep].path!)
|
||||
}
|
||||
|
||||
const updatePath = (data: Pick<LearningPathType, "notificationId">) => {
|
||||
if (!path) {
|
||||
return
|
||||
}
|
||||
setPath({
|
||||
...path,
|
||||
...data,
|
||||
})
|
||||
}
|
||||
|
||||
const initPath = () => {
|
||||
if (isBrowser) {
|
||||
// give query parameters higher precedence over local storage
|
||||
const queryPathName = new URLSearchParams(location.search).get("path")
|
||||
const queryPath = queryPathName
|
||||
? getLearningPath(queryPathName)
|
||||
: undefined
|
||||
if (queryPath) {
|
||||
startPath(queryPath)
|
||||
} else {
|
||||
const storedPath = localStorage.getItem("learning-path")
|
||||
if (storedPath) {
|
||||
const storedPathParsed = JSON.parse(storedPath)
|
||||
const currentPath = getLearningPath(storedPathParsed?.pathName)
|
||||
if (currentPath) {
|
||||
setPath(currentPath)
|
||||
setCurrentStep(storedPathParsed?.currentStep || 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isBrowser && !path) {
|
||||
initPath()
|
||||
}
|
||||
}, [isBrowser])
|
||||
|
||||
return (
|
||||
<LearningPathContext.Provider
|
||||
value={{
|
||||
path,
|
||||
setPath,
|
||||
currentStep,
|
||||
setCurrentStep,
|
||||
startPath,
|
||||
updatePath,
|
||||
endPath,
|
||||
nextStep,
|
||||
hasNextStep,
|
||||
previousStep,
|
||||
hasPreviousStep,
|
||||
goToStep,
|
||||
isCurrentPath,
|
||||
goToCurrentPath,
|
||||
baseUrl,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</LearningPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useLearningPath = () => {
|
||||
const context = useContext(LearningPathContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useLearningPath must be used within a LearningPathProvider"
|
||||
)
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
"use client"
|
||||
|
||||
import React, {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react"
|
||||
import { useSidebar } from "../Sidebar"
|
||||
import { usePrevious } from "@uidotdev/usehooks"
|
||||
import { SidebarItemType } from "types"
|
||||
|
||||
export type Page = {
|
||||
title: string
|
||||
description?: string
|
||||
link: string
|
||||
}
|
||||
|
||||
export type PaginationContextType = {
|
||||
nextPage?: Page
|
||||
previousPage?: Page
|
||||
}
|
||||
|
||||
export const PaginationContext = createContext<PaginationContextType | null>(
|
||||
null
|
||||
)
|
||||
|
||||
type SearchItemsResult = {
|
||||
foundActive: boolean
|
||||
prevItem?: SidebarItemType
|
||||
nextItem?: SidebarItemType
|
||||
}
|
||||
|
||||
export type PaginationProviderProps = {
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export const PaginationProvider = ({ children }: PaginationProviderProps) => {
|
||||
const { items, activePath } = useSidebar()
|
||||
const combinedItems = useMemo(() => [...items.top, ...items.bottom], [items])
|
||||
const previousActivePath = usePrevious(activePath)
|
||||
const [nextPage, setNextPage] = useState<Page | undefined>()
|
||||
const [prevPage, setPrevPage] = useState<Page | undefined>()
|
||||
|
||||
const getFirstChild = (
|
||||
item: SidebarItemType
|
||||
): SidebarItemType | undefined => {
|
||||
const children = getChildrenWithPages(item)
|
||||
if (!children?.length) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return children[0].path ? children[0] : getFirstChild(children[0])
|
||||
}
|
||||
|
||||
const getChildrenWithPages = (
|
||||
item: SidebarItemType
|
||||
): SidebarItemType[] | undefined => {
|
||||
return item.children?.filter(
|
||||
(childItem) =>
|
||||
childItem.path !== undefined || getChildrenWithPages(childItem)?.length
|
||||
)
|
||||
}
|
||||
|
||||
const getPrevItem = (
|
||||
items: SidebarItemType[],
|
||||
index: number
|
||||
): SidebarItemType | undefined => {
|
||||
let foundItem: SidebarItemType | undefined
|
||||
items
|
||||
.slice(0, index)
|
||||
.reverse()
|
||||
.some((item) => {
|
||||
if (item.children?.length) {
|
||||
foundItem = getPrevItem(item.children, item.children.length)
|
||||
} else if (item.path) {
|
||||
foundItem = item
|
||||
}
|
||||
|
||||
return foundItem !== undefined
|
||||
})
|
||||
|
||||
return foundItem
|
||||
}
|
||||
|
||||
const getNextItem = (
|
||||
items: SidebarItemType[],
|
||||
index: number
|
||||
): SidebarItemType | undefined => {
|
||||
let foundItem: SidebarItemType | undefined
|
||||
items.slice(index + 1).some((item) => {
|
||||
if (item.path) {
|
||||
foundItem = item
|
||||
} else if (item.children?.length) {
|
||||
foundItem = getNextItem(item.children, -1)
|
||||
}
|
||||
|
||||
return foundItem !== undefined
|
||||
})
|
||||
|
||||
return foundItem
|
||||
}
|
||||
|
||||
const searchItems = (currentItems: SidebarItemType[]): SearchItemsResult => {
|
||||
const result: SearchItemsResult = {
|
||||
foundActive: false,
|
||||
}
|
||||
|
||||
result.foundActive = currentItems.some((item, index) => {
|
||||
if (item.path === activePath) {
|
||||
if (index !== 0) {
|
||||
result.prevItem = getPrevItem(currentItems, index)
|
||||
}
|
||||
|
||||
if (item.children?.length) {
|
||||
result.nextItem = getFirstChild(item)
|
||||
}
|
||||
|
||||
if (!result.nextItem && index !== currentItems.length - 1) {
|
||||
result.nextItem = getNextItem(currentItems, index)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
if (item.children?.length) {
|
||||
const childrenResult = searchItems(item.children)
|
||||
|
||||
if (childrenResult.foundActive) {
|
||||
result.prevItem = childrenResult.prevItem
|
||||
result.nextItem = childrenResult.nextItem
|
||||
if (!result.prevItem) {
|
||||
result.prevItem = item.path
|
||||
? item
|
||||
: getPrevItem(currentItems, index)
|
||||
}
|
||||
|
||||
if (!result.nextItem && index !== currentItems.length - 1) {
|
||||
result.nextItem = getNextItem(currentItems, index)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (activePath !== previousActivePath) {
|
||||
const result = searchItems(combinedItems)
|
||||
setPrevPage(
|
||||
result.prevItem
|
||||
? {
|
||||
title: result.prevItem.title,
|
||||
link: result.prevItem.path || "",
|
||||
}
|
||||
: undefined
|
||||
)
|
||||
setNextPage(
|
||||
result.nextItem
|
||||
? {
|
||||
title: result.nextItem.title,
|
||||
link: result.nextItem.path || "",
|
||||
}
|
||||
: undefined
|
||||
)
|
||||
}
|
||||
}, [activePath, previousActivePath])
|
||||
|
||||
return (
|
||||
<PaginationContext.Provider
|
||||
value={{
|
||||
previousPage: prevPage,
|
||||
nextPage,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</PaginationContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const usePagination = (): PaginationContextType => {
|
||||
const context = useContext(PaginationContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error("usePagination must be used inside a PaginationProvider")
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
@@ -7,34 +7,30 @@ import React, {
|
||||
useContext,
|
||||
useEffect,
|
||||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react"
|
||||
import { usePathname } from "next/navigation"
|
||||
import { getScrolledTop } from "../../utils"
|
||||
import { useIsBrowser } from "../../hooks"
|
||||
import { usePathname, useRouter } from "next/navigation"
|
||||
import { getScrolledTop } from "@/utils"
|
||||
import { useIsBrowser } from "@/hooks"
|
||||
import {
|
||||
SidebarItemSections,
|
||||
SidebarItemType,
|
||||
SidebarSectionItemsType,
|
||||
} from "types"
|
||||
|
||||
export enum SidebarItemSections {
|
||||
TOP = "top",
|
||||
BOTTOM = "bottom",
|
||||
MOBILE = "mobile",
|
||||
export type CurrentItemsState = SidebarSectionItemsType & {
|
||||
previousSidebar?: CurrentItemsState
|
||||
}
|
||||
|
||||
export type SidebarItemType = {
|
||||
path?: string
|
||||
title: string
|
||||
additionalElms?: React.ReactNode
|
||||
children?: SidebarItemType[]
|
||||
loaded?: boolean
|
||||
isPathHref?: boolean
|
||||
linkProps?: React.AllHTMLAttributes<HTMLAnchorElement>
|
||||
}
|
||||
|
||||
export type SidebarSectionItemsType = {
|
||||
[k in SidebarItemSections]: SidebarItemType[]
|
||||
export type SidebarStyleOptions = {
|
||||
disableActiveTransition?: boolean
|
||||
noTitleStyling?: boolean
|
||||
}
|
||||
|
||||
export type SidebarContextType = {
|
||||
items: SidebarSectionItemsType
|
||||
currentItems: CurrentItemsState | undefined
|
||||
activePath: string | null
|
||||
getActiveItem: () => SidebarItemType | undefined
|
||||
setActivePath: (path: string | null) => void
|
||||
@@ -61,7 +57,11 @@ export type SidebarContextType = {
|
||||
isSidebarEmpty: () => boolean
|
||||
desktopSidebarOpen: boolean
|
||||
setDesktopSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>
|
||||
}
|
||||
staticSidebarItems?: boolean
|
||||
shouldHandleHashChange: boolean
|
||||
sidebarRef: React.RefObject<HTMLUListElement>
|
||||
goBack: () => void
|
||||
} & SidebarStyleOptions
|
||||
|
||||
export const SidebarContext = createContext<SidebarContextType | null>(null)
|
||||
|
||||
@@ -86,16 +86,21 @@ const findItem = (
|
||||
item: Partial<SidebarItemType>,
|
||||
checkChildren = true
|
||||
): SidebarItemType | undefined => {
|
||||
return section.find((i) => {
|
||||
if (!item.path) {
|
||||
return !i.path && i.title === item.title
|
||||
} else {
|
||||
return (
|
||||
i.path === item.path ||
|
||||
(checkChildren && i.children && findItem(i.children, item))
|
||||
)
|
||||
let foundItem: SidebarItemType | undefined
|
||||
section.some((i) => {
|
||||
if (
|
||||
(!item.path && !i.path && i.title === item.title) ||
|
||||
i.path === item.path
|
||||
) {
|
||||
foundItem = i
|
||||
} else if (checkChildren && i.children) {
|
||||
foundItem = findItem(i.children, item)
|
||||
}
|
||||
|
||||
return foundItem !== undefined
|
||||
})
|
||||
|
||||
return foundItem
|
||||
}
|
||||
|
||||
export const reducer = (
|
||||
@@ -160,7 +165,8 @@ export type SidebarProviderProps = {
|
||||
shouldHandleHashChange?: boolean
|
||||
shouldHandlePathChange?: boolean
|
||||
scrollableElement?: Element | Window
|
||||
}
|
||||
staticSidebarItems?: boolean
|
||||
} & SidebarStyleOptions
|
||||
|
||||
export const SidebarProvider = ({
|
||||
children,
|
||||
@@ -170,16 +176,25 @@ export const SidebarProvider = ({
|
||||
shouldHandleHashChange = false,
|
||||
shouldHandlePathChange = false,
|
||||
scrollableElement,
|
||||
staticSidebarItems = false,
|
||||
disableActiveTransition = false,
|
||||
noTitleStyling = false,
|
||||
}: SidebarProviderProps) => {
|
||||
const [items, dispatch] = useReducer(reducer, {
|
||||
top: initialItems?.top || [],
|
||||
bottom: initialItems?.bottom || [],
|
||||
mobile: initialItems?.mobile || [],
|
||||
})
|
||||
const [currentItems, setCurrentItems] = useState<
|
||||
CurrentItemsState | undefined
|
||||
>()
|
||||
const [activePath, setActivePath] = useState<string | null>("")
|
||||
const [mobileSidebarOpen, setMobileSidebarOpen] = useState<boolean>(false)
|
||||
const [desktopSidebarOpen, setDesktopSidebarOpen] = useState(true)
|
||||
const sidebarRef = useRef<HTMLUListElement>(null)
|
||||
|
||||
const pathname = usePathname()
|
||||
const router = useRouter()
|
||||
const isBrowser = useIsBrowser()
|
||||
const getResolvedScrollableElement = useCallback(() => {
|
||||
return scrollableElement || window
|
||||
@@ -229,9 +244,13 @@ export const SidebarProvider = ({
|
||||
)
|
||||
|
||||
const isSidebarEmpty = useCallback((): boolean => {
|
||||
return Object.values(items).every(
|
||||
(sectionItems) => sectionItems.length === 0
|
||||
)
|
||||
return Object.values(items).every((sectionItems) => {
|
||||
if (!Array.isArray(sectionItems)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return sectionItems.length === 0
|
||||
})
|
||||
}, [items])
|
||||
|
||||
const init = () => {
|
||||
@@ -241,6 +260,54 @@ export const SidebarProvider = ({
|
||||
}
|
||||
}
|
||||
|
||||
const getCurrentSidebar = useCallback(
|
||||
(searchItems: SidebarItemType[]): SidebarItemType | undefined => {
|
||||
let currentSidebar: SidebarItemType | undefined
|
||||
searchItems.some((item) => {
|
||||
if (item.isChildSidebar) {
|
||||
if (isItemActive(item)) {
|
||||
currentSidebar = item
|
||||
} else if (item.children?.length) {
|
||||
const childSidebar =
|
||||
getCurrentSidebar(item.children) ||
|
||||
findItem(item.children, { path: activePath || undefined })
|
||||
|
||||
if (childSidebar) {
|
||||
currentSidebar = childSidebar.isChildSidebar ? childSidebar : item
|
||||
}
|
||||
}
|
||||
} else if (item.children?.length) {
|
||||
currentSidebar = getCurrentSidebar(item.children)
|
||||
}
|
||||
|
||||
return currentSidebar !== undefined
|
||||
})
|
||||
|
||||
return currentSidebar
|
||||
},
|
||||
[isItemActive, activePath]
|
||||
)
|
||||
|
||||
const goBack = () => {
|
||||
if (!currentItems) {
|
||||
return
|
||||
}
|
||||
|
||||
const previousSidebar = currentItems.previousSidebar || items
|
||||
|
||||
const backItem =
|
||||
previousSidebar.top.find((item) => item.path && !item.isChildSidebar) ||
|
||||
previousSidebar.bottom.find((item) => item.path && !item.isChildSidebar)
|
||||
|
||||
if (!backItem) {
|
||||
return
|
||||
}
|
||||
|
||||
setActivePath(backItem.path!)
|
||||
setCurrentItems(currentItems.previousSidebar)
|
||||
router.replace(backItem.path!)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (shouldHandleHashChange) {
|
||||
init()
|
||||
@@ -297,15 +364,50 @@ export const SidebarProvider = ({
|
||||
}, [items, isLoading, setIsLoading])
|
||||
|
||||
useEffect(() => {
|
||||
if (shouldHandlePathChange && pathname !== activePath) {
|
||||
if (!shouldHandlePathChange) {
|
||||
return
|
||||
}
|
||||
|
||||
if (pathname !== activePath) {
|
||||
setActivePath(pathname)
|
||||
}
|
||||
}, [shouldHandlePathChange, pathname])
|
||||
|
||||
useEffect(() => {
|
||||
if (!activePath?.length) {
|
||||
setCurrentItems(undefined)
|
||||
return
|
||||
}
|
||||
|
||||
const currentSidebar =
|
||||
getCurrentSidebar(items.top) || getCurrentSidebar(items.bottom)
|
||||
|
||||
if (!currentSidebar) {
|
||||
setCurrentItems(undefined)
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
currentSidebar.isChildSidebar &&
|
||||
currentSidebar.children &&
|
||||
currentItems?.parentItem?.path !== currentSidebar.path
|
||||
) {
|
||||
const { children, ...parentItem } = currentSidebar
|
||||
setCurrentItems({
|
||||
top: children,
|
||||
bottom: [],
|
||||
mobile: items.mobile,
|
||||
parentItem: parentItem,
|
||||
previousSidebar: currentItems,
|
||||
})
|
||||
}
|
||||
}, [getCurrentSidebar, activePath])
|
||||
|
||||
return (
|
||||
<SidebarContext.Provider
|
||||
value={{
|
||||
items,
|
||||
currentItems,
|
||||
addItems,
|
||||
activePath,
|
||||
setActivePath,
|
||||
@@ -317,6 +419,12 @@ export const SidebarProvider = ({
|
||||
getActiveItem,
|
||||
desktopSidebarOpen,
|
||||
setDesktopSidebarOpen,
|
||||
staticSidebarItems,
|
||||
disableActiveTransition,
|
||||
noTitleStyling,
|
||||
shouldHandleHashChange,
|
||||
sidebarRef,
|
||||
goBack,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
export * from "./AiAssistant"
|
||||
export * from "./Analytics"
|
||||
export * from "./ColorMode"
|
||||
export * from "./LearningPath"
|
||||
export * from "./Mobile"
|
||||
export * from "./Modal"
|
||||
export * from "./Navbar"
|
||||
export * from "./Notification"
|
||||
export * from "./PageLoading"
|
||||
export * from "./Pagination"
|
||||
export * from "./Search"
|
||||
export * from "./Sidebar"
|
||||
|
||||
Reference in New Issue
Block a user