My personal website
1import { Link } from '@/components/Link/Link';
2import React from 'react';
3import { useLocation } from 'react-router-dom';
4import * as styles from './Breadcrumb.styles';
5import { ARIA_LABEL, DEFAULT_BASE, SEPARATOR_ICON } from './Breadcrumb.constants';
6import { BreadcrumbPath, BreadcrumbProps } from './Breadcrumb.types';
7
8const Breadcrumb: React.FC<BreadcrumbProps> = ({ base = DEFAULT_BASE }) => {
9 const location = useLocation();
10 const { pathname } = location;
11
12 // Split the pathname and filter out empty strings
13 const paths = pathname.split('/').filter(Boolean);
14
15 // If on the home page, show only the base and return early
16 if (paths.length === 0) {
17 return (
18 <nav aria-label={ARIA_LABEL}>
19 <ol className={styles.breadcrumbList}>
20 <li className={styles.breadcrumbItem}>
21 <span className={styles.currentPage}>{base}</span>
22 </li>
23 </ol>
24 </nav>
25 );
26 }
27
28 // Build breadcrumb links for all other paths
29 const breadcrumbPaths: BreadcrumbPath[] = paths.map((path, index) => {
30 const href = `/${paths.slice(0, index + 1).join('/')}`;
31 const name = path.charAt(0).toUpperCase() + path.slice(1);
32 return { name, href };
33 });
34
35 return (
36 <nav aria-label={ARIA_LABEL}>
37 <ol className={styles.breadcrumbList}>
38 <li className={styles.breadcrumbItem}>
39 <Link to="/">{base}</Link>
40 <svg className={styles.separator} {...SEPARATOR_ICON}>
41 <path d={SEPARATOR_ICON.path}></path>
42 </svg>
43 </li>
44 {breadcrumbPaths.map((path, index) => (
45 <li key={index} className={styles.breadcrumbItem}>
46 {index === breadcrumbPaths.length - 1 ? (
47 // If it's the last item, display it as text (not a link)
48 <span className={styles.currentPage}>{path.name}</span>
49 ) : (
50 // Otherwise, display it as a link
51 <Link to={path.href}>
52 {path.name}
53 <svg className={styles.separator} {...SEPARATOR_ICON}>
54 <path d={SEPARATOR_ICON.path}></path>
55 </svg>
56 </Link>
57 )}
58 </li>
59 ))}
60 </ol>
61 </nav>
62 );
63};
64
65export default Breadcrumb;