Skip to content

Commit 95af1e6

Browse files
committed
Replace custom tooltip logic with react-tooltip
1 parent adcad65 commit 95af1e6

File tree

7 files changed

+59
-157
lines changed

7 files changed

+59
-157
lines changed

src-ts/lib/styles/variables/_palette.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,6 @@ $tc-grad18: linear-gradient(84.92deg, #363D8C 2.08%, #723390 97.43%);
201201
/* OPACITY */
202202
$black-100-opacity-80: rgba(255, 255, 255, 0.8);
203203
$white-100-opacity-10: rgba(0, 0, 0, 0.1);
204+
205+
/* SHADOW */
206+
$tips-shadow: 0 1px 6px 1px rgba(0, 0, 0, 0.2);

src-ts/lib/table/Table.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ const Table: <T extends { [propertyName: string]: any }>(props: TableProps<T>) =
106106
<div className={styles.tooltip}>
107107
<Tooltip
108108
content={col.tooltip}
109-
positionX='end'
110-
positionY='end'
109+
place='bottom'
111110
trigger={<IconOutline.InformationCircleIcon />}
111+
triggerOn='click'
112112
/>
113113
</div>
114114
)}
Lines changed: 12 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,17 @@
11
@use '../styles/typography';
22
@import '../styles/includes';
33

4-
.tooltip-portal {
5-
position: absolute;
6-
top: -100vh;
7-
left: -100vw;
8-
z-index: 1000;
9-
pointer-events: none;
10-
}
11-
124
.tooltip {
13-
display: inline-block;
14-
position: relative;
15-
16-
&-icon {
17-
cursor: pointer;
18-
}
19-
20-
&-content {
21-
@extend .body-small;
22-
@include font-roboto;
23-
text-transform: none;
24-
white-space: nowrap;
25-
}
5+
@extend .body-small;
6+
@include font-roboto;
7+
8+
display: flex;
9+
padding: $space-sm;
10+
background-color: $tc-black;
11+
color: $black-5;
12+
border-radius: $space-sm;
13+
opacity: 1 !important;
14+
box-shadow: 0 1px 5px $tips-shadow;
15+
text-transform: none;
16+
max-width: 50%;
2617
}
27-
28-
.tooltip-open {
29-
position: absolute;
30-
z-index: 100;
31-
background-color: $black-100;
32-
border-radius: 8px;
33-
color: $tc-white;
34-
padding: $space-sm;
35-
pointer-events: none;
36-
min-width: 62px;
37-
text-align: center;
38-
39-
.tooltip-arrow {
40-
position: absolute;
41-
display: flex;
42-
}
43-
44-
&:global(.posy-end) {
45-
top: calc(100% + 11px);
46-
47-
.tooltip-arrow {
48-
top: -9px;
49-
}
50-
}
51-
52-
&:global(.posx-end) {
53-
right: -24px;
54-
55-
.tooltip-arrow {
56-
right: 11px;
57-
}
58-
}
59-
60-
&:global(.posx-middle) {
61-
left: 50%;
62-
transform: translateX(-50%);
63-
64-
.tooltip-arrow {
65-
right: calc(50% - 18px);
66-
}
67-
}
68-
}

src-ts/lib/tooltip/Tooltip.tsx

Lines changed: 39 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,66 @@
1-
import classNames from 'classnames'
2-
import { Dispatch, FC, MutableRefObject, ReactNode, SetStateAction, useCallback, useEffect, useRef, useState } from 'react'
3-
4-
import {
5-
useClickOutside,
6-
UseHoverElementValue,
7-
useOnHoverElement,
8-
useWindowSize,
9-
WindowSize
10-
} from '../hooks'
11-
import { Portal } from '../portal'
12-
import { TooltipArrowIcon } from '../svgs'
1+
import { FC, ReactNode, RefObject, useRef } from 'react'
2+
import ReactTooltip from 'react-tooltip'
3+
import { v4 as uuidv4 } from 'uuid'
134

145
import styles from './Tooltip.module.scss'
156

7+
interface TooltipEvent {
8+
[key: string]: string
9+
}
10+
1611
interface TooltipProps {
17-
className?: string
1812
content?: string
19-
positionX?: 'start' | 'middle' | 'end'
20-
positionY?: 'start' | 'middle' | 'end'
13+
place?: 'top' | 'right' | 'bottom' | 'left'
2114
trigger: ReactNode
2215
triggerOn?: 'click' | 'hover'
2316
}
2417

25-
interface ClickHandlersValue {
26-
onClick: (ev: any) => void
27-
}
28-
29-
function useClickHandlers(
30-
trigger: MutableRefObject<any>,
31-
toggle: (ev: any) => void,
32-
enabled: boolean = true
33-
): ClickHandlersValue | {} {
34-
useClickOutside(trigger.current, () => toggle(false), enabled)
35-
36-
return enabled ? {
37-
onClick: toggle,
38-
} : {}
39-
}
40-
4118
const Tooltip: FC<TooltipProps> = ({
42-
className,
4319
content,
4420
trigger,
45-
triggerOn = 'click',
46-
positionX = 'middle',
47-
positionY = 'end',
21+
triggerOn = 'hover',
22+
place = 'bottom',
4823
}: TooltipProps) => {
49-
50-
const portalRef: MutableRefObject<any> = useRef(undefined)
51-
const triggerRef: MutableRefObject<any> = useRef(undefined)
52-
const tooltipRef: MutableRefObject<any> = useRef(undefined)
53-
const [tooltipOpen, setTooltipOpen]: [boolean, Dispatch<SetStateAction<boolean>>] = useState<boolean>(false)
54-
const { width: windowWidth, height: windowHeight }: WindowSize = useWindowSize()
55-
56-
const toggleOpen: (toggleValue?: boolean) => void = useCallback((toggleValue?: boolean) => {
57-
setTooltipOpen(currentTooltipOpen => typeof toggleValue === 'boolean' ? toggleValue : !currentTooltipOpen)
58-
}, [])
59-
60-
const evHandlers: ClickHandlersValue & UseHoverElementValue | {} = {
61-
...useClickHandlers(triggerRef, toggleOpen, triggerOn === 'click'),
62-
...useOnHoverElement(triggerRef.current, toggleOpen, triggerOn === 'hover'),
63-
}
64-
65-
useEffect(() => {
66-
67-
if (!tooltipOpen || !portalRef?.current || !tooltipRef?.current) {
68-
return
69-
}
70-
71-
const triggerEl: HTMLElement = triggerRef.current
72-
const box: DOMRect = triggerEl.getBoundingClientRect()
73-
const left: number = Math.max(box.left, windowWidth - (box.left + tooltipRef.current.getBoundingClientRect().width))
74-
75-
Object.assign(portalRef.current.style, {
76-
height: `${box.width}px`,
77-
left: `${left}px`,
78-
top: `${box.top + window.scrollY}px`,
79-
width: `${box.width + window.scrollX}px`,
80-
})
81-
}, [
82-
tooltipOpen,
83-
windowWidth,
84-
windowHeight,
85-
])
24+
const tooltipId: RefObject<string> = useRef<string>(uuidv4())
8625

8726
// if we didn't get a tooltip, just return an empty fragment
8827
if (!content) {
8928
return <></>
9029
}
9130

31+
let event: TooltipEvent = {}
32+
let tooltipProps: TooltipEvent = {}
33+
// The following attributes are required by react-tooltip when we want to show the tooltip on click rather than hover
34+
if (triggerOn === 'click') {
35+
tooltipProps = {
36+
globalEventOff: 'click',
37+
}
38+
event = {
39+
'data-event': 'click focus',
40+
}
41+
}
42+
9243
return (
93-
<div className={styles.tooltip}>
44+
<div>
9445
<div
95-
className={classNames('tooltip-icon', styles['tooltip-icon'])}
96-
ref={triggerRef}
97-
{...evHandlers}
46+
className='tooltip-icon'
47+
data-tip
48+
data-for={tooltipId.current}
49+
{...event}
9850
>
9951
{trigger}
10052
</div>
101-
{tooltipOpen && (
102-
<Portal portalRef={portalRef} className={styles['tooltip-portal']}>
103-
<div className={classNames(styles['tooltip-open'], `posy-${positionY}`, `posx-${positionX}`, className)} ref={tooltipRef}>
104-
<div className={styles['tooltip-arrow']}>
105-
<TooltipArrowIcon />
106-
</div>
107-
<div className={styles['tooltip-content']}>
108-
{content}
109-
</div>
110-
</div>
111-
</Portal>
112-
)}
53+
<ReactTooltip
54+
className={styles['tooltip']}
55+
id={tooltipId.current}
56+
aria-haspopup='true'
57+
place={place}
58+
effect='solid'
59+
event=''
60+
{...tooltipProps}
61+
>
62+
{content}
63+
</ReactTooltip>
11364
</div>
11465
)
11566
}

src-ts/tools/work/work-service-price/WorkServicePrice.module.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
}
5555

5656
.help {
57+
display: flex;
58+
align-items: center;
5759
margin-left: $space-sm;
5860
color: $turq-160;
5961
}

src-ts/tools/work/work-service-price/WorkServicePrice.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ const ServicePrice: FC<WorkServicePriceProps> = (props: WorkServicePriceProps) =
4343
<Tooltip
4444
content='The price and project length is dynamic and dependent on the
4545
variables selected as you define your work.'
46-
triggerOn='hover'
4746
trigger={(
4847
<IconOutline.QuestionMarkCircleIcon width={14} height={14} />
4948
)}

src-ts/tools/work/work-table/work-delete-button-renderer/WorkDeleteButtonRenderer.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ function WorkDeleteButtonRenderer(work: Work): JSX.Element | undefined {
3535
<>
3636
<Tooltip
3737
content='Delete'
38-
positionX='middle'
39-
positionY='end'
40-
triggerOn='hover'
38+
place='bottom'
4139
trigger={(
4240
<Button
4341
buttonStyle='icon'

0 commit comments

Comments
 (0)