refactor: move Checkmark, Avatar, Chip and Tooltip to twenty-ui (#4946)

Split from https://github.com/twentyhq/twenty/pull/4518

Part of #4766
This commit is contained in:
Thaïs 2024-04-15 12:05:06 +02:00 committed by GitHub
parent acc2092b95
commit b6d0b8a895
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
93 changed files with 225 additions and 189 deletions

View File

@ -107,7 +107,7 @@ Handles overflowing text and displays a tooltip when the text overflows.
<SandpackEditor
availableComponentPaths={['@/ui/display/tooltip/OverflowingTextWithTooltip']}
availableComponentPaths={['twenty-ui']}
componentCode={overflowingTextWithTooltipCode}
/>

View File

@ -17,7 +17,7 @@ Represents a successful or completed action.
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/checkmark/components/Checkmark']}
availableComponentPaths={['twenty-ui']}
componentCode={checkmarkCode}
/>
@ -40,7 +40,7 @@ Represents a checkmark icon with the added feature of animation.
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/checkmark/components/AnimatedCheckmark']}
availableComponentPaths={['twenty-ui']}
componentCode={animatedCheckmarkCode}
/>

View File

@ -18,7 +18,7 @@ A visual element that you can use as a clickable or non-clickable container with
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/Chip']}
availableComponentPaths={['twenty-ui']}
componentCode={chipCode}
/>
</TabItem>
@ -117,8 +117,8 @@ A visual element that you can use as a clickable or non-clickable container with
### Transparent Disabled Chip
<SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/Chip']}
componentCode={`import { Chip } from "@/ui/display/chip/components/Chip";
availableComponentPaths={['twenty-ui']}
componentCode={`import { Chip } from "twenty-ui";
export const MyComponent = () => {
return (
@ -144,8 +144,8 @@ export const MyComponent = () => {
### Disabled Chip with Tooltip
<SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/Chip']}
componentCode={`import { Chip } from "@/ui/display/chip/components/Chip";
availableComponentPaths={['twenty-ui']}
componentCode={`import { Chip } from "twenty-ui";
export const MyComponent = () => {
return (
@ -176,7 +176,7 @@ A Chip-like element to display information about an entity.
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/EntityChip', 'twenty-ui']}
availableComponentPaths={['twenty-ui']}
componentCode={entityChipCode}
/>
</TabItem >

View File

@ -1,4 +1,4 @@
import { AnimatedCheckmark } from "@/ui/display/checkmark/components/AnimatedCheckmark";
import { AnimatedCheckmark } from 'twenty-ui';
export const MyComponent = () => {
return (
@ -9,6 +9,4 @@ export const MyComponent = () => {
size={30}
/>
);
};

View File

@ -1,4 +1,4 @@
import { Checkmark } from "@/ui/display/checkmark/components/Checkmark";
import { Checkmark } from 'twenty-ui';
export const MyComponent = () => {
return <Checkmark />;

View File

@ -1,4 +1,4 @@
import { Chip } from "@/ui/display/chip/components/Chip";
import { Chip } from 'twenty-ui';
export const MyComponent = () => {
return (

View File

@ -1,7 +1,5 @@
import { BrowserRouter as Router } from 'react-router-dom';
import { IconTwentyStar } from 'twenty-ui';
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
import { EntityChip, IconTwentyStar } from 'twenty-ui';
export const MyComponent = () => {
return (

View File

@ -1,8 +1,8 @@
import { OverflowingTextWithTooltip } from "@/ui/display/tooltip/OverflowingTextWithTooltip";
import { OverflowingTextWithTooltip } from 'twenty-ui';
export const MyComponent = () => {
const crmTaskDescription =
"Follow up with client regarding their recent product inquiry. Discuss pricing options, address any concerns, and provide additional product information. Record the details of the conversation in the CRM for future reference.";
'Follow up with client regarding their recent product inquiry. Discuss pricing options, address any concerns, and provide additional product information. Record the details of the conversation in the CRM for future reference.';
return <OverflowingTextWithTooltip text={crmTaskDescription} />;
};

View File

@ -1,7 +1,13 @@
import React from 'react';
import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconCalendarEvent } from 'twenty-ui';
import {
Chip,
ChipAccent,
ChipSize,
ChipVariant,
IconCalendarEvent,
} from 'twenty-ui';
import { CalendarEventParticipantsResponseStatus } from '@/activities/calendar/components/CalendarEventParticipantsResponseStatus';
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
@ -11,12 +17,6 @@ import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/util
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox';
import {
Chip,
ChipAccent,
ChipSize,
ChipVariant,
} from '@/ui/display/chip/components/Chip';
import { mapArrayToObject } from '~/utils/array/mapArrayToObject';
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';

View File

@ -3,7 +3,7 @@ import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { format } from 'date-fns';
import { useRecoilValue } from 'recoil';
import { IconArrowRight, IconLock } from 'twenty-ui';
import { Avatar, AvatarGroup, IconArrowRight, IconLock } from 'twenty-ui';
import { CalendarCurrentEventCursor } from '@/activities/calendar/components/CalendarCurrentEventCursor';
import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext';
@ -14,9 +14,8 @@ import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEv
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { Card } from '@/ui/layout/card/components/Card';
import { CardContent } from '@/ui/layout/card/components/CardContent';
import { Avatar } from '@/users/components/Avatar';
import { AvatarGroup } from '@/users/components/AvatarGroup';
import { TimelineCalendarEvent } from '~/generated-metadata/graphql';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { isDefined } from '~/utils/isDefined';
type CalendarEventRowProps = {
@ -161,7 +160,7 @@ export const CalendarEventRow = ({
key={[participant.workspaceMemberId, participant.displayName]
.filter(isDefined)
.join('-')}
avatarUrl={participant.avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(participant.avatarUrl)}
placeholder={
participant.firstName && participant.lastName
? `${participant.firstName} ${participant.lastName}`

View File

@ -1,12 +1,13 @@
import { Tooltip } from 'react-tooltip';
import styled from '@emotion/styled';
import { Avatar } from 'twenty-ui';
import { Comment } from '@/activities/types/Comment';
import { Avatar } from '@/users/components/Avatar';
import {
beautifyExactDateTime,
beautifyPastDateRelativeToNow,
} from '~/utils/date-utils';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledContainer = styled.div`
align-items: center;
@ -75,7 +76,7 @@ export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => {
<StyledContainer>
<StyledLeftContainer>
<Avatar
avatarUrl={avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
size="md"
entityId={author?.id}
placeholder={authorName}

View File

@ -1,10 +1,10 @@
import { useMemo } from 'react';
import styled from '@emotion/styled';
import { Chip, ChipVariant } from 'twenty-ui';
import { v4 } from 'uuid';
import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject';
import { RecordChip } from '@/object-record/components/RecordChip';
import { Chip, ChipVariant } from '@/ui/display/chip/components/Chip';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { RGBA } from '@/ui/theme/constants/Rgba';

View File

@ -1,14 +1,15 @@
import { useTheme } from '@emotion/react';
import { useRecoilState } from 'recoil';
import { IconCheckbox, IconNotes } from 'twenty-ui';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import {
Chip,
ChipAccent,
ChipSize,
ChipVariant,
} from '@/ui/display/chip/components/Chip';
IconCheckbox,
IconNotes,
} from 'twenty-ui';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
type ActivityTypeDropdownProps = {
activityId: string;

View File

@ -1,9 +1,10 @@
import styled from '@emotion/styled';
import { Avatar } from 'twenty-ui';
import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { RecordChip } from '@/object-record/components/RecordChip';
import { Avatar } from '@/users/components/Avatar';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledAvatar = styled(Avatar)`
margin-right: ${({ theme }) => theme.spacing(1)};
@ -67,7 +68,7 @@ export const ParticipantChip = ({
) : (
<StyledChip>
<StyledAvatar
avatarUrl={avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
type="rounded"
placeholder={displayName}
size="sm"

View File

@ -1,8 +1,8 @@
import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from 'twenty-ui';
import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant';
import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
type EmailThreadMessageReceiversProps = {
receivers: EmailThreadMessageParticipant[];

View File

@ -1,6 +1,7 @@
import { useRef } from 'react';
import styled from '@emotion/styled';
import { useRecoilCallback } from 'recoil';
import { Avatar } from 'twenty-ui';
import { EmailThreadNotShared } from '@/activities/emails/components/EmailThreadNotShared';
import { useEmailThread } from '@/activities/emails/hooks/useEmailThread';
@ -8,9 +9,9 @@ import { emailThreadIdWhenEmailThreadWasClosedState } from '@/activities/emails/
import { CardContent } from '@/ui/layout/card/components/CardContent';
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
import { GRAY_SCALE } from '@/ui/theme/constants/GrayScale';
import { Avatar } from '@/users/components/Avatar';
import { TimelineThread } from '~/generated/graphql';
import { formatToHumanReadableDate } from '~/utils';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledCardContent = styled(CardContent)<{ visibility: string }>`
align-items: center;
@ -152,20 +153,24 @@ export const EmailThreadPreview = ({
<StyledHeading unread={!thread.read}>
<StyledParticipantsContainer>
<Avatar
avatarUrl={thread?.firstParticipant?.avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(
thread?.firstParticipant?.avatarUrl,
)}
placeholder={thread.firstParticipant.displayName}
type="rounded"
/>
{thread?.lastTwoParticipants?.[0] && (
<StyledAvatar
avatarUrl={thread.lastTwoParticipants[0].avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(
thread.lastTwoParticipants[0].avatarUrl,
)}
placeholder={thread.lastTwoParticipants[0].displayName}
type="rounded"
/>
)}
{finalDisplayedName && (
<StyledAvatar
avatarUrl={finalAvatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(finalAvatarUrl)}
placeholder={finalDisplayedName}
type="rounded"
color={isCountIcon ? GRAY_SCALE.gray50 : undefined}

View File

@ -1,5 +1,6 @@
import { useApolloClient } from '@apollo/client';
import { useRecoilValue } from 'recoil';
import { Nullable } from 'twenty-ui';
import { Activity } from '@/activities/types/Activity';
import { ActivityTarget } from '@/activities/types/ActivityTarget';
@ -7,7 +8,6 @@ import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTarge
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
import { Nullable } from '~/types/Nullable';
import { isDefined } from '~/utils/isDefined';
export const useActivityTargetObjectRecords = (activity: Activity) => {

View File

@ -1,13 +1,16 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconCalendar, IconComment } from 'twenty-ui';
import {
IconCalendar,
IconComment,
OverflowingTextWithTooltip,
} from 'twenty-ui';
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
import { Activity } from '@/activities/types/Activity';
import { getActivitySummary } from '@/activities/utils/getActivitySummary';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox';
import { beautifyExactDate, hasDatePassed } from '~/utils/date-utils';

View File

@ -2,17 +2,17 @@ import { Tooltip } from 'react-tooltip';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { IconCheckbox, IconNotes } from 'twenty-ui';
import { Avatar, IconCheckbox, IconNotes } from 'twenty-ui';
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
import { timelineActivityWithoutTargetsFamilyState } from '@/activities/timeline/states/timelineActivityWithoutTargetsFamilyState';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { Avatar } from '@/users/components/Avatar';
import {
beautifyExactDateTime,
beautifyPastDateRelativeToNow,
} from '~/utils/date-utils';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledAvatarContainer = styled.div`
align-items: center;
@ -170,7 +170,9 @@ export const TimelineActivity = ({
<StyledTimelineItemContainer>
<StyledAvatarContainer>
<Avatar
avatarUrl={activityForTimeline.author?.avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(
activityForTimeline.author?.avatarUrl,
)}
placeholder={activityForTimeline.author?.name.firstName ?? ''}
size="sm"
type="rounded"

View File

@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from 'twenty-ui';
import { ActivityType } from '@/activities/types/Activity';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox';
const StyledTitleContainer = styled.div`

View File

@ -1,6 +1,6 @@
import styled from '@emotion/styled';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
type LogoProps = {
workspaceLogo?: string | null;

View File

@ -3,7 +3,7 @@ import styled from '@emotion/styled';
import { isNonEmptyString } from '@sniptt/guards';
import { useRecoilState, useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum';
import { IconNotes } from 'twenty-ui';
import { Avatar, IconNotes } from 'twenty-ui';
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
import { Activity } from '@/activities/types/Activity';
@ -21,7 +21,6 @@ import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { Avatar } from '@/users/components/Avatar';
import { getLogoUrlFromDomainName } from '~/utils';
import { isDefined } from '~/utils/isDefined';

View File

@ -1,11 +1,12 @@
import styled from '@emotion/styled';
import { Avatar } from 'twenty-ui';
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle';
import { Avatar } from '@/users/components/Avatar';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { useFavorites } from '../hooks/useFavorites';
@ -63,7 +64,7 @@ export const Favorites = () => {
Icon={() => (
<StyledAvatar
entityId={recordId}
avatarUrl={avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
type={avatarType}
placeholder={labelIdentifier}
className="fav-avatar"

View File

@ -1,6 +1,6 @@
import { gql } from '@apollo/client';
import { AvatarType } from 'twenty-ui';
import { AvatarType } from '@/users/components/Avatar';
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
export const mockId = '8f3b2121-f194-4ba4-9fbf-2d5a37126806';

View File

@ -1,4 +1,4 @@
import { AvatarType } from '@/users/components/Avatar';
import { AvatarType } from 'twenty-ui';
export type Favorite = {
id: string;

View File

@ -11,7 +11,7 @@ import {
} from '@/ui/navigation/navigation-drawer/components/NavigationDrawer';
import { isNavigationDrawerOpenState } from '@/ui/navigation/states/isNavigationDrawerOpenState';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { useIsSettingsPage } from '../hooks/useIsSettingsPage';
import { currentMobileNavigationDrawerState } from '../states/currentMobileNavigationDrawerState';

View File

@ -1,9 +1,9 @@
import { renderHook } from '@testing-library/react';
import { Nullable } from 'twenty-ui';
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
import { Nullable } from '~/types/Nullable';
describe('useColumnDefinitionsFromFieldMetadata', () => {
it('should return empty definitions if no object is passed', () => {

View File

@ -1,10 +1,10 @@
import { useMemo } from 'react';
import { Nullable } from 'twenty-ui';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
import { Nullable } from '~/types/Nullable';
import { formatFieldMetadataItemAsColumnDefinition } from '../utils/formatFieldMetadataItemAsColumnDefinition';
import { formatFieldMetadataItemsAsFilterDefinitions } from '../utils/formatFieldMetadataItemsAsFilterDefinitions';

View File

@ -1,8 +1,8 @@
import * as React from 'react';
import { EntityChip } from 'twenty-ui';
import { useMapToObjectRecordIdentifier } from '@/object-metadata/hooks/useMapToObjectRecordIdentifier';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
export type RecordChipProps = {
objectNameSingular: string;
@ -28,7 +28,9 @@ export const RecordChip = ({
entityId={record.id}
name={objectRecordIdentifier.name}
avatarType={objectRecordIdentifier.avatarType}
avatarUrl={objectRecordIdentifier.avatarUrl}
avatarUrl={
getImageAbsoluteURIOrBase64(objectRecordIdentifier.avatarUrl) || ''
}
linkToEntity={objectRecordIdentifier.linkToShowPage}
maxWidth={maxWidth}
className={className}

View File

@ -1,6 +1,6 @@
import { IconComponent } from 'twenty-ui';
import { EntityChip, IconComponent } from 'twenty-ui';
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { Filter } from '../types/Filter';
@ -17,7 +17,7 @@ export const GenericEntityFilterChip = ({
entityId={filter.value}
name={filter.displayValue}
avatarType="rounded"
avatarUrl={filter.displayAvatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(filter.displayAvatarUrl) || ''}
LeftIcon={Icon}
/>
);

View File

@ -1,6 +1,7 @@
import { Nullable } from 'twenty-ui';
import { useDateField } from '@/object-record/record-field/meta-types/hooks/useDateField';
import { DateInput } from '@/ui/field/input/components/DateInput';
import { Nullable } from '~/types/Nullable';
import { usePersistField } from '../../../hooks/usePersistField';

View File

@ -1,5 +1,6 @@
import { Nullable } from 'twenty-ui';
import { DateInput } from '@/ui/field/input/components/DateInput';
import { Nullable } from '~/types/Nullable';
import { usePersistField } from '../../../hooks/usePersistField';
import { useDateTimeField } from '../../hooks/useDateTimeField';

View File

@ -1,5 +1,6 @@
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { Avatar } from 'twenty-ui';
import { v4 } from 'uuid';
import { MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordSelectSelectableListId';
@ -7,7 +8,7 @@ import { ObjectRecordForSelect } from '@/object-record/relation-picker/hooks/use
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
import { Avatar } from '@/users/components/Avatar';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
export const StyledSelectableItem = styled(SelectableItem)`
height: 100%;
@ -42,7 +43,9 @@ export const MultipleObjectRecordSelectItem = ({
isKeySelected={isSelectedByKeyboard}
avatar={
<Avatar
avatarUrl={objectRecordForSelect.recordIdentifier.avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(
objectRecordForSelect.recordIdentifier.avatarUrl,
)}
entityId={objectRecordForSelect.record.id}
placeholder={objectRecordForSelect.recordIdentifier.name}
size="md"

View File

@ -1,11 +1,12 @@
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { Avatar } from 'twenty-ui';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemSelectAvatar';
import { Avatar } from '@/users/components/Avatar';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
type SelectableMenuItemSelectProps = {
entity: EntityForSelect;
@ -39,7 +40,7 @@ export const SelectableMenuItemSelect = ({
hovered={isSelectedItemId}
avatar={
<Avatar
avatarUrl={entity.avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(entity.avatarUrl)}
entityId={entity.id}
placeholder={entity.name}
size="md"

View File

@ -1,11 +1,12 @@
import { useEffect, useState } from 'react';
import { Avatar } from 'twenty-ui';
import { SelectableRecord } from '@/object-record/select/types/SelectableRecord';
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
import { Avatar } from '@/users/components/Avatar';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
export const MultipleRecordSelectDropdown = ({
recordsToSelect,
@ -68,7 +69,7 @@ export const MultipleRecordSelectDropdown = ({
}
avatar={
<Avatar
avatarUrl={record.avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(record.avatarUrl)}
entityId={record.id}
placeholder={record.name}
size="md"

View File

@ -1,4 +1,4 @@
import { AvatarType } from '@/users/components/Avatar';
import { AvatarType } from 'twenty-ui';
export type SelectableRecord = {
id: string;

View File

@ -1,6 +1,7 @@
import { Nullable } from 'twenty-ui';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { ObjectRecordEdge } from '@/object-record/types/ObjectRecordEdge';
import { Nullable } from '~/types/Nullable';
export type ObjectRecordConnection<T extends ObjectRecord = ObjectRecord> = {
__typename?: string;

View File

@ -1,4 +1,4 @@
import { AvatarType } from '@/users/components/Avatar';
import { AvatarType } from 'twenty-ui';
export type ObjectRecordIdentifier = {
id: string;

View File

@ -1,7 +1,6 @@
import {
EntityChip,
EntityChipVariant,
} from '@/ui/display/chip/components/EntityChip';
import { EntityChip, EntityChipVariant } from 'twenty-ui';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
export type PersonChipProps = {
id: string;
@ -21,7 +20,7 @@ export const PersonChip = ({
linkToEntity={`/person/${id}`}
name={name}
avatarType="rounded"
avatarUrl={avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl) || ''}
variant={variant}
/>
);

View File

@ -2,7 +2,7 @@ import { ReactNode, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useIcons } from 'twenty-ui';
import { Nullable, useIcons } from 'twenty-ui';
import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMetadata';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
@ -11,7 +11,6 @@ import { FieldIdentifierType } from '@/settings/data-model/types/FieldIdentifier
import { isFieldTypeSupportedInSettings } from '@/settings/data-model/utils/isFieldTypeSupportedInSettings';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
import { Nullable } from '~/types/Nullable';
import { RELATION_TYPES } from '../../constants/RelationTypes';

View File

@ -5,8 +5,8 @@ import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMembe
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { ImageInput } from '@/ui/input/components/ImageInput';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
import { useUploadProfilePictureMutation } from '~/generated/graphql';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { isDefined } from '~/utils/isDefined';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';

View File

@ -2,11 +2,11 @@ import { useRecoilState } from 'recoil';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { ImageInput } from '@/ui/input/components/ImageInput';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
import {
useUpdateWorkspaceMutation,
useUploadWorkspaceLogoMutation,
} from '~/generated/graphql';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const WorkspaceLogoUploader = () => {

View File

@ -9,11 +9,11 @@ import {
size,
useFloating,
} from '@floating-ui/react';
import { AppTooltip } from 'twenty-ui';
import { ReadonlyDeep } from 'type-fest';
import { useDebouncedCallback } from 'use-debounce';
import { SelectOption } from '@/spreadsheet-import/types';
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';

View File

@ -2,9 +2,9 @@
import { Column } from 'react-data-grid';
import { createPortal } from 'react-dom';
import styled from '@emotion/styled';
import { AppTooltip } from 'twenty-ui';
import { Fields } from '@/spreadsheet-import/types';
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
const StyledHeaderContainer = styled.div`
align-items: center;

View File

@ -2,10 +2,10 @@
import { Column, useRowSelection } from 'react-data-grid';
import { createPortal } from 'react-dom';
import styled from '@emotion/styled';
import { AppTooltip } from 'twenty-ui';
import { MatchColumnSelect } from '@/spreadsheet-import/components/MatchColumnSelect';
import { Data, Fields } from '@/spreadsheet-import/types';
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox';
import { TextInput } from '@/ui/input/components/TextInput';
import { Toggle } from '@/ui/input/components/Toggle';

View File

@ -1,8 +1,8 @@
import React, { ReactElement, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import styled from '@emotion/styled';
import { Chip, ChipVariant } from 'twenty-ui';
import { Chip, ChipVariant } from '@/ui/display/chip/components/Chip';
import { IntersectionObserverWrapper } from '@/ui/display/expandable-list/IntersectionObserverWrapper';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';

View File

@ -1,12 +1,10 @@
import { Meta, StoryObj } from '@storybook/react';
import { CatalogDecorator, CatalogStory, ComponentDecorator } from 'twenty-ui';
import { Info, InfoAccent } from '@/ui/display/info/components/Info.tsx';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator.tsx';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator.tsx';
import { CatalogStory } from '~/testing/types.ts';
import { Info, InfoAccent } from '@/ui/display/info/components/Info';
const meta: Meta<typeof Info> = {
title: 'UI/Display/Info/Info',
title: 'UI/Display/Info',
component: Info,
};

View File

@ -1,4 +1,4 @@
import { OverflowingTextWithTooltip } from '../../../display/tooltip/OverflowingTextWithTooltip';
import { OverflowingTextWithTooltip } from 'twenty-ui';
import { EllipsisDisplay } from './EllipsisDisplay';

View File

@ -2,11 +2,11 @@ import { useRef, useState } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { flip, offset, useFloating } from '@floating-ui/react';
import { Nullable } from 'twenty-ui';
import { useRegisterInputEvents } from '@/object-record/record-field/meta-types/input/hooks/useRegisterInputEvents';
import { DateDisplay } from '@/ui/field/display/components/DateDisplay';
import { InternalDatePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
import { Nullable } from '~/types/Nullable';
const StyledCalendarContainer = styled.div`
background: ${({ theme }) => theme.background.secondary};

View File

@ -6,8 +6,8 @@ import {
motion,
useAnimation,
} from 'framer-motion';
import { Checkmark } from 'twenty-ui';
import { Checkmark } from '@/ui/display/checkmark/components/Checkmark';
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
const StyledColorSchemeBackground = styled.div<

View File

@ -3,14 +3,13 @@ import styled from '@emotion/styled';
import { Decorator, Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, waitFor, within } from '@storybook/test';
import { PlayFunction } from '@storybook/types';
import { Avatar, ComponentDecorator } from 'twenty-ui';
import { Button } from '@/ui/input/button/components/Button';
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemSelectAvatar';
import { Avatar } from '@/users/components/Avatar';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { Dropdown } from '../Dropdown';
import { DropdownMenuHeader } from '../DropdownMenuHeader';

View File

@ -4,9 +4,12 @@ import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { IconChevronLeft, IconComponent } from 'twenty-ui';
import {
IconChevronLeft,
IconComponent,
OverflowingTextWithTooltip,
} from 'twenty-ui';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { IconButton } from '@/ui/input/button/components/IconButton';
import { NavigationDrawerCollapseButton } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerCollapseButton';
import { isNavigationDrawerOpenState } from '@/ui/navigation/states/isNavigationDrawerOpenState';

View File

@ -1,9 +1,9 @@
import { ChangeEvent, ReactNode, useRef } from 'react';
import { Tooltip } from 'react-tooltip';
import styled from '@emotion/styled';
import { Avatar, AvatarType } from 'twenty-ui';
import { v4 as uuidV4 } from 'uuid';
import { Avatar, AvatarType } from '@/users/components/Avatar';
import {
beautifyExactDateTime,
beautifyPastDateRelativeToNow,

View File

@ -1,8 +1,7 @@
import * as React from 'react';
import { Link as ReactLink } from 'react-router-dom';
import styled from '@emotion/styled';
import { Chip, ChipSize, ChipVariant } from '@/ui/display/chip/components/Chip';
import { Chip, ChipSize, ChipVariant } from 'twenty-ui';
type RoundedLinkProps = {
href: string;

View File

@ -1,7 +1,7 @@
import { ReactNode } from 'react';
import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from 'twenty-ui';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { Checkbox } from '@/ui/input/components/Checkbox';
import {

View File

@ -1,8 +1,6 @@
import { ReactNode } from 'react';
import { useTheme } from '@emotion/react';
import { IconCheck } from 'twenty-ui';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { IconCheck, OverflowingTextWithTooltip } from 'twenty-ui';
import {
StyledMenuItemLabel,

View File

@ -1,14 +1,14 @@
import { Meta, StoryObj } from '@storybook/react';
import { Avatar } from '@/users/components/Avatar';
import {
Avatar,
CatalogDecorator,
CatalogDimension,
CatalogOptions,
} from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
CatalogStory,
ComponentDecorator,
} from 'twenty-ui';
import { avatarUrl } from '~/testing/mock-data/users';
import { CatalogStory } from '~/testing/types';
import { MenuItemMultiSelectAvatar } from '../MenuItemMultiSelectAvatar';

View File

@ -1,14 +1,14 @@
import { Meta, StoryObj } from '@storybook/react';
import { Avatar } from '@/users/components/Avatar';
import {
Avatar,
CatalogDecorator,
CatalogDimension,
CatalogOptions,
} from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
CatalogStory,
ComponentDecorator,
} from 'twenty-ui';
import { avatarUrl } from '~/testing/mock-data/users';
import { CatalogStory } from '~/testing/types';
import { MenuItemSelectAvatar } from '../MenuItemSelectAvatar';

View File

@ -1,7 +1,9 @@
import { useTheme } from '@emotion/react';
import { IconComponent, IconGripVertical } from 'twenty-ui';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import {
IconComponent,
IconGripVertical,
OverflowingTextWithTooltip,
} from 'twenty-ui';
import {
StyledMenuItemLabel,

View File

@ -1,8 +1,8 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { motion } from 'framer-motion';
import { AnimatedCheckmark } from 'twenty-ui';
import { AnimatedCheckmark } from '@/ui/display/checkmark/components/AnimatedCheckmark';
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/MobileViewport';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';

View File

@ -1,4 +1,6 @@
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
import { EntityChip } from 'twenty-ui';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
export type UserChipProps = {
id: string;
@ -11,6 +13,6 @@ export const UserChip = ({ id, name, avatarUrl }: UserChipProps) => (
entityId={id}
name={name}
avatarType="rounded"
avatarUrl={avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl) || ''}
/>
);

View File

@ -5,11 +5,16 @@ import {
OnDragEndResponder,
ResponderProvided,
} from '@hello-pangea/dnd';
import { IconInfoCircle, IconMinus, IconPlus, useIcons } from 'twenty-ui';
import {
AppTooltip,
IconInfoCircle,
IconMinus,
IconPlus,
useIcons,
} from 'twenty-ui';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';

View File

@ -1,8 +1,8 @@
import styled from '@emotion/styled';
import { Avatar, OverflowingTextWithTooltip } from 'twenty-ui';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { Avatar } from '@/users/components/Avatar';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledContainer = styled.div`
background: ${({ theme }) => theme.background.secondary};
@ -39,7 +39,7 @@ export const WorkspaceMemberCard = ({
}: WorkspaceMemberCardProps) => (
<StyledContainer>
<Avatar
avatarUrl={workspaceMember.avatarUrl}
avatarUrl={getImageAbsoluteURIOrBase64(workspaceMember.avatarUrl)}
entityId={workspaceMember.id}
placeholder={workspaceMember.name.firstName || ''}
type="squared"

View File

@ -1,13 +0,0 @@
import { Decorator } from '@storybook/react';
import { ComponentStorybookLayout } from '../ComponentStorybookLayout';
export const ComponentDecorator: Decorator = (Story, context) => {
const { container } = context.parameters;
return (
<ComponentStorybookLayout width={container?.width}>
<Story />
</ComponentStorybookLayout>
);
};

View File

@ -5,11 +5,7 @@ export const getImageAbsoluteURIOrBase64 = (imageUrl?: string | null) => {
return null;
}
if (imageUrl?.startsWith('data:')) {
return imageUrl;
}
if (imageUrl?.startsWith('https:')) {
if (imageUrl?.startsWith('data:') || imageUrl?.startsWith('https:')) {
return imageUrl;
}

View File

@ -14,13 +14,13 @@ module.exports = {
patterns: [
{
group: ['@tabler/icons-react'],
message: 'Please import icons from `src/display`',
message: 'Please import icons from `@ui/display`',
},
{
group: ['react-hotkeys-web-hook'],
importNames: ['useHotkeys'],
message:
'Please use the custom wrapper: `useScopedHotkeys` from `src/utilities`',
'Please use the custom wrapper: `useScopedHotkeys` from `@ui/utilities`',
},
],
},

View File

@ -2,10 +2,10 @@
"name": "twenty-ui",
"version": "0.4.0",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"main": "./src/index.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}

View File

@ -2,10 +2,7 @@ import { useEffect, useState } from 'react';
import styled from '@emotion/styled';
import { isNonEmptyString } from '@sniptt/guards';
import { Nullable } from '~/types/Nullable';
import { stringToHslColor } from '~/utils/string-to-hsl';
import { getImageAbsoluteURIOrBase64 } from '../utils/getProfilePictureAbsoluteURI';
import { Nullable, stringToHslColor } from '@ui/utilities';
export type AvatarType = 'squared' | 'rounded';
@ -93,7 +90,7 @@ export const Avatar = ({
const img = new Image();
img.onload = () => resolve(false);
img.onerror = () => resolve(true);
img.src = getImageAbsoluteURIOrBase64(avatarUrl) as string;
img.src = avatarUrl;
}).then((res) => {
setIsInvalidAvatarUrl(res as boolean);
});
@ -110,7 +107,7 @@ export const Avatar = ({
return (
<StyledAvatar
className={className}
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
avatarUrl={avatarUrl}
placeholder={placeholder}
size={size}
type={type}

View File

@ -1,7 +1,6 @@
import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { avatarUrl } from '~/testing/mock-data/users';
import { AVATAR_URL_MOCK, ComponentDecorator } from '@ui/testing';
import { Avatar } from '../Avatar';
@ -9,7 +8,12 @@ const meta: Meta<typeof Avatar> = {
title: 'Modules/Users/Avatar',
component: Avatar,
decorators: [ComponentDecorator],
args: { avatarUrl, size: 'md', placeholder: 'L', type: 'rounded' },
args: {
avatarUrl: AVATAR_URL_MOCK,
size: 'md',
placeholder: 'L',
type: 'rounded',
},
};
export default meta;

View File

@ -5,10 +5,12 @@ import {
AvatarProps,
AvatarSize,
AvatarType,
} from '@/users/components/Avatar';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { avatarUrl } from '~/testing/mock-data/users';
} from '@ui/display/avatar/components/Avatar';
import {
AVATAR_URL_MOCK,
CatalogDecorator,
ComponentDecorator,
} from '@ui/testing';
import { AvatarGroup, AvatarGroupProps } from '../AvatarGroup';
@ -18,7 +20,7 @@ const makeAvatar = (userName: string, props: Partial<AvatarProps> = {}) => (
);
const getAvatars = (commonProps: Partial<AvatarProps> = {}) => [
makeAvatar('Matthew', { avatarUrl, ...commonProps }),
makeAvatar('Matthew', { avatarUrl: AVATAR_URL_MOCK, ...commonProps }),
makeAvatar('Sophie', commonProps),
makeAvatar('Jane', commonProps),
makeAvatar('Lily', commonProps),

View File

@ -1,7 +1,8 @@
import React from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconCheck } from 'twenty-ui';
import { IconCheck } from '@ui/display/icon/components/TablerIcons';
const StyledContainer = styled.div`
align-items: center;

View File

@ -1,11 +1,11 @@
import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { ComponentDecorator } from '@ui/testing/decorators/ComponentDecorator';
import { Checkmark } from '../Checkmark';
const meta: Meta<typeof Checkmark> = {
title: 'UI/Display/Checkmark/Checkmark',
title: 'UI/Display/Checkmark',
component: Checkmark,
decorators: [ComponentDecorator],
};

View File

@ -2,7 +2,7 @@ import { MouseEvent, ReactNode } from 'react';
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from '../../tooltip/OverflowingTextWithTooltip';
import { OverflowingTextWithTooltip } from '@ui/display/tooltip/OverflowingTextWithTooltip';
export enum ChipSize {
Large = 'large',

View File

@ -2,10 +2,10 @@ import * as React from 'react';
import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import { isNonEmptyString } from '@sniptt/guards';
import { IconComponent } from 'twenty-ui';
import { Avatar, AvatarType } from '@/users/components/Avatar';
import { Nullable } from '~/types/Nullable';
import { Avatar, AvatarType } from '@ui/display/avatar/components/Avatar';
import { IconComponent } from '@ui/display/icon/types/IconComponent';
import { Nullable } from '@ui/utilities/types/Nullable';
import { Chip, ChipVariant } from './Chip';

View File

@ -1,8 +1,10 @@
import { Meta, StoryObj } from '@storybook/react';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { CatalogStory } from '~/testing/types';
import {
CatalogDecorator,
CatalogStory,
ComponentDecorator,
} from '@ui/testing';
import { Chip, ChipAccent, ChipSize, ChipVariant } from '../Chip';

View File

@ -1,13 +1,13 @@
import { Meta, StoryObj } from '@storybook/react';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
import { ComponentDecorator, RouterDecorator } from '@ui/testing';
import { EntityChip } from '../EntityChip';
const meta: Meta<typeof EntityChip> = {
title: 'UI/Display/Chip/EntityChip',
component: EntityChip,
decorators: [ComponentWithRouterDecorator],
decorators: [RouterDecorator, ComponentDecorator],
args: {
name: 'Entity name',
linkToEntity: '/entity-link',

View File

@ -1,3 +1,9 @@
export * from './avatar/components/Avatar';
export * from './avatar/components/AvatarGroup';
export * from './checkmark/components/AnimatedCheckmark';
export * from './checkmark/components/Checkmark';
export * from './chip/components/Chip';
export * from './chip/components/EntityChip';
export * from './icon/components/IconAddressBook';
export * from './icon/components/IconGmail';
export * from './icon/components/IconGoogle';
@ -9,3 +15,5 @@ export * from './icon/hooks/useIcons';
export * from './icon/providers/IconsProvider';
export * from './icon/states/iconsState';
export * from './icon/types/IconComponent';
export * from './tooltip/AppTooltip';
export * from './tooltip/OverflowingTextWithTooltip';

View File

@ -1,7 +1,7 @@
import { PlacesType, PositionStrategy, Tooltip } from 'react-tooltip';
import styled from '@emotion/styled';
import { RGBA } from '@/ui/theme/constants/Rgba';
import { RGBA } from '@ui/theme/constants/Rgba';
export enum TooltipPosition {
Top = 'top',

View File

@ -1,7 +1,7 @@
import { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/test';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { ComponentDecorator } from '@ui/testing';
import { OverflowingTextWithTooltip } from '../OverflowingTextWithTooltip';

View File

@ -1,13 +1,15 @@
import { Meta, StoryObj } from '@storybook/react';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { CatalogStory } from '~/testing/types';
import {
CatalogDecorator,
CatalogStory,
ComponentDecorator,
} from '@ui/testing';
import { AppTooltip as Tooltip, TooltipPosition } from '../AppTooltip';
const meta: Meta<typeof Tooltip> = {
title: 'UI/Display/Tooltip/Tooltip',
title: 'UI/Display/Tooltip',
component: Tooltip,
};

View File

@ -0,0 +1,8 @@
import { MemoryRouter } from 'react-router-dom';
import { Decorator } from '@storybook/react';
export const RouterDecorator: Decorator = (Story) => (
<MemoryRouter>
<Story />
</MemoryRouter>
);

View File

@ -1,2 +1,6 @@
export * from './ComponentStorybookLayout';
export * from './decorators/CatalogDecorator';
export * from './decorators/ComponentDecorator';
export * from './decorators/RouterDecorator';
export * from './mocks/avatarUrlMock';
export * from './types/CatalogStory';

View File

@ -0,0 +1,2 @@
export const AVATAR_URL_MOCK =
'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAYABgAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABgAAAAAQAAAGAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABSgAwAEAAAAAQAAABQAAAAA/8AAEQgAFAAUAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMACwgICggHCwoJCg0MCw0RHBIRDw8RIhkaFBwpJCsqKCQnJy0yQDctMD0wJyc4TDk9Q0VISUgrNk9VTkZUQEdIRf/bAEMBDA0NEQ8RIRISIUUuJy5FRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRf/dAAQAAv/aAAwDAQACEQMRAD8Ava1q728otYY98joSCTgZrnbXWdTtrhrfVZXWLafmcAEkdgR/hVltQku9Q8+OIEBcGOT+ID0PY1ka1KH2u8ToqnPLbmIqG7u6LtbQ7RXBRec4Uck9eKXcPWsKDWVnhWSL5kYcFelSf2m3901POh8jP//QoyIAnTuKpXsY82NsksUyWPU5q/L9z8RVK++/F/uCsVsaEURwgA4HtT9x9TUcf3KfUGh//9k=';

View File

@ -4,7 +4,7 @@ import { StoryObj } from '@storybook/react';
import {
CatalogDimension,
CatalogOptions,
} from './decorators/CatalogDecorator';
} from '../decorators/CatalogDecorator';
export type CatalogStory<
StoryType extends StoryObj<ComponentType>,

View File

@ -1,4 +1,4 @@
import { stringToHslColor } from '../string-to-hsl';
import { stringToHslColor } from '../stringToHslColor';
describe('stringToHslColor', () => {
it('should return a color based on a string', () => {

View File

@ -1 +1,3 @@
export * from './color/utils/stringToHslColor';
export * from './state/utils/createState';
export * from './types/Nullable';

View File

@ -17,8 +17,7 @@
"baseUrl": ".",
"paths": {
"twenty-emails": ["packages/twenty-emails/src/index.ts"],
"twenty-ui": ["packages/twenty-ui/src/index.ts"],
"@ui/*": ["packages/twenty-ui/src/*"]
"twenty-ui": ["packages/twenty-ui/src/index.ts"]
}
},
"exclude": ["node_modules", "tmp"]