Added Linaria for performance optimization (#5693)
- Added Linaria to have compiled CSS on our optimized field displays - Refactored mocks for performance stories on fields - Refactored generateRecordChipData into a global context, computed only when we fetch object metadata items. - Refactored ChipFieldDisplay - Refactored PhoneFieldDisplay
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledEllipsisDisplay = styled.div<{ maxWidth?: number }>`
|
||||
max-width: ${({ maxWidth }) => maxWidth ?? '100%'};
|
||||
@ -19,7 +19,7 @@ export const EllipsisDisplay = ({
|
||||
maxWidth,
|
||||
className,
|
||||
}: EllipsisDisplayProps) => (
|
||||
<StyledEllipsisDisplay style={{ maxWidth }} className={className}>
|
||||
<StyledEllipsisDisplay maxWidth={maxWidth} className={className}>
|
||||
{children}
|
||||
</StyledEllipsisDisplay>
|
||||
);
|
||||
|
||||
@ -1,27 +1,39 @@
|
||||
import { MouseEvent } from 'react';
|
||||
import { isValidPhoneNumber, parsePhoneNumber } from 'libphonenumber-js';
|
||||
import { parsePhoneNumber, PhoneNumber } from 'libphonenumber-js';
|
||||
|
||||
import { ContactLink } from '@/ui/navigation/link/components/ContactLink';
|
||||
|
||||
import { EllipsisDisplay } from './EllipsisDisplay';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
type PhoneDisplayProps = {
|
||||
value: string | null;
|
||||
};
|
||||
|
||||
export const PhoneDisplay = ({ value }: PhoneDisplayProps) => (
|
||||
<EllipsisDisplay>
|
||||
{value && isValidPhoneNumber(value) ? (
|
||||
<ContactLink
|
||||
href={parsePhoneNumber(value, 'FR')?.getURI()}
|
||||
onClick={(event: MouseEvent<HTMLElement>) => {
|
||||
event.stopPropagation();
|
||||
}}
|
||||
>
|
||||
{parsePhoneNumber(value, 'FR')?.formatNational() || value}
|
||||
</ContactLink>
|
||||
) : (
|
||||
<ContactLink href="#">{value}</ContactLink>
|
||||
)}
|
||||
</EllipsisDisplay>
|
||||
);
|
||||
// TODO: see if we can find a faster way to format the phone number
|
||||
export const PhoneDisplay = ({ value }: PhoneDisplayProps) => {
|
||||
if (!isDefined(value)) {
|
||||
return <ContactLink href="#">{value}</ContactLink>;
|
||||
}
|
||||
|
||||
let parsedPhoneNumber: PhoneNumber | null = null;
|
||||
|
||||
try {
|
||||
// TODO: parse according to locale not hard coded FR
|
||||
parsedPhoneNumber = parsePhoneNumber(value, 'FR');
|
||||
} catch (error) {
|
||||
return <ContactLink href="#">{value}</ContactLink>;
|
||||
}
|
||||
|
||||
const URI = parsedPhoneNumber.getURI();
|
||||
const formattedNational = parsedPhoneNumber?.formatNational();
|
||||
|
||||
return (
|
||||
<ContactLink
|
||||
href={URI}
|
||||
onClick={(event: MouseEvent<HTMLElement>) => {
|
||||
event.stopPropagation();
|
||||
}}
|
||||
>
|
||||
{formattedNational || value}
|
||||
</ContactLink>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { ComponentDecorator } from 'twenty-ui';
|
||||
|
||||
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Input/EllipsisDisplay/EllipsisDisplay',
|
||||
component: EllipsisDisplay,
|
||||
decorators: [ComponentDecorator],
|
||||
args: {
|
||||
maxWidth: 100,
|
||||
children: 'This is a long text that should be truncated',
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof EllipsisDisplay>;
|
||||
|
||||
export const Default: Story = {};
|
||||
@ -1,4 +1,4 @@
|
||||
import { Meta } from '@storybook/react';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { ComponentDecorator } from 'twenty-ui';
|
||||
|
||||
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
|
||||
@ -19,6 +19,10 @@ const meta: Meta = {
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof EllipsisDisplay>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Performance = getProfilingStory({
|
||||
componentName: 'EllipsisDisplay',
|
||||
averageThresholdInMs: 0.1,
|
||||
|
||||
@ -1,43 +1,47 @@
|
||||
import * as React from 'react';
|
||||
import { Link as ReactLink } from 'react-router-dom';
|
||||
import styled from '@emotion/styled';
|
||||
import { Theme, withTheme } from '@emotion/react';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
const StyledClickableLink = withTheme(styled.a<{
|
||||
theme: Theme;
|
||||
maxWidth?: number;
|
||||
}>`
|
||||
color: inherit;
|
||||
overflow: hidden;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: ${({ theme }) => theme.border.color.strong};
|
||||
text-overflow: ellipsis;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
|
||||
max-width: ${({ maxWidth }) => maxWidth ?? '100%'};
|
||||
|
||||
&:hover {
|
||||
text-decoration-color: ${({ theme }) => theme.font.color.primary};
|
||||
}
|
||||
`);
|
||||
|
||||
type ContactLinkProps = {
|
||||
className?: string;
|
||||
href: string;
|
||||
children?: React.ReactNode;
|
||||
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
||||
maxWidth?: number;
|
||||
};
|
||||
|
||||
const StyledClickable = styled.div`
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
overflow: hidden;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: ${({ theme }) => theme.border.color.strong};
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:hover {
|
||||
text-decoration-color: ${({ theme }) => theme.font.color.primary};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const ContactLink = ({
|
||||
className,
|
||||
href,
|
||||
children,
|
||||
onClick,
|
||||
maxWidth,
|
||||
}: ContactLinkProps) => (
|
||||
<div>
|
||||
<StyledClickable className={className}>
|
||||
<ReactLink target="_blank" onClick={onClick} to={href}>
|
||||
{children}
|
||||
</ReactLink>
|
||||
</StyledClickable>
|
||||
</div>
|
||||
<StyledClickableLink
|
||||
maxWidth={maxWidth}
|
||||
target="_blank"
|
||||
onClick={onClick}
|
||||
href={href}
|
||||
>
|
||||
{children}
|
||||
</StyledClickableLink>
|
||||
);
|
||||
|
||||
@ -10,7 +10,6 @@ const meta: Meta<typeof ContactLink> = {
|
||||
component: ContactLink,
|
||||
decorators: [ComponentWithRouterDecorator],
|
||||
args: {
|
||||
className: 'ContactLink',
|
||||
href: '/test',
|
||||
children: 'Contact Link',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user