diff --git a/www/apps/api-reference/components/Tags/index.tsx b/www/apps/api-reference/components/Tags/index.tsx index d558fe8bc67b9..f07a46b1fa8b6 100644 --- a/www/apps/api-reference/components/Tags/index.tsx +++ b/www/apps/api-reference/components/Tags/index.tsx @@ -32,7 +32,7 @@ const Tags = () => { const [expand, setExpand] = useState("") const { baseSpecs, setBaseSpecs } = useBaseSpecs() const { addItems } = useSidebar() - const { area } = useArea() + const { area, prevArea } = useArea() const { data } = useSWR( loadData && !baseSpecs @@ -63,6 +63,11 @@ const Tags = () => { useEffect(() => { if (baseSpecs) { + if (prevArea !== area) { + setBaseSpecs(null) + return + } + addItems( baseSpecs.tags?.map((tag) => { const tagPathName = getSectionId([tag.name.toLowerCase()]) diff --git a/www/apps/api-reference/providers/area.tsx b/www/apps/api-reference/providers/area.tsx index f6fe678dcc7d1..de4db69d6410e 100644 --- a/www/apps/api-reference/providers/area.tsx +++ b/www/apps/api-reference/providers/area.tsx @@ -1,11 +1,12 @@ "use client" import type { Area } from "@/types/openapi" -import { useSearch } from "docs-ui" +import { usePrevious, useSearch } from "docs-ui" import { createContext, useContext, useEffect, useState } from "react" type AreaContextType = { area: Area + prevArea: Area | undefined setArea: (value: Area) => void } @@ -18,6 +19,7 @@ type AreaProviderProps = { const AreaProvider = ({ area: passedArea, children }: AreaProviderProps) => { const [area, setArea] = useState(passedArea) + const prevArea = usePrevious(area) const { defaultFilters, setDefaultFilters } = useSearch() useEffect(() => { @@ -30,6 +32,7 @@ const AreaProvider = ({ area: passedArea, children }: AreaProviderProps) => { diff --git a/www/apps/api-reference/providers/base-specs.tsx b/www/apps/api-reference/providers/base-specs.tsx index e1db3d1988b5e..fbe43b37bd4c9 100644 --- a/www/apps/api-reference/providers/base-specs.tsx +++ b/www/apps/api-reference/providers/base-specs.tsx @@ -5,7 +5,7 @@ import { ReactNode, createContext, useContext, useState } from "react" type BaseSpecsContextType = { baseSpecs: ExpandedDocument | null - setBaseSpecs: (value: ExpandedDocument) => void + setBaseSpecs: React.Dispatch> getSecuritySchema: (securityName: string) => SecuritySchemeObject | null } diff --git a/www/apps/api-reference/providers/sidebar.tsx b/www/apps/api-reference/providers/sidebar.tsx index 8a35e2fac572c..f361463ccbdfb 100644 --- a/www/apps/api-reference/providers/sidebar.tsx +++ b/www/apps/api-reference/providers/sidebar.tsx @@ -2,9 +2,12 @@ import { SidebarProvider as UiSidebarProvider, usePageLoading, + usePrevious, useScrollController, } from "docs-ui" import { config } from "../config" +import { usePathname } from "next/navigation" +import { useCallback } from "react" type SidebarProviderProps = { children?: React.ReactNode @@ -13,6 +16,13 @@ type SidebarProviderProps = { const SidebarProvider = ({ children }: SidebarProviderProps) => { const { isLoading, setIsLoading } = usePageLoading() const { scrollableElement } = useScrollController() + const pathname = usePathname() + const prevPathname = usePrevious(pathname) + + const resetOnCondition = useCallback( + () => prevPathname !== undefined && prevPathname !== pathname, + [pathname, prevPathname] + ) return ( { shouldHandleHashChange={true} scrollableElement={scrollableElement} initialItems={config.sidebar} + resetOnCondition={resetOnCondition} > {children} diff --git a/www/packages/docs-ui/src/providers/Sidebar/index.tsx b/www/packages/docs-ui/src/providers/Sidebar/index.tsx index 6253e6169ea8b..c4534793ceea5 100644 --- a/www/packages/docs-ui/src/providers/Sidebar/index.tsx +++ b/www/packages/docs-ui/src/providers/Sidebar/index.tsx @@ -61,6 +61,7 @@ export type SidebarContextType = { shouldHandleHashChange: boolean sidebarRef: React.RefObject goBack: () => void + resetItems: () => void } & SidebarStyleOptions export const SidebarContext = createContext(null) @@ -75,11 +76,16 @@ export type ActionOptionsType = { ignoreExisting?: boolean } -export type ActionType = { - type: "add" | "update" - items: SidebarItemType[] - options?: ActionOptionsType -} +export type ActionType = + | { + type: "add" | "update" + items: SidebarItemType[] + options?: ActionOptionsType + } + | { + type: "replace" + replacementItems: SidebarSectionItemsType + } const findItem = ( section: SidebarItemType[], @@ -105,8 +111,15 @@ const findItem = ( export const reducer = ( state: SidebarSectionItemsType, - { type, items, options }: ActionType + actionData: ActionType ) => { + if (actionData.type === "replace") { + return actionData.replacementItems + } + + const { type, options } = actionData + let { items } = actionData + const { section = SidebarItemSections.TOP, parent, @@ -173,6 +186,7 @@ export type SidebarProviderProps = { shouldHandlePathChange?: boolean scrollableElement?: Element | Window staticSidebarItems?: boolean + resetOnCondition?: () => boolean } & SidebarStyleOptions export const SidebarProvider = ({ @@ -186,6 +200,7 @@ export const SidebarProvider = ({ staticSidebarItems = false, disableActiveTransition = false, noTitleStyling = false, + resetOnCondition, }: SidebarProviderProps) => { const [items, dispatch] = useReducer(reducer, { top: initialItems?.top || [], @@ -315,6 +330,17 @@ export const SidebarProvider = ({ router.replace(backItem.path!) } + const resetItems = useCallback(() => { + dispatch({ + type: "replace", + replacementItems: { + top: initialItems?.top || [], + bottom: initialItems?.bottom || [], + mobile: initialItems?.mobile || [], + }, + }) + }, [initialItems]) + useEffect(() => { if (shouldHandleHashChange) { init() @@ -413,6 +439,12 @@ export const SidebarProvider = ({ } }, [getCurrentSidebar, activePath]) + useEffect(() => { + if (resetOnCondition?.()) { + resetItems() + } + }, [resetOnCondition]) + return ( {children}