1. Disable self links in breadcrumbs
2. Make the disabled link unclickable
This commit is contained in:
Xuebing Li 2024-03-15 16:13:58 +09:00
parent 7bb87f58a2
commit 0c6cf62361
3 changed files with 53 additions and 2 deletions

View File

@ -3,6 +3,8 @@ import React, { FunctionComponent, ReactElement } from 'react';
import Icon from '../Icon/Icon';
import IconProp from 'Common/Types/Icon/IconProp';
import UILink from '../Link/Link';
import Route from 'Common/Types/API/Route';
import URL from 'Common/Types/API/URL';
interface ComponentProps {
links: Array<Link>;
@ -39,7 +41,11 @@ const Breadcrumbs: FunctionComponent<ComponentProps> = ({
icon={IconProp.ChevronRight}
/>
<UILink
to={link.to}
to={
isCurrentPage(link.to)
? null // Avoid linking to current page
: link.to
}
className="ml-1 text-sm font-medium text-gray-500 hover:text-gray-700 -mt-1"
>
{link.title}
@ -54,4 +60,8 @@ const Breadcrumbs: FunctionComponent<ComponentProps> = ({
);
};
function isCurrentPage(linkTo: Route | URL): boolean {
return linkTo.toString() === window.location.pathname;
}
export default Breadcrumbs;

View File

@ -38,10 +38,14 @@ const Link: FunctionComponent<ComponentProps> = (
linkProps['href'] = props.to?.toString();
}
const cursorClassName: string = props.to
? 'cursor-pointer'
: 'cursor-default';
return (
<a
id={props.id}
className={`cursor-pointer ${props.className || ''}`}
className={`${cursorClassName} ${props.className || ''}`}
onMouseOver={props.onMouseOver}
onMouseOut={props.onMouseOut}
onMouseLeave={props.onMouseLeave}

View File

@ -7,6 +7,7 @@ import renderer, {
} from 'react-test-renderer';
import Breadcrumbs from '../../Components/Breadcrumbs/Breadcrumbs';
import Link from 'Common/Types/Link';
import Navigation from '../../Utils/Navigation';
describe('Breadcrumbs', () => {
test('Should render correctly and also contain "Home" and "Projects" string', () => {
const links: Array<Link> = [
@ -42,4 +43,40 @@ describe('Breadcrumbs', () => {
]
).toEqual('Projects');
});
test('Should avoid linking to the current page', () => {
// Mock `window.location.pathname`
Object.defineProperty(window, 'location', {
get() {
return { pathname: '/projects' };
},
});
// Render component
const links: Array<Link> = [
{
title: 'Home',
to: new Route('/'),
},
{
title: 'Projects',
to: new Route('/projects'),
},
];
const testRenderer: ReactTestRenderer = renderer.create(
<Breadcrumbs links={links} />
);
const testInstance: ReactTestInstance = testRenderer.root;
// Assert cursor style
const anchors: ReactTestInstance[] = testInstance.findAllByType('a');
expect(anchors[0]?.props['className']).toContain('cursor-pointer');
expect(anchors[1]?.props['className']).toContain('cursor-default');
// Set up spy on navigation
jest.spyOn(Navigation, 'navigate');
// Assert the second link does not navigate
anchors[1]?.props['onClick']();
expect(Navigation.navigate).not.toHaveBeenCalled();
// Assert the first link navigates
anchors[0]?.props['onClick']();
expect(Navigation.navigate).toHaveBeenCalledTimes(1);
});
});