diff --git a/packages/ui/src/components/Breadcrumb/Breadcrumb.test.tsx b/packages/ui/src/components/Breadcrumb/Breadcrumb.test.tsx
new file mode 100644
index 000000000..489795eb2
--- /dev/null
+++ b/packages/ui/src/components/Breadcrumb/Breadcrumb.test.tsx
@@ -0,0 +1,93 @@
+import { render, screen } from '@testing-library/react';
+import Link from 'next/link';
+import { Breadcrumbs } from './index';
+import '@testing-library/jest-dom';
+
+describe('Breadcrumb navigation', () => {
+ const props = {
+ label: 'Kruimelpad',
+ links: [
+ {
+ href: 'https://www.utrecht.nl/',
+ label: 'Home',
+ current: false,
+ rel: 'home',
+ },
+ {
+ href: '/',
+ label: 'Online loket',
+ current: true,
+ },
+ ],
+ backLink: {
+ href: '/',
+ label: 'Online loket',
+ current: false,
+ },
+ Link: Link,
+ };
+
+ it('renders a navigation landmark', () => {
+ render();
+
+ const navigation = screen.getByRole('navigation', { name: 'Kruimelpad' });
+
+ expect(navigation).toBeInTheDocument();
+ });
+
+ it('renders links', () => {
+ render();
+
+ const links = screen.getAllByRole('link');
+
+ expect(links.length).toBe(props.links.length);
+ });
+
+ it('renders a link', () => {
+ render();
+
+ const link = screen.getByRole('link', { name: 'Home' });
+
+ expect(link).toBeInTheDocument();
+ expect(link).toHaveAttribute('href', 'https://www.utrecht.nl/');
+ expect(link).toHaveAttribute('rel', 'home');
+ });
+
+ it('renders a current link', () => {
+ render();
+
+ const link = screen.getByRole('link', { name: 'Online loket', current: 'page' });
+
+ expect(link).toBeInTheDocument();
+ });
+
+ it('renders no separator for one link', () => {
+ const { container } = render();
+
+ const separator = container.querySelector('.utrecht-breadcrumb-nav__separator');
+
+ expect(separator).not.toBeInTheDocument();
+ });
+
+ it('renders separators between items', () => {
+ const { container } = render();
+
+ const separators = container.querySelectorAll(
+ '.utrecht-breadcrumb-nav__item + .utrecht-breadcrumb-nav__separator + .utrecht-breadcrumb-nav__item',
+ );
+
+ expect(separators.length).toBe(props.links.length - 1);
+ });
+
+ it('renders a custom Link component', () => {
+ const { container } = render(
+ } />,
+ );
+
+ const links = container.querySelectorAll('.custom-link');
+
+ expect(links.length).toBe(props.links.length);
+ });
+
+ // TODO: Test small screen breadcrumb
+});
diff --git a/packages/ui/src/components/Breadcrumb/index.module.scss b/packages/ui/src/components/Breadcrumb/index.module.scss
index 8708698fc..953e64182 100644
--- a/packages/ui/src/components/Breadcrumb/index.module.scss
+++ b/packages/ui/src/components/Breadcrumb/index.module.scss
@@ -16,6 +16,12 @@
margin-inline-end: 8px;
}
+@media (width >= 360px) {
+ .utrecht-breadcrumb-nav__separator {
+ margin-inline-end: var(--utrecht-space-inline-xs);
+ }
+}
+
.utrecht-breadcrumb-nav__link {
--utrecht-link-focus-color: var(--utrecht-color-black);
diff --git a/packages/ui/src/components/Breadcrumb/index.tsx b/packages/ui/src/components/Breadcrumb/index.tsx
index 808acab4f..ce0618596 100644
--- a/packages/ui/src/components/Breadcrumb/index.tsx
+++ b/packages/ui/src/components/Breadcrumb/index.tsx
@@ -12,21 +12,24 @@ import './index.module.scss';
import styles from './index.module.scss';
import { useScreenSize } from '../../hooks';
+export const extendLink = (link: BreadcrumbLinkType) => ({
+ // Use default `rel`, but actual optional rel should override this
+ rel: link.current ? undefined : link.href === '/' ? 'home' : 'up',
+ ...link,
+});
+
const css = classnames.bind(styles);
type BreadcrumbLinkType = {
href: string;
label: string;
current: boolean;
+ rel?: string;
};
interface BreadcrumbProps extends BreadcrumbNavProps {
links: BreadcrumbLinkType[];
Link?: ComponentType;
- backLink?: {
- href: string;
- label: string;
- current: boolean;
- };
+ backLink?: BreadcrumbLinkType;
breakpoint?: number;
}
@@ -41,59 +44,51 @@ export const Breadcrumbs = ({
const smallScreen = Number(screenSize) <= breakpoint;
- if (smallScreen && backLink?.href && backLink.label) {
+ const linkData = links.map(extendLink);
+ const backLinkData = backLink && extendLink(backLink);
+
+ if (
+ (smallScreen && backLinkData?.href && backLinkData.label) ||
+ (links.length === 1 && backLinkData?.href && backLinkData.label)
+ ) {
return (
-
-
-
- {backLink?.label?.toLowerCase() !== 'home' && (
-
-
-
- )}
- {backLink.label}
-
-
+
+
+ {backLinkData?.rel === 'up' && } {backLinkData.label}
+
);
}
return (
-
- {links &&
- links.length > 0 &&
- links
- .filter(({ label }) => label)
- .map(({ href, label, current }: any, index: number) => (
-
-
- {links.length === 1 && label?.toLowerCase() !== 'home' && (
-
-
-
- )}
- {label}
- {index !== links.length - 1 && (
-
-
-
- )}
-
-
- ))}
+
+ {linkData
+ .filter(({ label }) => label)
+ .map(({ href, label, current, rel }: any, index: number) => (
+
+
+ {label}
+
+ {index !== links.length - 1 && (
+
+
+
+ )}
+
+ ))}
);
};