docs: fix sidebar not updating when api reference path changes (#8409)

This commit is contained in:
Shahed Nasser authored and GitHub committed 2024-08-05 13:20:53 +03:00
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()])
+4 -1
View File
@@ -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}