-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.tsx
81 lines (66 loc) · 2.4 KB
/
utils.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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import {stringify} from "qs"
import {TermUnion, MenuItem, BookLink} from "@lib/gql/__generated__/drupal.d"
export const buildUrl = (path: string, params?: string | Record<string, string> | URLSearchParams): URL => {
const url = new URL(path.charAt(0) === "/" ? `${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}${path}` : path)
// Use instead URLSearchParams for nested params.
if (params) url.search = stringify(params)
return url
}
export type Slug = {slug: string[]}
export type PageProps = {
params: Promise<Slug>
searchParams?: Promise<Record<string, string | string[] | undefined>>
}
export const getPathFromContext = (slug: string | string[], prefix = ""): string => {
let slugString = Array.isArray(slug) ? slug.map(s => encodeURIComponent(s)).join("/") : slug
slugString = slugString.replace(/^\//, "")
return prefix ? `${prefix}/${slugString}` : `/${slugString}`
}
export type TermTree<T extends TermUnion> = T & {
below?: TermTree<T>[]
}
export const getTaxonomyTree = <T extends TermUnion>(terms: T[]): TermTree<T>[] => {
const {below} = buildTaxonomyTree<T>(terms)
return below || terms
}
export const buildTaxonomyTree = <T extends TermUnion>(terms: T[], parent: T["id"] = ""): {below?: T[]} => {
if (!terms?.length) return {below: []}
const children = terms.filter(term => parent && term.parent?.id === parent)
return children.length
? {
below: children.map(link => ({
...link,
...buildTaxonomyTree(terms, link.id),
})),
}
: {}
}
/**
* Get an array of menu item ids representing the current page"s location in the main menu.
*
* @param menuItems
* Array of menu items.
* @param currentPath
* Current page url.
*/
export const getMenuActiveTrail = (menuItems: MenuItem[] | BookLink[], currentPath?: string): string[] => {
const getActiveTrail = (menuItems: MenuItem[] | BookLink[], trail: string[] = []): string[] => {
let childTrail, currentTrail
for (let i = 0; i < menuItems.length; i++) {
currentTrail = [...trail]
currentTrail.push(menuItems[i].id)
if (currentPath === menuItems[i].url) {
return currentTrail
}
const childrenItems = menuItems[i].children
if (childrenItems) {
childTrail = getActiveTrail(childrenItems, [...currentTrail])
if (childTrail.length > 0) {
return childTrail
}
}
}
return []
}
return getActiveTrail(menuItems)
}