-
Notifications
You must be signed in to change notification settings - Fork 0
/
MenuProvider.tsx
49 lines (44 loc) · 1.58 KB
/
MenuProvider.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { useCallback, type PropsWithChildren } from 'react'
import { useFilter } from '../../../../../hooks/useFilter'
import { filterTreeNodes } from '../../../core/filterTreeNodes'
import { getBreadCrumbs } from '../../../core/getBreadCrumbs'
import type { PageURL, TableOfContent } from '../../../types'
import { FilterContext, TocContext } from './contexts'
type MenuProviderProps = PropsWithChildren<{
/** The whole TOC tree */
toc: TableOfContent
/** Current URL */
url: PageURL
/** Is the TOC loading */
isLoading?: boolean
}>
/**
* Takes the data needed to render the menu and creates two contexts:
*
* * `TocContext` contains data for the menu tree, and changing it causes the menu to rerender.
* This is only needed when filtering or switching a page.
*
* * `FilterContext` contains methods and data for the filter input.
* Changing the context only causes the input to rerender.
*/
export function MenuProvider({ toc, url, children, isLoading = false }: MenuProviderProps): JSX.Element {
const filterCallback = useCallback(
(text: string) => filterTreeNodes(toc, text),
[toc]
)
const { data: filter, manager: filterContextValue } = useFilter(filterCallback)
const tocContextValue = {
url,
toc,
breadcrumbs: getBreadCrumbs(toc, url),
filter,
isLoading,
}
return (
<TocContext.Provider value={tocContextValue}>
<FilterContext.Provider value={filterContextValue}>
{children}
</FilterContext.Provider>
</TocContext.Provider>
)
}