react-tooltip 5.1.0-beta.0 → 5.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-tooltip",
3
- "version": "5.1.0-beta.0",
3
+ "version": "5.1.0-beta.1",
4
4
  "description": "react tooltip component",
5
5
  "scripts": {
6
6
  "dev": "node ./cli.js --env=development && node --max_old_space_size=2048 ./node_modules/rollup/dist/bin/rollup -c rollup.config.dev.js --watch",
package/src/App.tsx DELETED
@@ -1,79 +0,0 @@
1
- import { TooltipController as Tooltip } from 'components/TooltipController'
2
- import { useState } from 'react'
3
- import styles from './styles.module.css'
4
-
5
- function App() {
6
- const [anchorId, setAnchorId] = useState('button')
7
- const [isDarkOpen, setIsDarkOpen] = useState(false)
8
-
9
- return (
10
- <main className={styles['main']}>
11
- <button
12
- id="button"
13
- aria-describedby="tooltip"
14
- onClick={() => {
15
- setAnchorId('button')
16
- }}
17
- >
18
- My button
19
- </button>
20
- <Tooltip
21
- place="bottom"
22
- anchorId={anchorId}
23
- content="My big tooltip content"
24
- isOpen={isDarkOpen}
25
- setIsOpen={setIsDarkOpen}
26
- />
27
- <Tooltip
28
- place="top"
29
- variant="success"
30
- anchorId="button2"
31
- content="My big tooltip content"
32
- isOpen={isDarkOpen}
33
- setIsOpen={setIsDarkOpen}
34
- />
35
- <Tooltip
36
- place="top"
37
- variant="info"
38
- anchorId="button3"
39
- content="My big tooltip content"
40
- isOpen={isDarkOpen}
41
- setIsOpen={setIsDarkOpen}
42
- />
43
- <Tooltip
44
- place="right"
45
- variant="info"
46
- anchorId="button3"
47
- content="My big tooltip content"
48
- isOpen={isDarkOpen}
49
- setIsOpen={setIsDarkOpen}
50
- style={{ backgroundColor: '#ff00ff' }}
51
- />
52
-
53
- <section style={{ marginTop: '100px' }}>
54
- <p>
55
- <button
56
- id="button2"
57
- data-tip="Hello World from a Tooltip"
58
- onClick={() => {
59
- setAnchorId('button2')
60
- }}
61
- >
62
- Hover or focus me
63
- </button>
64
- <button
65
- id="button3"
66
- data-tip="Hello World from a Tooltip 2"
67
- onClick={() => {
68
- setAnchorId('button3')
69
- }}
70
- >
71
- Hover or focus me 2
72
- </button>
73
- </p>
74
- </section>
75
- </main>
76
- )
77
- }
78
-
79
- export default App
@@ -1,191 +0,0 @@
1
- import { createRef, useEffect, useState, useId, useRef } from 'react'
2
- import classNames from 'classnames'
3
- import debounce from 'utils/debounce'
4
- import { TooltipContent } from 'components/TooltipContent'
5
- import { computeToolTipPosition } from '../../utils/compute-positions'
6
- import styles from './styles.module.css'
7
- import type { ITooltip } from './TooltipTypes'
8
-
9
- const Tooltip = ({
10
- // props
11
- id = useId(),
12
- className,
13
- classNameArrow,
14
- variant = 'dark',
15
- anchorId,
16
- place = 'top',
17
- offset = 10,
18
- events = ['hover'],
19
- positionStrategy = 'absolute',
20
- wrapper: WrapperElement = 'div',
21
- children = null,
22
- delayShow = 0,
23
- delayHide = 0,
24
- style: externalStyles,
25
- // props handled by controller
26
- isHtmlContent = false,
27
- content,
28
- isOpen,
29
- setIsOpen,
30
- }: ITooltip) => {
31
- const tooltipRef = createRef()
32
- const tooltipArrowRef = createRef()
33
- const tooltipShowDelayTimerRef = useRef<ReturnType<typeof setTimeout>>()
34
- const tooltipHideDelayTimerRef = useRef<ReturnType<typeof setTimeout>>()
35
- const [inlineStyles, setInlineStyles] = useState({})
36
- const [inlineArrowStyles, setInlineArrowStyles] = useState({})
37
- const [show, setShow] = useState<boolean>(false)
38
-
39
- const handleShow = (value: boolean) => {
40
- if (setIsOpen) {
41
- setIsOpen(value)
42
- } else if (isOpen === undefined) {
43
- setShow(value)
44
- }
45
- }
46
-
47
- const handleShowTooltipDelayed = () => {
48
- if (tooltipShowDelayTimerRef.current) {
49
- clearTimeout(tooltipShowDelayTimerRef.current)
50
- }
51
-
52
- tooltipShowDelayTimerRef.current = setTimeout(() => {
53
- handleShow(true)
54
- }, delayShow)
55
- }
56
-
57
- const handleHideTooltipDelayed = () => {
58
- if (tooltipHideDelayTimerRef.current) {
59
- clearTimeout(tooltipHideDelayTimerRef.current)
60
- }
61
-
62
- tooltipHideDelayTimerRef.current = setTimeout(() => {
63
- handleShow(false)
64
- }, delayHide)
65
- }
66
-
67
- const handleShowTooltip = () => {
68
- if (delayShow) {
69
- handleShowTooltipDelayed()
70
- } else {
71
- handleShow(true)
72
- }
73
-
74
- if (tooltipHideDelayTimerRef.current) {
75
- clearTimeout(tooltipHideDelayTimerRef.current)
76
- }
77
- }
78
-
79
- const handleHideTooltip = () => {
80
- if (delayHide) {
81
- handleHideTooltipDelayed()
82
- } else {
83
- handleShow(false)
84
- }
85
-
86
- if (show && tooltipShowDelayTimerRef.current) {
87
- clearTimeout(tooltipShowDelayTimerRef.current)
88
- } else if (!show && tooltipShowDelayTimerRef.current) {
89
- // workaround to prevent tooltip being show forever
90
- // when we remove the mouse before show tooltip with `delayShow`
91
- tooltipHideDelayTimerRef.current = setTimeout(() => {
92
- handleShow(false)
93
- }, delayShow * 2)
94
- }
95
- }
96
-
97
- const handleClickTooltipAnchor = () => {
98
- if (setIsOpen) {
99
- setIsOpen(!isOpen)
100
- } else if (isOpen === undefined) {
101
- setShow((currentValue) => !currentValue)
102
- }
103
- }
104
-
105
- // debounce handler to prevent call twice when
106
- // mouse enter and focus events being triggered toggether
107
- const debouncedHandleShowTooltip = debounce(handleShowTooltip, 50)
108
- const debouncedHandleHideTooltip = debounce(handleHideTooltip, 50)
109
-
110
- useEffect(() => {
111
- const elementReference = document.querySelector(`#${anchorId}`)
112
-
113
- if (!elementReference) {
114
- // eslint-disable-next-line @typescript-eslint/no-empty-function
115
- return () => {}
116
- }
117
-
118
- const enabledEvents: { event: string; listener: () => void }[] = []
119
-
120
- if (events.find((event: string) => event === 'click')) {
121
- enabledEvents.push({ event: 'click', listener: handleClickTooltipAnchor })
122
- }
123
-
124
- if (events.find((event: string) => event === 'hover')) {
125
- enabledEvents.push(
126
- { event: 'mouseenter', listener: debouncedHandleShowTooltip },
127
- { event: 'mouseleave', listener: debouncedHandleHideTooltip },
128
- { event: 'focus', listener: debouncedHandleShowTooltip },
129
- { event: 'blur', listener: debouncedHandleHideTooltip },
130
- )
131
- }
132
-
133
- enabledEvents.forEach(({ event, listener }) => {
134
- elementReference?.addEventListener(event, listener)
135
- })
136
-
137
- return () => {
138
- enabledEvents.forEach(({ event, listener }) => {
139
- elementReference?.removeEventListener(event, listener)
140
- })
141
- }
142
- }, [anchorId, events, delayHide, delayShow])
143
-
144
- useEffect(() => {
145
- const elementReference = document.querySelector(`#${anchorId}`)
146
-
147
- computeToolTipPosition({
148
- place,
149
- offset,
150
- elementReference,
151
- tooltipReference: tooltipRef.current as HTMLElement,
152
- tooltipArrowReference: tooltipArrowRef.current as HTMLElement,
153
- strategy: positionStrategy,
154
- }).then((computedStylesData) => {
155
- if (Object.keys(computedStylesData.tooltipStyles).length) {
156
- setInlineStyles(computedStylesData.tooltipStyles)
157
- }
158
-
159
- if (Object.keys(computedStylesData.tooltipArrowStyles).length) {
160
- setInlineArrowStyles(computedStylesData.tooltipArrowStyles)
161
- }
162
- })
163
-
164
- return () => {
165
- tooltipShowDelayTimerRef.current = undefined
166
- tooltipHideDelayTimerRef.current = undefined
167
- }
168
- }, [show, isOpen, anchorId])
169
-
170
- return (
171
- <WrapperElement
172
- id={id}
173
- role="tooltip"
174
- className={classNames(styles['tooltip'], styles[variant], className, {
175
- [styles['show']]: isOpen || show,
176
- [styles['fixed']]: positionStrategy === 'fixed',
177
- })}
178
- style={{ ...externalStyles, ...inlineStyles }}
179
- ref={tooltipRef as React.RefObject<HTMLDivElement>}
180
- >
181
- {children || (isHtmlContent ? <TooltipContent content={content as string} /> : content)}
182
- <div
183
- className={classNames(styles['arrow'], classNameArrow)}
184
- style={inlineArrowStyles}
185
- ref={tooltipArrowRef as React.RefObject<HTMLDivElement>}
186
- />
187
- </WrapperElement>
188
- )
189
- }
190
-
191
- export default Tooltip
@@ -1,35 +0,0 @@
1
- import type { ElementType, ReactNode, Element, CSSProperties } from 'react'
2
-
3
- export type PlacesType = 'top' | 'right' | 'bottom' | 'left'
4
-
5
- export type VariantType = 'dark' | 'light' | 'success' | 'warning' | 'error' | 'info'
6
-
7
- export type WrapperType = ElementType | 'div' | 'span'
8
-
9
- export type ChildrenType = Element | ElementType | ReactNode
10
-
11
- export type EventsType = 'hover' | 'click'
12
-
13
- export type PositionStrategy = 'absolute' | 'fixed'
14
-
15
- export interface ITooltip {
16
- className?: string
17
- classNameArrow?: string
18
- content?: string | number
19
- html?: string
20
- place?: PlacesType
21
- offset?: number
22
- id?: string
23
- variant?: VariantType
24
- anchorId?: string
25
- isHtmlContent?: boolean
26
- wrapper?: WrapperType
27
- children?: ChildrenType
28
- events?: EventsType[]
29
- positionStrategy?: PositionStrategy
30
- delayShow?: number
31
- delayHide?: number
32
- style?: CSSProperties
33
- isOpen?: boolean
34
- setIsOpen?: (value: boolean) => void
35
- }
@@ -1 +0,0 @@
1
- export { default as Tooltip } from './Tooltip'
@@ -1,62 +0,0 @@
1
- .tooltip {
2
- visibility: hidden;
3
- width: max-content;
4
- position: absolute;
5
- top: 0;
6
- left: 0;
7
- padding: 8px 16px;
8
- border-radius: 3px;
9
- font-size: 90%;
10
- pointer-events: none;
11
- opacity: 0;
12
- transition: opacity 0.3s ease-out;
13
- will-change: opacity, visibility;
14
- }
15
-
16
- .fixed {
17
- position: fixed;
18
- }
19
-
20
- .arrow {
21
- position: absolute;
22
- background: inherit;
23
- width: 8px;
24
- height: 8px;
25
- transform: rotate(45deg);
26
- }
27
-
28
- .show {
29
- visibility: visible;
30
- opacity: 0.9;
31
- }
32
-
33
- /** Types variant **/
34
- .dark {
35
- background: var(--rt-color-dark);
36
- color: var(--rt-color-white);
37
- }
38
-
39
- .light {
40
- background-color: var(--rt-color-white);
41
- color: var(--rt-color-dark);
42
- }
43
-
44
- .success {
45
- background-color: var(--rt-color-success);
46
- color: var(--rt-color-white);
47
- }
48
-
49
- .warning {
50
- background-color: var(--rt-color-warning);
51
- color: var(--rt-color-white);
52
- }
53
-
54
- .error {
55
- background-color: var(--rt-color-error);
56
- color: var(--rt-color-white);
57
- }
58
-
59
- .info {
60
- background-color: var(--rt-color-info);
61
- color: var(--rt-color-white);
62
- }
@@ -1,8 +0,0 @@
1
- /* eslint-disable react/no-danger */
2
- import type { ITooltipContent } from './TooltipContentTypes'
3
-
4
- const TooltipContent = ({ content }: ITooltipContent) => {
5
- return <span dangerouslySetInnerHTML={{ __html: content }} />
6
- }
7
-
8
- export default TooltipContent
@@ -1,3 +0,0 @@
1
- export interface ITooltipContent {
2
- content: string
3
- }
@@ -1 +0,0 @@
1
- export { default as TooltipContent } from './TooltipContent'
@@ -1,203 +0,0 @@
1
- import { useEffect, useState } from 'react'
2
- import { Tooltip } from 'components/Tooltip'
3
- import type {
4
- EventsType,
5
- PositionStrategy,
6
- PlacesType,
7
- VariantType,
8
- WrapperType,
9
- } from 'components/Tooltip/TooltipTypes'
10
- import { dataAttributesKeys } from './constants'
11
- import type { ITooltipController } from './TooltipControllerTypes'
12
-
13
- const TooltipController = ({
14
- id,
15
- anchorId,
16
- content,
17
- html,
18
- className,
19
- classNameArrow,
20
- variant = 'dark',
21
- place = 'top',
22
- offset = 10,
23
- wrapper = 'div',
24
- children = null,
25
- events = ['hover'],
26
- positionStrategy = 'absolute',
27
- delayShow = 0,
28
- delayHide = 0,
29
- style,
30
- getContent,
31
- isOpen,
32
- setIsOpen,
33
- }: ITooltipController) => {
34
- const [tooltipContent, setTooltipContent] = useState(content || html)
35
- const [tooltipPlace, setTooltipPlace] = useState(place)
36
- const [tooltipVariant, setTooltipVariant] = useState(variant)
37
- const [tooltipOffset, setTooltipOffset] = useState(offset)
38
- const [tooltipDelayShow, setTooltipDelayShow] = useState(delayShow)
39
- const [tooltipDelayHide, setTooltipDelayHide] = useState(delayHide)
40
- const [tooltipWrapper, setTooltipWrapper] = useState<WrapperType>(wrapper)
41
- const [tooltipEvents, setTooltipEvents] = useState<EventsType[]>(events)
42
- const [tooltipPositionStrategy, setTooltipPositionStrategy] =
43
- useState<PositionStrategy>(positionStrategy)
44
- const [isHtmlContent, setIsHtmlContent] = useState<boolean>(Boolean(html))
45
-
46
- const getDataAttributesFromAnchorElement = (elementReference: HTMLElement) => {
47
- const dataAttributes = elementReference?.getAttributeNames().reduce((acc, name) => {
48
- if (name.includes('data-tooltip-')) {
49
- ;(acc as any)[name] = elementReference?.getAttribute(name)
50
- }
51
-
52
- return acc
53
- }, {})
54
-
55
- return dataAttributes
56
- }
57
-
58
- const applyAllDataAttributesFromAnchorElement = (dataAttributes: {
59
- [key: string]: string | number | boolean
60
- }) => {
61
- const keys = Object.keys(dataAttributes)
62
- let formatedKey = null
63
-
64
- const handleDataAttributes = {
65
- place: (value: PlacesType) => {
66
- setTooltipPlace(value)
67
- },
68
- content: (value: string) => {
69
- setIsHtmlContent(true)
70
- if (getContent) {
71
- setTooltipContent(getContent(value))
72
- } else {
73
- setTooltipContent(value)
74
- }
75
- },
76
- html: (value: string) => {
77
- setIsHtmlContent(true)
78
- if (getContent) {
79
- setTooltipContent(getContent(value))
80
- } else {
81
- setTooltipContent(value)
82
- }
83
- },
84
- variant: (value: VariantType) => {
85
- setTooltipVariant(value)
86
- },
87
- offset: (value: number) => {
88
- setTooltipOffset(value)
89
- },
90
- wrapper: (value: WrapperType) => {
91
- setTooltipWrapper(value)
92
- },
93
- events: (value: string) => {
94
- const parsedEvents = value.split(' ')
95
- setTooltipEvents(parsedEvents as EventsType[])
96
- },
97
- positionStrategy: (value: PositionStrategy) => {
98
- setTooltipPositionStrategy(value)
99
- },
100
- 'delay-show': (value: number) => {
101
- setTooltipDelayShow(Number(value))
102
- },
103
- 'delay-hide': (value: number) => {
104
- setTooltipDelayHide(Number(value))
105
- },
106
- }
107
-
108
- keys.forEach((key) => {
109
- formatedKey = key.replace('data-tooltip-', '')
110
-
111
- if (dataAttributesKeys.includes(formatedKey)) {
112
- // @ts-ignore
113
- handleDataAttributes[formatedKey](dataAttributes[key])
114
- }
115
- })
116
- }
117
-
118
- const getElementSpecificAttributeKeyAndValueParsed = ({
119
- element,
120
- attributeName,
121
- }: {
122
- element: HTMLElement
123
- attributeName: string
124
- }) => {
125
- return { [attributeName]: element.getAttribute(attributeName) }
126
- }
127
-
128
- useEffect(() => {
129
- if (!anchorId) {
130
- // eslint-disable-next-line @typescript-eslint/no-empty-function
131
- return () => {}
132
- }
133
-
134
- const elementReference = document.querySelector(`#${anchorId}`)
135
-
136
- if (!elementReference) {
137
- // eslint-disable-next-line @typescript-eslint/no-empty-function
138
- return () => {}
139
- }
140
-
141
- if (content && getContent) {
142
- setTooltipContent(getContent(content))
143
- }
144
-
145
- // do not check for subtree and childrens, we only want to know attribute changes
146
- // to stay watching `data-attributes` from anchor element
147
- const observerConfig = { attributes: true, childList: false, subtree: false }
148
-
149
- const observerCallback = (mutationList: any) => {
150
- mutationList.forEach((mutation: any) => {
151
- if (mutation.type === 'attributes') {
152
- const attributeKeyAndValue = getElementSpecificAttributeKeyAndValueParsed({
153
- element: elementReference as HTMLElement,
154
- attributeName: mutation.attributeName,
155
- })
156
-
157
- applyAllDataAttributesFromAnchorElement(
158
- attributeKeyAndValue as { [key: string]: string | number | boolean },
159
- )
160
- }
161
- })
162
- }
163
-
164
- // Create an observer instance linked to the callback function
165
- const observer = new MutationObserver(observerCallback)
166
-
167
- // Start observing the target node for configured mutations
168
- observer.observe(elementReference, observerConfig)
169
-
170
- const dataAttributes = getDataAttributesFromAnchorElement(elementReference as HTMLElement)
171
-
172
- applyAllDataAttributesFromAnchorElement(dataAttributes)
173
-
174
- return () => {
175
- // Remove the observer when the tooltip is destroyed
176
- observer.disconnect()
177
- }
178
- }, [anchorId])
179
-
180
- const props = {
181
- id,
182
- anchorId,
183
- className,
184
- classNameArrow,
185
- content: tooltipContent,
186
- isHtmlContent,
187
- place: tooltipPlace,
188
- variant: tooltipVariant,
189
- offset: tooltipOffset,
190
- wrapper: tooltipWrapper,
191
- events: tooltipEvents,
192
- positionStrategy: tooltipPositionStrategy,
193
- delayShow: tooltipDelayShow,
194
- delayHide: tooltipDelayHide,
195
- style,
196
- isOpen,
197
- setIsOpen,
198
- }
199
-
200
- return children ? <Tooltip {...props}>{children}</Tooltip> : <Tooltip {...props} />
201
- }
202
-
203
- export default TooltipController
@@ -1,32 +0,0 @@
1
- import type { CSSProperties } from 'react'
2
-
3
- import type {
4
- PlacesType,
5
- VariantType,
6
- WrapperType,
7
- ChildrenType,
8
- EventsType,
9
- PositionStrategy,
10
- } from 'components/Tooltip/TooltipTypes'
11
-
12
- export interface ITooltipController {
13
- className?: string
14
- classNameArrow?: string
15
- content?: string | number
16
- html?: string
17
- place?: PlacesType
18
- offset?: number
19
- id?: string
20
- variant?: VariantType
21
- anchorId?: string
22
- wrapper?: WrapperType
23
- children?: ChildrenType
24
- events?: EventsType[]
25
- positionStrategy?: PositionStrategy
26
- delayShow?: number
27
- delayHide?: number
28
- getContent?: (value) => string
29
- style?: CSSProperties
30
- isOpen?: boolean
31
- setIsOpen?: (value: boolean) => void
32
- }
@@ -1,11 +0,0 @@
1
- export const dataAttributesKeys = [
2
- 'place', // place of tooltip
3
- 'content', // content of tooltip
4
- 'html', // html content of tooltip
5
- 'variant', // variant of tooltip
6
- 'offset', // offset of tooltip
7
- 'wrapper', // wrapper of tooltip
8
- 'events', // events of tooltip
9
- 'delay-show', // delay to show tooltip
10
- 'delay-hide', // delay to hide tooltip
11
- ]
@@ -1 +0,0 @@
1
- export { default as TooltipController } from './TooltipController'
package/src/index-dev.tsx DELETED
@@ -1,15 +0,0 @@
1
- import { StrictMode, version } from 'react'
2
- import { createRoot } from 'react-dom/client'
3
- import './tokens.css'
4
- import App from './App'
5
-
6
- console.log('Parent folder loaded react version: ', version)
7
-
8
- const container = document.getElementById('app')
9
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
10
- const root = createRoot(container!)
11
- root.render(
12
- <StrictMode>
13
- <App />
14
- </StrictMode>,
15
- )
package/src/index.tsx DELETED
@@ -1,3 +0,0 @@
1
- import './tokens.css'
2
-
3
- export { TooltipController as Tooltip } from './components/TooltipController'
@@ -1,5 +0,0 @@
1
- .main {
2
- margin: 0 auto;
3
- width: 100%;
4
- height: 100vh;
5
- }
@@ -1,107 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`tooltip props basic tooltip component 1`] = `
4
- [
5
- <span
6
- id="basic-example"
7
- >
8
- Lorem Ipsum
9
- </span>,
10
- <div
11
- className=""
12
- id=":r2:"
13
- role="tooltip"
14
- style={{}}
15
- >
16
- Hello World!
17
- <div
18
- className=""
19
- style={{}}
20
- />
21
- </div>,
22
- ]
23
- `;
24
-
25
- exports[`tooltip props tooltip component - getContent 1`] = `
26
- [
27
- <span
28
- id="basic-example-get-content"
29
- >
30
- Lorem Ipsum
31
- </span>,
32
- <div
33
- className=""
34
- id=":r4:"
35
- role="tooltip"
36
- style={{}}
37
- >
38
- Hello World!
39
- <div
40
- className=""
41
- style={{}}
42
- />
43
- </div>,
44
- ]
45
- `;
46
-
47
- exports[`tooltip props tooltip component - html 1`] = `
48
- [
49
- <span
50
- id="basic-example-html"
51
- >
52
- Lorem Ipsum
53
- </span>,
54
- <div
55
- className=""
56
- id=":r3:"
57
- role="tooltip"
58
- style={{}}
59
- >
60
- <span
61
- dangerouslySetInnerHTML={
62
- {
63
- "__html": "Hello World!",
64
- }
65
- }
66
- />
67
- <div
68
- className=""
69
- style={{}}
70
- />
71
- </div>,
72
- ]
73
- `;
74
-
75
- exports[`tooltip props tooltip component - without anchorId 1`] = `
76
- [
77
- <span>
78
- Lorem Ipsum
79
- </span>,
80
- <div
81
- className=""
82
- id=":r0:"
83
- role="tooltip"
84
- style={{}}
85
- >
86
- Hello World!
87
- <div
88
- className=""
89
- style={{}}
90
- />
91
- </div>,
92
- ]
93
- `;
94
-
95
- exports[`tooltip props tooltip component - without element reference 1`] = `
96
- <div
97
- className=""
98
- id=":r1:"
99
- role="tooltip"
100
- style={{}}
101
- >
102
- <div
103
- className=""
104
- style={{}}
105
- />
106
- </div>
107
- `;
@@ -1,142 +0,0 @@
1
- import renderer from 'react-test-renderer'
2
- import debounce from 'utils/debounce'
3
- import { computeToolTipPosition } from 'utils/compute-positions'
4
- import { TooltipController as Tooltip } from '../components/TooltipController'
5
-
6
- // Tell Jest to mock all timeout functions
7
- jest.useFakeTimers()
8
-
9
- const TooltipProps = ({ id, ...tooltipParams }) => (
10
- <>
11
- <span id={id}>Lorem Ipsum</span>
12
- <Tooltip anchorId={id} {...tooltipParams} />
13
- </>
14
- )
15
-
16
- describe('tooltip props', () => {
17
- test('tooltip component - without anchorId', () => {
18
- const component = renderer.create(<TooltipProps content="Hello World!" />)
19
- const tree = component.toJSON()
20
- expect(tree).toMatchSnapshot()
21
- })
22
-
23
- test('tooltip component - without element reference', () => {
24
- const component = renderer.create(<Tooltip />)
25
- const tree = component.toJSON()
26
- expect(tree).toMatchSnapshot()
27
- })
28
-
29
- test('basic tooltip component', () => {
30
- const component = renderer.create(<TooltipProps id="basic-example" content="Hello World!" />)
31
- const tree = component.toJSON()
32
- expect(tree).toMatchSnapshot()
33
- })
34
-
35
- test('tooltip component - html', () => {
36
- const component = renderer.create(
37
- <TooltipProps id="basic-example-html" html="Hello World!" variant="info" place="top" />,
38
- )
39
- const tree = component.toJSON()
40
- expect(tree).toMatchSnapshot()
41
- })
42
-
43
- test('tooltip component - getContent', () => {
44
- const component = renderer.create(
45
- <TooltipProps
46
- id="basic-example-get-content"
47
- content="Hello World!"
48
- getContent={(value) => `${value} Manipuled!`}
49
- variant="info"
50
- place="top"
51
- />,
52
- )
53
- const tree = component.toJSON()
54
- expect(tree).toMatchSnapshot()
55
- })
56
- })
57
-
58
- describe('compute positions', () => {
59
- test('empty reference elements', async () => {
60
- const value = await computeToolTipPosition({
61
- elementReference: null,
62
- tooltipReference: null,
63
- tooltipArrowReference: null,
64
- })
65
-
66
- expect(value).toEqual({ tooltipStyles: {}, tooltipArrowStyles: {} })
67
- })
68
-
69
- test('empty tooltip reference element', async () => {
70
- const element = document.createElement('div')
71
- const value = await computeToolTipPosition({
72
- elementReference: element,
73
- tooltipReference: null,
74
- tooltipArrowReference: null,
75
- })
76
-
77
- expect(value).toEqual({ tooltipStyles: {}, tooltipArrowStyles: {} })
78
- })
79
-
80
- test('empty tooltip arrow reference element', async () => {
81
- const element = document.createElement('div')
82
- const elementTooltip = document.createElement('div')
83
- const value = await computeToolTipPosition({
84
- elementReference: element,
85
- tooltipReference: elementTooltip,
86
- tooltipArrowReference: null,
87
- })
88
-
89
- expect(value).toEqual({
90
- tooltipArrowStyles: {},
91
- tooltipStyles: {
92
- left: '5px',
93
- top: '10px',
94
- },
95
- })
96
- })
97
-
98
- test('all reference elements', async () => {
99
- const element = document.createElement('div')
100
- const elementTooltip = document.createElement('div')
101
- const elementTooltipArrow = document.createElement('div')
102
- const value = await computeToolTipPosition({
103
- elementReference: element,
104
- tooltipReference: elementTooltip,
105
- tooltipArrowReference: elementTooltipArrow,
106
- })
107
-
108
- expect(value).toEqual({
109
- tooltipArrowStyles: {
110
- bottom: '-4px',
111
- left: '0px',
112
- right: '',
113
- top: '',
114
- },
115
- tooltipStyles: {
116
- left: '5px',
117
- top: '-10px',
118
- },
119
- })
120
- })
121
- })
122
-
123
- describe('debounce', () => {
124
- let func
125
- let debouncedFunc
126
-
127
- beforeEach((timeout = 1000) => {
128
- func = jest.fn()
129
- debouncedFunc = debounce(func, timeout)
130
- })
131
-
132
- test('execute just once', () => {
133
- for (let i = 0; i < 100; i += 1) {
134
- debouncedFunc()
135
- }
136
-
137
- // Fast-forward time
138
- jest.runAllTimers()
139
-
140
- expect(func).toBeCalledTimes(1)
141
- })
142
- })
package/src/tokens.css DELETED
@@ -1,8 +0,0 @@
1
- :root {
2
- --rt-color-white: #fff;
3
- --rt-color-dark: #222;
4
- --rt-color-success: #8dc572;
5
- --rt-color-error: #be6464;
6
- --rt-color-warning: #f0ad4e;
7
- --rt-color-info: #337ab7;
8
- }
@@ -1,8 +0,0 @@
1
- export interface IComputePositions {
2
- elementReference?: Element | HTMLElement | null
3
- tooltipReference?: Element | HTMLElement | null
4
- tooltipArrowReference?: Element | HTMLElement | null
5
- place?: 'top' | 'right' | 'bottom' | 'left'
6
- offset?: number
7
- strategy?: 'absolute' | 'fixed'
8
- }
@@ -1,66 +0,0 @@
1
- import { computePosition, offset, flip, shift, arrow } from '@floating-ui/dom'
2
- import type { IComputePositions } from './compute-positions-types'
3
-
4
- export const computeToolTipPosition = async ({
5
- elementReference = null,
6
- tooltipReference = null,
7
- tooltipArrowReference = null,
8
- place = 'top',
9
- offset: offsetValue = 10,
10
- strategy = 'absolute',
11
- }: IComputePositions) => {
12
- if (!elementReference) {
13
- // elementReference can be null or undefined and we will not compute the position
14
- // eslint-disable-next-line no-console
15
- // console.error('The reference element for tooltip was not defined: ', elementReference)
16
- return { tooltipStyles: {}, tooltipArrowStyles: {} }
17
- }
18
-
19
- if (tooltipReference === null) {
20
- return { tooltipStyles: {}, tooltipArrowStyles: {} }
21
- }
22
-
23
- const middleware = [offset(Number(offsetValue)), flip(), shift({ padding: 5 })]
24
-
25
- if (tooltipArrowReference) {
26
- middleware.push(arrow({ element: tooltipArrowReference as HTMLElement }))
27
- return computePosition(elementReference as HTMLElement, tooltipReference as HTMLElement, {
28
- placement: place,
29
- strategy,
30
- middleware,
31
- }).then(({ x, y, placement, middlewareData }) => {
32
- const styles = { left: `${x}px`, top: `${y}px` }
33
-
34
- // @ts-ignore
35
- const { x: arrowX, y: arrowY } = middlewareData.arrow
36
-
37
- const staticSide = {
38
- top: 'bottom',
39
- right: 'left',
40
- bottom: 'top',
41
- left: 'right',
42
- }[placement.split('-')[0]]
43
-
44
- const arrowStyle = {
45
- left: arrowX != null ? `${arrowX}px` : '',
46
- top: arrowY != null ? `${arrowY}px` : '',
47
- right: '',
48
- bottom: '',
49
- // @ts-ignore
50
- [staticSide]: '-4px',
51
- }
52
-
53
- return { tooltipStyles: styles, tooltipArrowStyles: arrowStyle }
54
- })
55
- }
56
-
57
- return computePosition(elementReference as HTMLElement, tooltipReference as HTMLElement, {
58
- placement: 'bottom',
59
- strategy,
60
- middleware,
61
- }).then(({ x, y }) => {
62
- const styles = { left: `${x}px`, top: `${y}px` }
63
-
64
- return { tooltipStyles: styles, tooltipArrowStyles: {} }
65
- })
66
- }
@@ -1,32 +0,0 @@
1
- /* eslint-disable func-names */
2
- /* eslint-disable prefer-rest-params */
3
- /* eslint-disable @typescript-eslint/no-this-alias */
4
- /**
5
- * This function debounce the received function
6
- * @param { function } func Function to be debounced
7
- * @param { number } wait Time to wait before execut the function
8
- * @param { boolean } immediate Param to define if the function will be executed immediately
9
- */
10
- const debounce = (func: { (): void; (): void; apply?: any }, wait?: number, immediate?: true) => {
11
- let timeout: string | number | NodeJS.Timeout | null | undefined
12
-
13
- return function () {
14
- // @ts-ignore
15
- const context = this
16
- const args = arguments
17
-
18
- const later = () => {
19
- timeout = null
20
- if (!immediate) {
21
- func.apply(context, args)
22
- }
23
- }
24
-
25
- // @ts-ignore
26
- clearTimeout(timeout)
27
-
28
- timeout = setTimeout(later, wait)
29
- }
30
- }
31
-
32
- export default debounce