Create ESLint rule to discourage usage of navigate() and prefer Link (#5642)

### Description
Create ESLint rule to discourage usage of navigate() and prefer Link


### Refs
#5468 

### Demo

![Capture-2024-05-29-112852](https://github.com/twentyhq/twenty/assets/140154534/28378c09-86bb-49d3-9e9a-49aa1c07ad11)

![Capture-2024-05-29-112843](https://github.com/twentyhq/twenty/assets/140154534/2c05ea92-e19b-49ae-acb9-07f6ec9182ab)

Fixes #5468

---------

Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com>
Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: Matheus <matheus_benini@hotmail.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
gitstart-twenty
2024-06-04 11:04:57 -04:00
committed by GitHub
parent 234e062232
commit bb7d94a455
18 changed files with 317 additions and 132 deletions

View File

@ -0,0 +1,25 @@
import React from 'react';
import { Link } from 'react-router-dom';
import styled from '@emotion/styled';
const StyledUndecoratedLink = styled(Link)`
text-decoration: none;
`;
type UndecoratedLinkProps = {
to: string | number;
children: React.ReactNode;
replace?: boolean;
};
export const UndecoratedLink = ({
children,
to,
replace = false,
}: UndecoratedLinkProps) => {
return (
<StyledUndecoratedLink to={to as string} replace={replace}>
{children}
</StyledUndecoratedLink>
);
};

View File

@ -0,0 +1,32 @@
import { expect } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/test';
import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
const meta: Meta<typeof UndecoratedLink> = {
title: 'UI/navigation/link/UndecoratedLink',
component: UndecoratedLink,
decorators: [ComponentWithRouterDecorator],
};
export default meta;
type Story = StoryObj<typeof UndecoratedLink>;
export const Default: Story = {
args: {
children: 'Go Home',
to: '/home',
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const link = canvas.getByText('Go Home');
await userEvent.click(link);
const href = link.getAttribute('href');
expect(href).toBe('/home');
},
};

View File

@ -1,9 +1,9 @@
import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { IconChevronLeft } from 'twenty-ui';
import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
type NavigationDrawerBackButtonProps = {
@ -36,22 +36,19 @@ export const NavigationDrawerBackButton = ({
title,
}: NavigationDrawerBackButtonProps) => {
const theme = useTheme();
const navigate = useNavigate();
const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState);
return (
<StyledContainer>
<StyledIconAndButtonContainer
onClick={() => {
navigate(navigationMemorizedUrl, { replace: true });
}}
>
<IconChevronLeft
size={theme.icon.size.md}
stroke={theme.icon.stroke.lg}
/>
<span>{title}</span>
</StyledIconAndButtonContainer>
<UndecoratedLink to={navigationMemorizedUrl} replace>
<StyledIconAndButtonContainer>
<IconChevronLeft
size={theme.icon.size.md}
stroke={theme.icon.stroke.lg}
/>
<span>{title}</span>
</StyledIconAndButtonContainer>
</UndecoratedLink>
</StyledContainer>
);
};