fix #7085 breadcrumb fix for mobile viewport (#7419)

ISSUE
Closes https://github.com/twentyhq/twenty/issues/7085

DEMO 


https://github.com/user-attachments/assets/39692906-c02e-4e4c-9205-82447fa142df

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
NitinPSingh
2024-10-31 22:47:13 +05:30
committed by GitHub
parent 74291e531c
commit e5641c5c53
9 changed files with 122 additions and 9 deletions

View File

@ -1,7 +1,10 @@
import { InformationBannerWrapper } from '@/information-banner/components/InformationBannerWrapper';
import {
Breadcrumb,
BreadcrumbProps,
} from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import styled from '@emotion/styled';
import { JSX, ReactNode } from 'react';
import { Breadcrumb, BreadcrumbProps } from 'twenty-ui';
import { PageBody } from './PageBody';
import { PageHeader } from './PageHeader';

View File

@ -0,0 +1,70 @@
import { MobileBreadcrumb } from '@/ui/navigation/bread-crumb/components/MobileBreadcrumb';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import styled from '@emotion/styled';
import { Fragment, ReactNode } from 'react';
import { Link } from 'react-router-dom';
export type BreadcrumbProps = {
className?: string;
links: { children: string | ReactNode; href?: string }[];
};
const StyledWrapper = styled.nav`
align-items: center;
color: ${({ theme }) => theme.font.color.tertiary};
display: grid;
font-size: ${({ theme }) => theme.font.size.md};
grid-auto-flow: column;
grid-column-gap: ${({ theme }) => theme.spacing(1)};
max-width: 100%;
min-width: 0;
height: ${({ theme }) => theme.spacing(8)};
`;
const StyledLink = styled(Link)`
color: inherit;
text-decoration: none;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
const StyledText = styled.span`
color: ${({ theme }) => theme.font.color.primary};
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
const StyledDivider = styled.span`
width: ${({ theme }) => theme.spacing(2)};
`;
export const Breadcrumb = ({ className, links }: BreadcrumbProps) => {
const isMobile = useIsMobile();
if (isMobile && links.length > 0) {
return <MobileBreadcrumb className={className} links={links} />;
}
return (
<StyledWrapper className={className}>
{links.map((link, index) => {
const text = typeof link.children === 'string' ? link.children : '';
return (
<Fragment key={index}>
{link.href ? (
<StyledLink title={text} to={link.href}>
{link.children}
</StyledLink>
) : (
<StyledText title={text}>{link.children}</StyledText>
)}
{index < links.length - 1 && <StyledDivider>/</StyledDivider>}
</Fragment>
);
})}
</StyledWrapper>
);
};

View File

@ -0,0 +1,81 @@
import { useOpenSettingsMenu } from '@/navigation/hooks/useOpenSettings';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { isNonEmptyString } from '@sniptt/guards';
import { ReactNode } from 'react';
import { Link } from 'react-router-dom';
import { IconChevronLeft } from 'twenty-ui';
export type MobileBreadcrumbProps = {
className?: string;
links: { children: string | ReactNode; href?: string }[];
};
const StyledWrapper = styled.nav`
align-items: center;
color: ${({ theme }) => theme.font.color.tertiary};
display: grid;
font-size: ${({ theme }) => theme.font.size.md};
grid-auto-flow: column;
grid-column-gap: ${({ theme }) => theme.spacing(1)};
max-width: 100%;
min-width: 0;
height: ${({ theme }) => theme.spacing(8)};
`;
const StyledLink = styled(Link)`
color: inherit;
text-decoration: none;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
const StyledText = styled.span`
color: inherit;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
export const MobileBreadcrumb = ({
className,
links,
}: MobileBreadcrumbProps) => {
const theme = useTheme();
const { openSettingsMenu } = useOpenSettingsMenu();
const handleBackToSettingsClick = () => {
openSettingsMenu();
};
const previousLink = links[links.length - 2];
const shouldRedirectToSettings = links.length === 2;
const text = isNonEmptyString(previousLink.children)
? previousLink.children
: '';
return (
<StyledWrapper className={className}>
{shouldRedirectToSettings ? (
<>
<IconChevronLeft size={theme.icon.size.md} />
<StyledText onClick={handleBackToSettingsClick}>
Back to Settings
</StyledText>
</>
) : previousLink?.href ? (
<>
<IconChevronLeft size={theme.icon.size.md} />
<StyledLink title={text} to={previousLink.href}>
Back to {previousLink.children}
</StyledLink>
</>
) : (
<StyledText title={text}>{previousLink?.children}</StyledText>
)}
</StyledWrapper>
);
};

View File

@ -1,5 +1,6 @@
import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator, Breadcrumb } from 'twenty-ui';
import { ComponentDecorator } from 'twenty-ui';
import { Breadcrumb } from '../Breadcrumb';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';