Feat : Introduced Delay Options for Tooltip (#5766)

Fixes https://github.com/twentyhq/twenty/issues/5727

---------

Co-authored-by: Rushikesh Tarapure <rushikeshtarapure@gofynd.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Rushikesh Tarapure
2024-06-19 20:07:44 +05:30
committed by GitHub
parent 86f95c0870
commit bc8c895b0e
8 changed files with 98 additions and 88 deletions

View File

@ -1,6 +1,5 @@
import { Tooltip } from 'react-tooltip';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Avatar } from 'twenty-ui'; import { AppTooltip, Avatar } from 'twenty-ui';
import { Comment } from '@/activities/types/Comment'; import { Comment } from '@/activities/types/Comment';
import { import {
@ -42,21 +41,6 @@ const StyledDate = styled.div`
margin-left: ${({ theme }) => theme.spacing(1)}; margin-left: ${({ theme }) => theme.spacing(1)};
`; `;
const StyledTooltip = styled(Tooltip)`
background-color: ${({ theme }) => theme.background.primary};
box-shadow: 0px 2px 4px 3px
${({ theme }) => theme.background.transparent.light};
box-shadow: 2px 4px 16px 6px
${({ theme }) => theme.background.transparent.light};
color: ${({ theme }) => theme.font.color.primary};
opacity: 1;
padding: 8px;
`;
type CommentHeaderProps = { type CommentHeaderProps = {
comment: Pick<Comment, 'id' | 'author' | 'createdAt'>; comment: Pick<Comment, 'id' | 'author' | 'createdAt'>;
actionBar?: React.ReactNode; actionBar?: React.ReactNode;
@ -87,7 +71,7 @@ export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => {
<StyledDate id={`id-${commentId}`}> <StyledDate id={`id-${commentId}`}>
{beautifiedCreatedAt} {beautifiedCreatedAt}
</StyledDate> </StyledDate>
<StyledTooltip <AppTooltip
anchorSelect={`#id-${commentId}`} anchorSelect={`#id-${commentId}`}
content={exactCreatedAt} content={exactCreatedAt}
clickable clickable

View File

@ -1,8 +1,7 @@
import { Tooltip } from 'react-tooltip';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { Avatar, IconCheckbox, IconNotes } from 'twenty-ui'; import { AppTooltip, Avatar, IconCheckbox, IconNotes } from 'twenty-ui';
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
import { timelineActivityWithoutTargetsFamilyState } from '@/activities/timeline/states/timelineActivityWithoutTargetsFamilyState'; import { timelineActivityWithoutTargetsFamilyState } from '@/activities/timeline/states/timelineActivityWithoutTargetsFamilyState';
@ -109,21 +108,6 @@ const StyledVerticalLine = styled.div`
width: 2px; width: 2px;
`; `;
const StyledTooltip = styled(Tooltip)`
background-color: ${({ theme }) => theme.background.primary};
box-shadow: 0px 2px 4px 3px
${({ theme }) => theme.background.transparent.light};
box-shadow: 2px 4px 16px 6px
${({ theme }) => theme.background.transparent.light};
color: ${({ theme }) => theme.font.color.primary};
opacity: 1;
padding: ${({ theme }) => theme.spacing(2)};
`;
const StyledTimelineItemContainer = styled.div<{ isGap?: boolean }>` const StyledTimelineItemContainer = styled.div<{ isGap?: boolean }>`
align-items: center; align-items: center;
align-self: stretch; align-self: stretch;
@ -217,7 +201,7 @@ export const TimelineActivity = ({
<StyledItemTitleDate id={`id-${activityForTimeline.id}`}> <StyledItemTitleDate id={`id-${activityForTimeline.id}`}>
{beautifiedCreatedAt} {beautifiedCreatedAt}
</StyledItemTitleDate> </StyledItemTitleDate>
<StyledTooltip <AppTooltip
anchorSelect={`#id-${activityForTimeline.id}`} anchorSelect={`#id-${activityForTimeline.id}`}
content={exactCreatedAt} content={exactCreatedAt}
clickable clickable

View File

@ -1,8 +1,7 @@
import React, { ReactElement, useContext } from 'react'; import React, { ReactElement, useContext } from 'react';
import { Tooltip } from 'react-tooltip';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { IconComponent } from 'twenty-ui'; import { AppTooltip, IconComponent } from 'twenty-ui';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { useFieldFocus } from '@/object-record/record-field/hooks/useFieldFocus'; import { useFieldFocus } from '@/object-record/record-field/hooks/useFieldFocus';
@ -55,17 +54,6 @@ const StyledInlineCellBaseContainer = styled.div`
user-select: none; user-select: none;
`; `;
const StyledTooltip = styled(Tooltip)`
background-color: ${({ theme }) => theme.background.primary};
box-shadow: ${({ theme }) => theme.boxShadow.light};
color: ${({ theme }) => theme.font.color.primary};
font-size: ${({ theme }) => theme.font.size.sm};
font-weight: ${({ theme }) => theme.font.weight.regular};
padding: ${({ theme }) => theme.spacing(2)};
`;
export const StyledSkeletonDiv = styled.div` export const StyledSkeletonDiv = styled.div`
height: 24px; height: 24px;
`; `;
@ -141,7 +129,7 @@ export const RecordInlineCellContainer = ({
)} )}
{/* TODO: Displaying Tooltips on the board is causing performance issues https://react-tooltip.com/docs/examples/render */} {/* TODO: Displaying Tooltips on the board is causing performance issues https://react-tooltip.com/docs/examples/render */}
{!showLabel && !fieldDefinition?.disableTooltip && ( {!showLabel && !fieldDefinition?.disableTooltip && (
<StyledTooltip <AppTooltip
anchorSelect={`#${labelId}`} anchorSelect={`#${labelId}`}
content={label} content={label}
clickable clickable

View File

@ -1,9 +1,8 @@
import { ChangeEvent, ReactNode, useRef } from 'react'; import { ChangeEvent, ReactNode, useRef } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { Tooltip } from 'react-tooltip';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Avatar, AvatarType } from 'twenty-ui'; import { AppTooltip, Avatar, AvatarType } from 'twenty-ui';
import { v4 as uuidV4 } from 'uuid'; import { v4 as uuidV4 } from 'uuid';
import { import {
@ -55,17 +54,6 @@ const StyledTitle = styled.div`
justify-content: center; justify-content: center;
`; `;
const StyledTooltip = styled(Tooltip)`
background-color: ${({ theme }) => theme.background.primary};
box-shadow: ${({ theme }) => theme.boxShadow.light};
color: ${({ theme }) => theme.font.color.primary};
font-size: ${({ theme }) => theme.font.size.sm};
font-weight: ${({ theme }) => theme.font.weight.regular};
padding: ${({ theme }) => theme.spacing(2)};
`;
const StyledAvatarWrapper = styled.div` const StyledAvatarWrapper = styled.div`
cursor: pointer; cursor: pointer;
`; `;
@ -153,7 +141,7 @@ export const ShowPageSummaryCard = ({
Added {beautifiedCreatedAt} Added {beautifiedCreatedAt}
</StyledDate> </StyledDate>
)} )}
<StyledTooltip <AppTooltip
anchorSelect={`#${dateElementId}`} anchorSelect={`#${dateElementId}`}
content={exactCreatedAt} content={exactCreatedAt}
clickable clickable

View File

@ -10,6 +10,12 @@ export enum TooltipPosition {
Bottom = 'bottom', Bottom = 'bottom',
} }
export enum TooltipDelay {
noDelay = '0ms',
shortDelay = '300ms',
mediumDelay = '500ms',
}
const StyledAppTooltip = styled(Tooltip)` const StyledAppTooltip = styled(Tooltip)`
backdrop-filter: ${({ theme }) => theme.blur.strong}; backdrop-filter: ${({ theme }) => theme.blur.strong};
background-color: ${({ theme }) => RGBA(theme.color.gray80, 0.8)}; background-color: ${({ theme }) => RGBA(theme.color.gray80, 0.8)};
@ -36,38 +42,51 @@ export type AppTooltipProps = {
anchorSelect?: string; anchorSelect?: string;
content?: string; content?: string;
children?: React.ReactNode; children?: React.ReactNode;
delayHide?: number;
offset?: number; offset?: number;
noArrow?: boolean; noArrow?: boolean;
isOpen?: boolean; isOpen?: boolean;
place?: PlacesType; place?: PlacesType;
delay?: TooltipDelay;
positionStrategy?: PositionStrategy; positionStrategy?: PositionStrategy;
clickable?: boolean;
}; };
export const AppTooltip = ({ export const AppTooltip = ({
anchorSelect, anchorSelect,
className, className,
content, content,
delayHide,
isOpen, isOpen,
noArrow, noArrow,
offset, offset,
delay = TooltipDelay.mediumDelay,
place, place,
positionStrategy, positionStrategy,
children, children,
}: AppTooltipProps) => ( clickable,
<StyledAppTooltip }: AppTooltipProps) => {
{...{ const delayInMs =
anchorSelect, delay === TooltipDelay.noDelay
className, ? 0
content, : delay === TooltipDelay.shortDelay
delayHide, ? 300
isOpen, : 500;
noArrow,
offset, return (
place, <StyledAppTooltip
positionStrategy, {...{
children, anchorSelect,
}} className,
/> content,
); delayShow: delayInMs,
delayHide: delayInMs,
isOpen,
noArrow,
offset,
place,
positionStrategy,
children,
clickable,
}}
/>
);
};

View File

@ -4,7 +4,7 @@ import { styled } from '@linaria/react';
import { THEME_COMMON } from '@ui/theme'; import { THEME_COMMON } from '@ui/theme';
import { AppTooltip } from './AppTooltip'; import { AppTooltip, TooltipDelay } from './AppTooltip';
const spacing4 = THEME_COMMON.spacing(4); const spacing4 = THEME_COMMON.spacing(4);
@ -87,12 +87,12 @@ export const OverflowingTextWithTooltip = ({
<AppTooltip <AppTooltip
anchorSelect={`#${textElementId}`} anchorSelect={`#${textElementId}`}
content={mutliline ? undefined : text ?? ''} content={mutliline ? undefined : text ?? ''}
delayHide={1}
offset={5} offset={5}
isOpen isOpen
noArrow noArrow
place="bottom" place="bottom"
positionStrategy="absolute" positionStrategy="absolute"
delay={TooltipDelay.mediumDelay}
> >
{mutliline ? <pre>{text}</pre> : ''} {mutliline ? <pre>{text}</pre> : ''}
</AppTooltip> </AppTooltip>

View File

@ -6,7 +6,11 @@ import {
ComponentDecorator, ComponentDecorator,
} from '@ui/testing'; } from '@ui/testing';
import { AppTooltip as Tooltip, TooltipPosition } from '../AppTooltip'; import {
AppTooltip as Tooltip,
TooltipDelay,
TooltipPosition,
} from '../AppTooltip';
const meta: Meta<typeof Tooltip> = { const meta: Meta<typeof Tooltip> = {
title: 'UI/Display/Tooltip', title: 'UI/Display/Tooltip',
@ -19,6 +23,7 @@ type Story = StoryObj<typeof Tooltip>;
export const Default: Story = { export const Default: Story = {
args: { args: {
place: TooltipPosition.Bottom, place: TooltipPosition.Bottom,
delay: TooltipDelay.mediumDelay,
content: 'Tooltip Test', content: 'Tooltip Test',
isOpen: true, isOpen: true,
anchorSelect: '#hover-text', anchorSelect: '#hover-text',
@ -28,12 +33,54 @@ export const Default: Story = {
anchorSelect, anchorSelect,
className, className,
content, content,
delayHide, delay,
isOpen, isOpen,
noArrow, noArrow,
offset, offset,
place, place,
positionStrategy, positionStrategy,
clickable,
}) => (
<>
<p id="hover-text" data-testid="tooltip">
Hover me!
</p>
<Tooltip
{...{
anchorSelect,
className,
content,
delay,
isOpen,
noArrow,
offset,
place,
positionStrategy,
clickable,
}}
/>
</>
),
};
export const Hoverable: Story = {
args: {
place: TooltipPosition.Bottom,
delay: TooltipDelay.mediumDelay,
content: 'Tooltip Test',
isOpen: true,
anchorSelect: '#hover-text',
},
decorators: [ComponentDecorator],
render: ({
anchorSelect,
className,
content,
delay,
noArrow,
offset,
place,
positionStrategy,
}) => ( }) => (
<> <>
<p id="hover-text" data-testid="tooltip"> <p id="hover-text" data-testid="tooltip">
@ -44,8 +91,7 @@ export const Default: Story = {
anchorSelect, anchorSelect,
className, className,
content, content,
delayHide, delay,
isOpen,
noArrow, noArrow,
offset, offset,
place, place,

View File

@ -6,6 +6,7 @@ import { PullRequestIcon } from '@/app/_components/ui/icons/SvgIcons';
import { Theme } from '@/app/_components/ui/theme/theme'; import { Theme } from '@/app/_components/ui/theme/theme';
import { formatIntoRelativeDate } from '@/shared-utils/formatIntoRelativeDate'; import { formatIntoRelativeDate } from '@/shared-utils/formatIntoRelativeDate';
// TODO: use twenty-ui Tooltip
const StyledTooltip = styled(Tooltip)``; const StyledTooltip = styled(Tooltip)``;
const Item = styled.div` const Item = styled.div`