+1
-1
components/Common/Breadcrumbs/index.tsx
+1
-1
components/Common/Breadcrumbs/index.tsx
+32
-9
components/withBreadcrumbs.tsx
+32
-9
components/withBreadcrumbs.tsx
···
2
2
3
3
import type { FC } from 'react';
4
4
5
+
import type { BreadcrumbLink } from '@/components/Common/Breadcrumbs';
5
6
import Breadcrumbs from '@/components/Common/Breadcrumbs';
6
7
import { useClientContext, useMediaQuery, useSiteNavigation } from '@/hooks';
7
8
import type { NavigationKeys } from '@/types';
9
+
import { dashToCamelCase } from '@/util/stringUtils';
8
10
9
11
const WithBreadcrumbs: FC = () => {
10
12
const { navigationItems, getSideNavigation } = useSiteNavigation();
11
13
const { pathname } = useClientContext();
12
-
13
14
const isMobileScreen = useMediaQuery('(max-width: 639px)');
14
15
16
+
const maxLength = isMobileScreen ? 2 : 4;
17
+
15
18
const getBreadrumbs = () => {
16
19
const [navigationKey] =
17
20
navigationItems.find(([, item]) => pathname.includes(item.link)) || [];
···
20
23
return [];
21
24
}
22
25
23
-
return getSideNavigation([navigationKey as NavigationKeys])
24
-
.map(([, item]) => item.items)
25
-
.flat()
26
-
.filter(([, item]) => pathname.includes(item.link))
27
-
.map(([, item]) => ({ label: item.label, href: item.link }));
26
+
const navigationTree = getSideNavigation([navigationKey as NavigationKeys]);
27
+
28
+
const pathList = pathname
29
+
.split('/')
30
+
.filter(item => item !== '')
31
+
.map(dashToCamelCase);
32
+
33
+
let currentNode = navigationTree;
34
+
35
+
// Reduce the pathList to a breadcrumbs array by finding each path in the current navigation layer,
36
+
// updating the currentNode to the found node's items(next layer) for the next iteration.
37
+
return pathList.reduce((breadcrumbs, path) => {
38
+
const nodeWithCurrentPath = currentNode.find(
39
+
([nodePath]) => nodePath === path
40
+
);
41
+
42
+
if (nodeWithCurrentPath) {
43
+
const [, { label, link = '', items = [] }] = nodeWithCurrentPath;
44
+
45
+
// Goes deeper on the tree of items if there are any.
46
+
currentNode = items;
47
+
48
+
return label ? [...breadcrumbs, { label, href: link }] : breadcrumbs;
49
+
}
50
+
51
+
return breadcrumbs;
52
+
}, [] as Array<BreadcrumbLink>);
28
53
};
29
54
30
-
return (
31
-
<Breadcrumbs links={getBreadrumbs()} maxLength={isMobileScreen ? 2 : 4} />
32
-
);
55
+
return <Breadcrumbs links={getBreadrumbs()} maxLength={maxLength} />;
33
56
};
34
57
35
58
export default WithBreadcrumbs;
+5
util/stringUtils.ts
+5
util/stringUtils.ts
···
21
21
.replace(/^[ ]+|[ ]+$/gm, '')
22
22
// replaces leading numbers and dots from each line with an empty string
23
23
.replace(/^\d+\.\s/gm, '');
24
+
25
+
export const dashToCamelCase = (str: string) =>
26
+
str
27
+
.replace(/-([a-z])/g, (match, chr) => chr.toUpperCase())
28
+
.replace(/^[A-Z]/, chr => chr.toLowerCase());