[UI] Extract our ColorSample and Tag components from twenty-front to twenty-ui. (#5543)

Two more components extracted out of twenty-front: `ColorSample` and
`Tag`.
This commit is contained in:
Abdullah
2024-05-23 10:46:31 +05:00
committed by GitHub
parent 6b1d4e0744
commit b8eef21343
21 changed files with 66 additions and 65 deletions

View File

@ -1,7 +1,6 @@
import styled from '@emotion/styled';
import { IconMail } from 'twenty-ui';
import { IconMail, Tag } from 'twenty-ui';
import { Tag } from '@/ui/display/tag/components/Tag';
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
type EmailThreadHeaderProps = {

View File

@ -1,11 +1,10 @@
import React, { useContext, useState } from 'react';
import styled from '@emotion/styled';
import { IconDotsVertical } from 'twenty-ui';
import { IconDotsVertical, Tag } from 'twenty-ui';
import { RecordBoardColumnDropdownMenu } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnDropdownMenu';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { RecordBoardColumnHotkeyScope } from '@/object-record/record-board/types/BoardColumnHotkeyScope';
import { Tag } from '@/ui/display/tag/components/Tag';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';

View File

@ -1,5 +1,6 @@
import { Tag } from 'twenty-ui';
import { useMultiSelectField } from '@/object-record/record-field/meta-types/hooks/useMultiSelectField';
import { Tag } from '@/ui/display/tag/components/Tag';
import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList';
type MultiSelectFieldDisplayProps = {

View File

@ -1,4 +1,4 @@
import { Tag } from '@/ui/display/tag/components/Tag';
import { Tag } from 'twenty-ui';
import { useSelectField } from '../../hooks/useSelectField';

View File

@ -2,6 +2,7 @@ import { useMemo } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import {
ColorSample,
IconCheck,
IconDotsVertical,
IconGripVertical,
@ -12,7 +13,6 @@ import { v4 } from 'uuid';
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/utils/getOptionValueFromLabel';
import { ColorSample } from '@/ui/display/color/components/ColorSample';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { TextInput } from '@/ui/input/components/TextInput';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';

View File

@ -1,5 +1,6 @@
import { Tag } from 'twenty-ui';
import { ObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
import { Tag } from '@/ui/display/tag/components/Tag';
type SettingsDataModelObjectTypeTagProps = {
objectTypeLabel: ObjectTypeLabel;

View File

@ -1,41 +0,0 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { ThemeColor } from '@/ui/theme/constants/MainColorNames';
export type ColorSampleVariant = 'default' | 'pipeline';
export type ColorSampleProps = {
colorName: ThemeColor;
variant?: ColorSampleVariant;
};
const StyledColorSample = styled.div<ColorSampleProps>`
background-color: ${({ theme, colorName }) =>
theme.tag.background[colorName]};
border: 1px solid ${({ theme, colorName }) => theme.tag.text[colorName]};
border-radius: 60px;
height: ${({ theme }) => theme.spacing(4)};
width: ${({ theme }) => theme.spacing(3)};
${({ colorName, theme, variant }) => {
if (variant === 'pipeline')
return css`
align-items: center;
border: 0;
display: flex;
justify-content: center;
&:after {
background-color: ${theme.tag.text[colorName]};
border-radius: ${theme.border.radius.rounded};
content: '';
display: block;
height: ${theme.spacing(1)};
width: ${theme.spacing(1)};
}
`;
}}
`;
export { StyledColorSample as ColorSample };

View File

@ -1,24 +0,0 @@
import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from 'twenty-ui';
import { ColorSample } from '../ColorSample';
const meta: Meta<typeof ColorSample> = {
title: 'UI/Display/Color/ColorSample',
component: ColorSample,
decorators: [ComponentDecorator],
args: { colorName: 'green' },
argTypes: {
as: { control: false },
theme: { control: false },
},
};
export default meta;
type Story = StoryObj<typeof ColorSample>;
export const Default: Story = {};
export const Pipeline: Story = {
args: { variant: 'pipeline' },
};

View File

@ -1,77 +0,0 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconComponent, OverflowingTextWithTooltip } from 'twenty-ui';
import { ThemeColor } from '@/ui/theme/constants/MainColorNames';
import { themeColorSchema } from '@/ui/theme/utils/themeColorSchema';
const StyledTag = styled.h3<{
color: ThemeColor;
weight: TagWeight;
}>`
align-items: center;
background: ${({ color, theme }) => theme.tag.background[color]};
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ color, theme }) => theme.tag.text[color]};
display: inline-flex;
font-size: ${({ theme }) => theme.font.size.md};
font-style: normal;
font-weight: ${({ theme, weight }) =>
weight === 'regular'
? theme.font.weight.regular
: theme.font.weight.medium};
height: ${({ theme }) => theme.spacing(5)};
margin: 0;
overflow: hidden;
padding: 0 ${({ theme }) => theme.spacing(2)};
`;
const StyledContent = styled.span`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
const StyledIconContainer = styled.div`
display: flex;
margin-right: ${({ theme }) => theme.spacing(1)};
`;
type TagWeight = 'regular' | 'medium';
type TagProps = {
className?: string;
color: ThemeColor;
text: string;
Icon?: IconComponent;
onClick?: () => void;
weight?: TagWeight;
};
export const Tag = ({
className,
color,
text,
Icon,
onClick,
weight = 'regular',
}: TagProps) => {
const theme = useTheme();
return (
<StyledTag
className={className}
color={themeColorSchema.catch('gray').parse(color)}
onClick={onClick}
weight={weight}
>
{!!Icon && (
<StyledIconContainer>
<Icon size={theme.icon.size.sm} stroke={theme.icon.stroke.sm} />
</StyledIconContainer>
)}
<StyledContent>
<OverflowingTextWithTooltip text={text} />
</StyledContent>
</StyledTag>
);
};

View File

@ -1,66 +0,0 @@
import { Meta, StoryObj } from '@storybook/react';
import { expect, fn, userEvent, within } from '@storybook/test';
import { CatalogDecorator, CatalogStory, ComponentDecorator } from 'twenty-ui';
import {
MAIN_COLOR_NAMES,
ThemeColor,
} from '@/ui/theme/constants/MainColorNames';
import { Tag } from '../Tag';
const meta: Meta<typeof Tag> = {
title: 'UI/Display/Tag/Tag',
component: Tag,
args: {
text: 'Urgent',
},
};
export default meta;
type Story = StoryObj<typeof Tag>;
export const Default: Story = {
args: {
color: 'red',
onClick: fn(),
},
decorators: [ComponentDecorator],
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);
const tag = canvas.getByRole('heading', { level: 3 });
await userEvent.click(tag);
await expect(args.onClick).toHaveBeenCalled();
},
};
export const WithLongText: Story = {
decorators: [ComponentDecorator],
args: {
color: 'green',
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
},
parameters: {
container: { width: 100 },
},
};
export const Catalog: CatalogStory<Story, typeof Tag> = {
argTypes: {
color: { control: false },
},
parameters: {
catalog: {
dimensions: [
{
name: 'colors',
values: MAIN_COLOR_NAMES,
props: (color: ThemeColor) => ({ color }),
},
],
},
},
decorators: [CatalogDecorator],
};

View File

@ -1,10 +1,7 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { ColorSample, ColorSampleProps } from 'twenty-ui';
import {
ColorSample,
ColorSampleProps,
} from '@/ui/display/color/components/ColorSample';
import {
LightIconButton,
LightIconButtonProps,

View File

@ -2,9 +2,8 @@ import styled from '@emotion/styled';
import { expect } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/test';
import { ComponentDecorator } from 'packages/twenty-ui';
import { ComponentDecorator, Tag } from 'twenty-ui';
import { Tag } from '@/ui/display/tag/components/Tag';
import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList';
import { MAIN_COLOR_NAMES } from '@/ui/theme/constants/MainColorNames';

View File

@ -1,7 +1,6 @@
import styled from '@emotion/styled';
import { IconComponent } from 'twenty-ui';
import { IconComponent, Tag } from 'twenty-ui';
import { Tag } from '@/ui/display/tag/components/Tag';
import { Checkbox } from '@/ui/input/components/Checkbox';
import { MenuItemLeftContent } from '@/ui/navigation/menu-item/internals/components/MenuItemLeftContent';
import { ThemeColor } from '@/ui/theme/constants/MainColorNames';

View File

@ -1,4 +1,5 @@
import { Tag } from '@/ui/display/tag/components/Tag';
import { Tag } from 'twenty-ui';
import {
Checkbox,
CheckboxShape,

View File

@ -1,10 +1,6 @@
import { useTheme } from '@emotion/react';
import { IconCheck } from 'twenty-ui';
import { ColorSample, ColorSampleVariant, IconCheck } from 'twenty-ui';
import {
ColorSample,
ColorSampleVariant,
} from '@/ui/display/color/components/ColorSample';
import { ThemeColor } from '@/ui/theme/constants/MainColorNames';
import {

View File

@ -1,7 +1,6 @@
import { useTheme } from '@emotion/react';
import { IconCheck } from 'twenty-ui';
import { IconCheck, Tag } from 'twenty-ui';
import { Tag } from '@/ui/display/tag/components/Tag';
import { ThemeColor } from '@/ui/theme/constants/MainColorNames';
import { StyledMenuItemLeftContent } from '../internals/components/StyledMenuItemBase';

View File

@ -4,10 +4,10 @@ import {
CatalogDimension,
CatalogOptions,
CatalogStory,
ColorSampleVariant,
ComponentDecorator,
} from 'twenty-ui';
import { ColorSampleVariant } from '@/ui/display/color/components/ColorSample';
import {
MAIN_COLOR_NAMES,
ThemeColor,