docs: fix sidebar not updating when api reference path changes (#8409)
This commit is contained in:
1 parent
8eb538ff8f
commit
2682e2e324
5 files changed
+61
-9
No files matched your search
@@ -32,7 +32,7 @@ const Tags = () => {
|
|||||||
const [expand, setExpand] = useState<string>("")
|
const [expand, setExpand] = useState<string>("")
|
||||||
const { baseSpecs, setBaseSpecs } = useBaseSpecs()
|
const { baseSpecs, setBaseSpecs } = useBaseSpecs()
|
||||||
const { addItems } = useSidebar()
|
const { addItems } = useSidebar()
|
||||||
const { area } = useArea()
|
const { area, prevArea } = useArea()
|
||||||
|
|
||||||
const { data } = useSWR<ExpandedDocument>(
|
const { data } = useSWR<ExpandedDocument>(
|
||||||
loadData && !baseSpecs
|
loadData && !baseSpecs
|
||||||
@@ -63,6 +63,11 @@ const Tags = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (baseSpecs) {
|
if (baseSpecs) {
|
||||||
|
if (prevArea !== area) {
|
||||||
|
setBaseSpecs(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
addItems(
|
addItems(
|
||||||
baseSpecs.tags?.map((tag) => {
|
baseSpecs.tags?.map((tag) => {
|
||||||
const tagPathName = getSectionId([tag.name.toLowerCase()])
|
const tagPathName = getSectionId([tag.name.toLowerCase()])
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import type { Area } from "@/types/openapi"
|
import type { Area } from "@/types/openapi"
|
||||||
import { useSearch } from "docs-ui"
|
import { usePrevious, useSearch } from "docs-ui"
|
||||||
import { createContext, useContext, useEffect, useState } from "react"
|
import { createContext, useContext, useEffect, useState } from "react"
|
||||||
|
|
||||||
type AreaContextType = {
|
type AreaContextType = {
|
||||||
area: Area
|
area: Area
|
||||||
|
prevArea: Area | undefined
|
||||||
setArea: (value: Area) => void
|
setArea: (value: Area) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ type AreaProviderProps = {
|
|||||||
|
|
||||||
const AreaProvider = ({ area: passedArea, children }: AreaProviderProps) => {
|
const AreaProvider = ({ area: passedArea, children }: AreaProviderProps) => {
|
||||||
const [area, setArea] = useState<Area>(passedArea)
|
const [area, setArea] = useState<Area>(passedArea)
|
||||||
|
const prevArea = usePrevious(area)
|
||||||
const { defaultFilters, setDefaultFilters } = useSearch()
|
const { defaultFilters, setDefaultFilters } = useSearch()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -30,6 +32,7 @@ const AreaProvider = ({ area: passedArea, children }: AreaProviderProps) => {
|
|||||||
<AreaContext.Provider
|
<AreaContext.Provider
|
||||||
value={{
|
value={{
|
||||||
area,
|
area,
|
||||||
|
prevArea,
|
||||||
setArea,
|
setArea,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { ReactNode, createContext, useContext, useState } from "react"
|
|||||||
|
|
||||||
type BaseSpecsContextType = {
|
type BaseSpecsContextType = {
|
||||||
baseSpecs: ExpandedDocument | null
|
baseSpecs: ExpandedDocument | null
|
||||||
setBaseSpecs: (value: ExpandedDocument) => void
|
setBaseSpecs: React.Dispatch<React.SetStateAction<ExpandedDocument | null>>
|
||||||
getSecuritySchema: (securityName: string) => SecuritySchemeObject | null
|
getSecuritySchema: (securityName: string) => SecuritySchemeObject | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
import {
|
import {
|
||||||
SidebarProvider as UiSidebarProvider,
|
SidebarProvider as UiSidebarProvider,
|
||||||
usePageLoading,
|
usePageLoading,
|
||||||
|
usePrevious,
|
||||||
useScrollController,
|
useScrollController,
|
||||||
} from "docs-ui"
|
} from "docs-ui"
|
||||||
import { config } from "../config"
|
import { config } from "../config"
|
||||||
|
import { usePathname } from "next/navigation"
|
||||||
|
import { useCallback } from "react"
|
||||||
|
|
||||||
type SidebarProviderProps = {
|
type SidebarProviderProps = {
|
||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
@@ -13,6 +16,13 @@ type SidebarProviderProps = {
|
|||||||
const SidebarProvider = ({ children }: SidebarProviderProps) => {
|
const SidebarProvider = ({ children }: SidebarProviderProps) => {
|
||||||
const { isLoading, setIsLoading } = usePageLoading()
|
const { isLoading, setIsLoading } = usePageLoading()
|
||||||
const { scrollableElement } = useScrollController()
|
const { scrollableElement } = useScrollController()
|
||||||
|
const pathname = usePathname()
|
||||||
|
const prevPathname = usePrevious(pathname)
|
||||||
|
|
||||||
|
const resetOnCondition = useCallback(
|
||||||
|
() => prevPathname !== undefined && prevPathname !== pathname,
|
||||||
|
[pathname, prevPathname]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UiSidebarProvider
|
<UiSidebarProvider
|
||||||
@@ -21,6 +31,7 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
|
|||||||
shouldHandleHashChange={true}
|
shouldHandleHashChange={true}
|
||||||
scrollableElement={scrollableElement}
|
scrollableElement={scrollableElement}
|
||||||
initialItems={config.sidebar}
|
initialItems={config.sidebar}
|
||||||
|
resetOnCondition={resetOnCondition}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</UiSidebarProvider>
|
</UiSidebarProvider>
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ export type SidebarContextType = {
|
|||||||
shouldHandleHashChange: boolean
|
shouldHandleHashChange: boolean
|
||||||
sidebarRef: React.RefObject<HTMLDivElement>
|
sidebarRef: React.RefObject<HTMLDivElement>
|
||||||
goBack: () => void
|
goBack: () => void
|
||||||
|
resetItems: () => void
|
||||||
} & SidebarStyleOptions
|
} & SidebarStyleOptions
|
||||||
|
|
||||||
export const SidebarContext = createContext<SidebarContextType | null>(null)
|
export const SidebarContext = createContext<SidebarContextType | null>(null)
|
||||||
@@ -75,11 +76,16 @@ export type ActionOptionsType = {
|
|||||||
ignoreExisting?: boolean
|
ignoreExisting?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ActionType = {
|
export type ActionType =
|
||||||
type: "add" | "update"
|
| {
|
||||||
items: SidebarItemType[]
|
type: "add" | "update"
|
||||||
options?: ActionOptionsType
|
items: SidebarItemType[]
|
||||||
}
|
options?: ActionOptionsType
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: "replace"
|
||||||
|
replacementItems: SidebarSectionItemsType
|
||||||
|
}
|
||||||
|
|
||||||
const findItem = (
|
const findItem = (
|
||||||
section: SidebarItemType[],
|
section: SidebarItemType[],
|
||||||
@@ -105,8 +111,15 @@ const findItem = (
|
|||||||
|
|
||||||
export const reducer = (
|
export const reducer = (
|
||||||
state: SidebarSectionItemsType,
|
state: SidebarSectionItemsType,
|
||||||
{ type, items, options }: ActionType
|
actionData: ActionType
|
||||||
) => {
|
) => {
|
||||||
|
if (actionData.type === "replace") {
|
||||||
|
return actionData.replacementItems
|
||||||
|
}
|
||||||
|
|
||||||
|
const { type, options } = actionData
|
||||||
|
let { items } = actionData
|
||||||
|
|
||||||
const {
|
const {
|
||||||
section = SidebarItemSections.TOP,
|
section = SidebarItemSections.TOP,
|
||||||
parent,
|
parent,
|
||||||
@@ -173,6 +186,7 @@ export type SidebarProviderProps = {
|
|||||||
shouldHandlePathChange?: boolean
|
shouldHandlePathChange?: boolean
|
||||||
scrollableElement?: Element | Window
|
scrollableElement?: Element | Window
|
||||||
staticSidebarItems?: boolean
|
staticSidebarItems?: boolean
|
||||||
|
resetOnCondition?: () => boolean
|
||||||
} & SidebarStyleOptions
|
} & SidebarStyleOptions
|
||||||
|
|
||||||
export const SidebarProvider = ({
|
export const SidebarProvider = ({
|
||||||
@@ -186,6 +200,7 @@ export const SidebarProvider = ({
|
|||||||
staticSidebarItems = false,
|
staticSidebarItems = false,
|
||||||
disableActiveTransition = false,
|
disableActiveTransition = false,
|
||||||
noTitleStyling = false,
|
noTitleStyling = false,
|
||||||
|
resetOnCondition,
|
||||||
}: SidebarProviderProps) => {
|
}: SidebarProviderProps) => {
|
||||||
const [items, dispatch] = useReducer(reducer, {
|
const [items, dispatch] = useReducer(reducer, {
|
||||||
top: initialItems?.top || [],
|
top: initialItems?.top || [],
|
||||||
@@ -315,6 +330,17 @@ export const SidebarProvider = ({
|
|||||||
router.replace(backItem.path!)
|
router.replace(backItem.path!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resetItems = useCallback(() => {
|
||||||
|
dispatch({
|
||||||
|
type: "replace",
|
||||||
|
replacementItems: {
|
||||||
|
top: initialItems?.top || [],
|
||||||
|
bottom: initialItems?.bottom || [],
|
||||||
|
mobile: initialItems?.mobile || [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, [initialItems])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (shouldHandleHashChange) {
|
if (shouldHandleHashChange) {
|
||||||
init()
|
init()
|
||||||
@@ -413,6 +439,12 @@ export const SidebarProvider = ({
|
|||||||
}
|
}
|
||||||
}, [getCurrentSidebar, activePath])
|
}, [getCurrentSidebar, activePath])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (resetOnCondition?.()) {
|
||||||
|
resetItems()
|
||||||
|
}
|
||||||
|
}, [resetOnCondition])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarContext.Provider
|
<SidebarContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@@ -435,6 +467,7 @@ export const SidebarProvider = ({
|
|||||||
shouldHandleHashChange,
|
shouldHandleHashChange,
|
||||||
sidebarRef,
|
sidebarRef,
|
||||||
goBack,
|
goBack,
|
||||||
|
resetItems,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
Reference in new issue
Block a user