-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.tsx
116 lines (94 loc) · 3.48 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { FunctionComponent, useEffect, useState, useRef } from "react"
import styled from 'styled-components'
import './styles.css'
import { Explanation } from "../../../domain/explanation"
import { usePopper } from 'react-popper';
interface Props {
explanation: Explanation
explanationNumber: number
showExplanations: boolean
referenceElement?: HTMLElement
}
const ExplanationTooltip: FunctionComponent<Props> = ({
explanation,
explanationNumber,
showExplanations,
}) => {
const [popperElement, setPopperElement] = useState(null);
const [arrowElement, setArrowElement] = useState(null);
const referenceElementRef = useRef<HTMLElement>(null);
useEffect(() => {
const referenceElement = document.querySelector(`[data-explanation="${explanation.index}"]`) as HTMLElement;
referenceElementRef.current = referenceElement;
}, [explanation.index]);
useEffect(() => {
const referenceElement = document.querySelector(`[data-explanation="${explanation.index}"]`) as HTMLElement;
if(showExplanations && parseInt(explanation.index) === explanationNumber) {
referenceElement.scrollIntoView({ behavior: 'smooth' })
}
}, [explanationNumber, showExplanations, explanation.index])
useEffect(() => {
const references = document.querySelectorAll(`[data-explanation="${explanationNumber}"]`) as NodeListOf<HTMLElement>
const explanations = document.querySelectorAll(`[data-explanation]`) as NodeListOf<HTMLElement>
let parentDiv: HTMLElement | null = null
// here we should remove the background color from all the explanations
explanations.forEach( e => {
e.style.zIndex = '0'
e.style.background = 'transparent';
parentDiv = e.parentElement as HTMLElement;
if (parentDiv) {
parentDiv.style.zIndex = '0';
}
if(parentDiv.tagName.toLocaleLowerCase() === 'p') {
const div = parentDiv.parentElement as HTMLElement
const highlited = div?.parentElement as HTMLElement
highlited.style.zIndex = '0'
}
})
// here we should highlight the current explanation
references.forEach( reference => {
if(reference && showExplanations) {
parentDiv = reference.parentElement as HTMLElement;
reference.style.zIndex = '4';
reference.style.background = 'white';
if (parentDiv) {
parentDiv.style.zIndex = '4';
}
if(parentDiv.tagName.toLocaleLowerCase() === 'p') {
const div = parentDiv.parentElement as HTMLElement
const highlited = div?.parentElement as HTMLElement
highlited.style.zIndex = '4'
}
}
})
}, [explanationNumber, showExplanations])
const { styles, attributes } = usePopper(referenceElementRef.current, popperElement, {
modifiers: [
{ name: 'flip', options: { fallbackPlacements: ['top', 'bottom'], padding: 100 }},
{ name: 'arrow', options: { element: arrowElement } }
],
});
return (
<Wrapper
ref={setPopperElement}
id={`explanation-${explanation.index}`}
className="tooltip"
style={styles.popper}
{...attributes.popper}
hide={parseInt(explanation.index) !== explanationNumber || !showExplanations}
>
{explanation.text}
<div ref={setArrowElement} id='arrow' style={styles.arrow}/>
</Wrapper>
)
}
const Wrapper = styled('div')<{ hide: boolean }>`
${props => props.hide && `
visibility: hidden;
> #arrow::before {
visibility: hidden;
}
`
}
`
export default ExplanationTooltip