docs: collapse sidebar by default in main docs + persist state (#8608)
* docs: collapse sidebar by default in main docs + persist state * persist sidebar hidden
This commit is contained in:
@@ -33,6 +33,8 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
|
|||||||
scrollableElement={scrollableElement}
|
scrollableElement={scrollableElement}
|
||||||
initialItems={config.sidebar}
|
initialItems={config.sidebar}
|
||||||
resetOnCondition={resetOnCondition}
|
resetOnCondition={resetOnCondition}
|
||||||
|
persistState={false}
|
||||||
|
projectName="api"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</UiSidebarProvider>
|
</UiSidebarProvider>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
|
|||||||
initialItems={config.sidebar}
|
initialItems={config.sidebar}
|
||||||
staticSidebarItems={true}
|
staticSidebarItems={true}
|
||||||
disableActiveTransition={true}
|
disableActiveTransition={true}
|
||||||
|
projectName="docs"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</UiSidebarProvider>
|
</UiSidebarProvider>
|
||||||
|
|||||||
@@ -14,24 +14,27 @@ export default function numberSidebarItems(sidebarItems, numbering = [1]) {
|
|||||||
const numberedItems = []
|
const numberedItems = []
|
||||||
/** @type {import("@/types").SidebarItem | undefined} */
|
/** @type {import("@/types").SidebarItem | undefined} */
|
||||||
let parentItem
|
let parentItem
|
||||||
sidebarItems.forEach((item) => {
|
sidebarItems.forEach((item, index) => {
|
||||||
if (item.type === "separator") {
|
if (item.type === "separator") {
|
||||||
;(parentItem?.children || numberedItems).push(item)
|
;(parentItem?.children || numberedItems).push(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// append current number to the item's title
|
||||||
|
item.number = `${numbering.join(".")}.`
|
||||||
|
item.title = `${item.number} ${item.title.trim()}`
|
||||||
|
|
||||||
if (isTopItems) {
|
if (isTopItems) {
|
||||||
// Add chapter category
|
// Add chapter category
|
||||||
numberedItems.push({
|
numberedItems.push({
|
||||||
type: "category",
|
type: "category",
|
||||||
title: `Chapter ${padNumber(numbering[0])}`,
|
title: item.title,
|
||||||
children: [],
|
children: [],
|
||||||
loaded: true,
|
loaded: true,
|
||||||
|
initialOpen: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
parentItem = numberedItems[numberedItems.length - 1]
|
parentItem = numberedItems[numberedItems.length - 1]
|
||||||
}
|
}
|
||||||
// append current number to the item's title
|
|
||||||
item.number = `${numbering.join(".")}.`
|
|
||||||
item.title = `${item.number} ${item.title.trim()}`
|
|
||||||
|
|
||||||
if (item.children) {
|
if (item.children) {
|
||||||
item.children = numberSidebarItems(item.children, [...numbering, 1])
|
item.children = numberSidebarItems(item.children, [...numbering, 1])
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
|
|||||||
initialItems={config.sidebar}
|
initialItems={config.sidebar}
|
||||||
staticSidebarItems={true}
|
staticSidebarItems={true}
|
||||||
disableActiveTransition={true}
|
disableActiveTransition={true}
|
||||||
|
projectName="resources"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</UiSidebarProvider>
|
</UiSidebarProvider>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
|
|||||||
shouldHandlePathChange={true}
|
shouldHandlePathChange={true}
|
||||||
scrollableElement={scrollableElement}
|
scrollableElement={scrollableElement}
|
||||||
disableActiveTransition={true}
|
disableActiveTransition={true}
|
||||||
|
projectName="ui"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</UiSidebarProvider>
|
</UiSidebarProvider>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const SidebarProvider = ({ children }: SidebarProviderProps) => {
|
|||||||
initialItems={config.sidebar}
|
initialItems={config.sidebar}
|
||||||
staticSidebarItems={true}
|
staticSidebarItems={true}
|
||||||
disableActiveTransition={true}
|
disableActiveTransition={true}
|
||||||
|
projectName="user-guide"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</UiSidebarProvider>
|
</UiSidebarProvider>
|
||||||
|
|||||||
@@ -23,7 +23,12 @@ export const SidebarItemCategory = ({
|
|||||||
item.initialOpen !== undefined ? item.initialOpen : expandItems
|
item.initialOpen !== undefined ? item.initialOpen : expandItems
|
||||||
)
|
)
|
||||||
const childrenRef = useRef<HTMLUListElement>(null)
|
const childrenRef = useRef<HTMLUListElement>(null)
|
||||||
const { isChildrenActive } = useSidebar()
|
const {
|
||||||
|
isChildrenActive,
|
||||||
|
updatePersistedCategoryState,
|
||||||
|
getPersistedCategoryState,
|
||||||
|
persistState,
|
||||||
|
} = useSidebar()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open && !item.loaded) {
|
if (open && !item.loaded) {
|
||||||
@@ -44,6 +49,16 @@ export const SidebarItemCategory = ({
|
|||||||
}
|
}
|
||||||
}, [isChildrenActive])
|
}, [isChildrenActive])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!persistState) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const persistedOpen = getPersistedCategoryState(item.title)
|
||||||
|
if (persistedOpen !== undefined) {
|
||||||
|
setOpen(persistedOpen)
|
||||||
|
}
|
||||||
|
}, [persistState])
|
||||||
|
|
||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
item.onOpen?.()
|
item.onOpen?.()
|
||||||
}
|
}
|
||||||
@@ -70,6 +85,9 @@ export const SidebarItemCategory = ({
|
|||||||
if (!open) {
|
if (!open) {
|
||||||
handleOpen()
|
handleOpen()
|
||||||
}
|
}
|
||||||
|
if (persistState) {
|
||||||
|
updatePersistedCategoryState(item.title, !open)
|
||||||
|
}
|
||||||
setOpen((prev) => !prev)
|
setOpen((prev) => !prev)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ export type SidebarContextType = {
|
|||||||
setSidebarTopHeight: React.Dispatch<React.SetStateAction<number>>
|
setSidebarTopHeight: React.Dispatch<React.SetStateAction<number>>
|
||||||
resetItems: () => void
|
resetItems: () => void
|
||||||
isItemLoaded: (path: string) => boolean
|
isItemLoaded: (path: string) => boolean
|
||||||
|
updatePersistedCategoryState: (title: string, opened: boolean) => void
|
||||||
|
getPersistedCategoryState: (title: string) => boolean | undefined
|
||||||
|
persistState: boolean
|
||||||
} & SidebarStyleOptions
|
} & SidebarStyleOptions
|
||||||
|
|
||||||
export const SidebarContext = createContext<SidebarContextType | null>(null)
|
export const SidebarContext = createContext<SidebarContextType | null>(null)
|
||||||
@@ -191,6 +194,8 @@ export type SidebarProviderProps = {
|
|||||||
scrollableElement?: Element | Window
|
scrollableElement?: Element | Window
|
||||||
staticSidebarItems?: boolean
|
staticSidebarItems?: boolean
|
||||||
resetOnCondition?: () => boolean
|
resetOnCondition?: () => boolean
|
||||||
|
projectName: string
|
||||||
|
persistState?: boolean
|
||||||
} & SidebarStyleOptions
|
} & SidebarStyleOptions
|
||||||
|
|
||||||
export const SidebarProvider = ({
|
export const SidebarProvider = ({
|
||||||
@@ -204,7 +209,11 @@ export const SidebarProvider = ({
|
|||||||
staticSidebarItems = false,
|
staticSidebarItems = false,
|
||||||
disableActiveTransition = false,
|
disableActiveTransition = false,
|
||||||
resetOnCondition,
|
resetOnCondition,
|
||||||
|
projectName,
|
||||||
|
persistState = true,
|
||||||
}: SidebarProviderProps) => {
|
}: SidebarProviderProps) => {
|
||||||
|
const categoriesStorageKey = `${projectName}_categories`
|
||||||
|
const hideSidebarStorageKey = `hide_sidebar`
|
||||||
const [items, dispatch] = useReducer(reducer, {
|
const [items, dispatch] = useReducer(reducer, {
|
||||||
default: initialItems?.default || [],
|
default: initialItems?.default || [],
|
||||||
mobile: initialItems?.mobile || [],
|
mobile: initialItems?.mobile || [],
|
||||||
@@ -462,6 +471,56 @@ export const SidebarProvider = ({
|
|||||||
}
|
}
|
||||||
}, [resetOnCondition, resetItems])
|
}, [resetOnCondition, resetItems])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isBrowser) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const storageValue = localStorage.getItem(hideSidebarStorageKey)
|
||||||
|
|
||||||
|
if (storageValue !== null) {
|
||||||
|
setDesktopSidebarOpen(storageValue === "false")
|
||||||
|
}
|
||||||
|
}, [isBrowser])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isBrowser) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem(
|
||||||
|
hideSidebarStorageKey,
|
||||||
|
`${desktopSidebarOpen === false}`
|
||||||
|
)
|
||||||
|
}, [isBrowser, desktopSidebarOpen])
|
||||||
|
|
||||||
|
const updatePersistedCategoryState = (title: string, opened: boolean) => {
|
||||||
|
const storageData = JSON.parse(
|
||||||
|
localStorage.getItem(categoriesStorageKey) || "{}"
|
||||||
|
)
|
||||||
|
if (!Object.hasOwn(storageData, projectName)) {
|
||||||
|
storageData[projectName] = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
storageData[projectName] = {
|
||||||
|
...storageData[projectName],
|
||||||
|
[title]: opened,
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem(categoriesStorageKey, JSON.stringify(storageData))
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPersistedCategoryState = (title: string): boolean | undefined => {
|
||||||
|
const storageData = JSON.parse(
|
||||||
|
localStorage.getItem(categoriesStorageKey) || "{}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return !Object.hasOwn(storageData, projectName) ||
|
||||||
|
!Object.hasOwn(storageData[projectName], title)
|
||||||
|
? undefined
|
||||||
|
: storageData[projectName][title]
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarContext.Provider
|
<SidebarContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@@ -487,6 +546,9 @@ export const SidebarProvider = ({
|
|||||||
setSidebarTopHeight,
|
setSidebarTopHeight,
|
||||||
resetItems,
|
resetItems,
|
||||||
isItemLoaded,
|
isItemLoaded,
|
||||||
|
updatePersistedCategoryState,
|
||||||
|
getPersistedCategoryState,
|
||||||
|
persistState,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -54,3 +54,9 @@ export type RawSidebarItem = SidebarItem & {
|
|||||||
custom_autogenerate?: string
|
custom_autogenerate?: string
|
||||||
number?: string
|
number?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type PersistedSidebarCategoryState = {
|
||||||
|
[k: string]: {
|
||||||
|
[k: string]: boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user