Skip to content

Commit

Permalink
feat!: update link component
Browse files Browse the repository at this point in the history
- Wrapped Link atom with Next Link for better perfromance and NextJS support.
- Removed the condition to check for a Link being a button if href is not provided.
- Removed test to check if Link can act as a button.
  • Loading branch information
ishaan000 committed Nov 1, 2024
1 parent 808cb93 commit 0bf77f5
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 64 deletions.
33 changes: 16 additions & 17 deletions src/components/atoms/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { LinkProps } from '@components/atoms/Link';
import { Link as MuiLink } from '@mui/material';
import NextLink from 'next/link';
import React from 'react';

const Link: React.FC<LinkProps> = ({
Expand All @@ -17,13 +18,10 @@ const Link: React.FC<LinkProps> = ({
children,
ariaLabel,
role,
component,
...props
}) => {
if (!href && component !== 'button') {
throw new Error(
'The `href` prop is required unless `component="button"` is used.'
);
if (!href) {
throw new Error('The `href` prop is required for the `Link` component.');
}

const computedRel =
Expand All @@ -34,27 +32,28 @@ const Link: React.FC<LinkProps> = ({
: rel;

const linkProps = {
...(component !== 'button' && { href }),
href,
target,
rel: computedRel,
onClick,
'aria-label': ariaLabel,
role,
tabIndex,
component,
};

return (
<MuiLink
color={color}
sx={sx}
underline={underline}
variant={variant}
{...linkProps}
{...props}
>
{children}
</MuiLink>
<NextLink href={href} legacyBehavior passHref>
<MuiLink
color={color}
sx={sx}
underline={underline}
variant={variant}
{...linkProps}
{...props}
>
{children}
</MuiLink>
</NextLink>
);
};

Expand Down
48 changes: 1 addition & 47 deletions tests/components/atoms/Link.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,6 @@ describe('Link component', () => {
expect(handleClick).toHaveBeenCalledTimes(1);
});

it('renders as a button when component="button"', () => {
const handleClick = jest.fn();
render(
<Link component="button" onClick={handleClick}>
Button Link
</Link>
);
const buttonElement = screen.getByRole('button', { name: 'Button Link' });
expect(buttonElement.tagName).toBe('BUTTON');
expect(buttonElement).not.toHaveAttribute('href');
fireEvent.click(buttonElement);
expect(handleClick).toHaveBeenCalledTimes(1);
});

it('applies aria-label when provided', () => {
render(<Link {...defaultProps} ariaLabel="Custom Aria Label" />);
const linkElement = screen.getByLabelText('Custom Aria Label');
Expand All @@ -80,39 +66,7 @@ describe('Link component', () => {
expect(linkElement).toBeInTheDocument();
});

it('supports custom components via the "component" prop', () => {
const CustomComponent = React.forwardRef<
HTMLAnchorElement,
React.AnchorHTMLAttributes<HTMLAnchorElement>
>((props, ref) => (
<a data-testid="custom-component" ref={ref} {...props} />
));

CustomComponent.displayName = 'CustomComponent';

render(
<Link component={CustomComponent} href="/custom">
Custom Component Link
</Link>
);

const customElement = screen.getByTestId('custom-component');
expect(customElement).toBeInTheDocument();
expect(customElement).toHaveAttribute('href', '/custom');
expect(customElement).toHaveTextContent('Custom Component Link');
});

it('handles missing href when component is "button"', () => {
render(<Link component="button">Button without href</Link>);
const buttonElement = screen.getByRole('button', {
name: 'Button without href',
});
expect(buttonElement).toBeInTheDocument();
expect(buttonElement.tagName).toBe('BUTTON');
expect(buttonElement).not.toHaveAttribute('href');
});

it('throws an error when href is missing and component is not "button"', () => {
it('throws an error when href is missing', () => {
console.error = jest.fn();
expect(() => {
render(<Link>Link without href</Link>);
Expand Down

0 comments on commit 0bf77f5

Please sign in to comment.