Skip to content

Commit b62fa2f

Browse files
feat: disableStyleInjection tooltip prop
1 parent 9d35880 commit b62fa2f

File tree

4 files changed

+66
-29
lines changed

4 files changed

+66
-29
lines changed

src/components/TooltipController/TooltipController.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const TooltipController = ({
4444
style,
4545
position,
4646
isOpen,
47+
disableStyleInjection = false,
4748
setIsOpen,
4849
afterShow,
4950
afterHide,
@@ -61,6 +62,7 @@ const TooltipController = ({
6162
const [tooltipEvents, setTooltipEvents] = useState(events)
6263
const [tooltipPositionStrategy, setTooltipPositionStrategy] = useState(positionStrategy)
6364
const [activeAnchor, setActiveAnchor] = useState<HTMLElement | null>(null)
65+
const styleInjectionRef = useRef(disableStyleInjection)
6466
/**
6567
* @todo Remove this in a future version (provider/wrapper method is deprecated)
6668
*/
@@ -168,11 +170,26 @@ const TooltipController = ({
168170
setTooltipPositionStrategy(positionStrategy)
169171
}, [positionStrategy])
170172

173+
useEffect(() => {
174+
if (styleInjectionRef.current === disableStyleInjection) {
175+
return
176+
}
177+
if (process.env.NODE_ENV !== 'production') {
178+
// eslint-disable-next-line no-console
179+
console.warn('[react-tooltip] Do not change `disableStyleInjection` dynamically.')
180+
}
181+
}, [disableStyleInjection])
182+
171183
useEffect(() => {
172184
if (typeof window !== 'undefined') {
173-
// here we can do validations related to the props before inject the styles,
174-
// we can also send something into the 'detail' to the inject style function
175-
window.dispatchEvent(new CustomEvent('rt_inject_styles', { detail: {} }))
185+
window.dispatchEvent(
186+
new CustomEvent('react-tooltip-inject-styles', {
187+
detail: {
188+
disableCore: disableStyleInjection === 'core',
189+
disableBase: disableStyleInjection,
190+
},
191+
}),
192+
)
176193
}
177194
}, [])
178195

src/components/TooltipController/TooltipControllerTypes.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export interface ITooltipController {
6060
style?: CSSProperties
6161
position?: IPosition
6262
isOpen?: boolean
63+
disableStyleInjection?: boolean | 'core'
6364
setIsOpen?: (value: boolean) => void
6465
afterShow?: () => void
6566
afterHide?: () => void

src/index.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,16 @@ const TooltipCoreStyles = 'react-tooltip-core-css-placeholder'
2121
const TooltipStyles = 'react-tooltip-css-placeholder'
2222

2323
if (typeof window !== 'undefined') {
24-
window.addEventListener('rt_inject_styles', () => {
25-
injectStyle({ css: TooltipCoreStyles, type: 'core' })
26-
injectStyle({ css: TooltipStyles })
27-
})
24+
window.addEventListener('react-tooltip-inject-styles', ((
25+
event: CustomEvent<{ disableCore: boolean; disableBase: boolean }>,
26+
) => {
27+
if (!event.detail.disableCore) {
28+
injectStyle({ css: TooltipCoreStyles, type: 'core' })
29+
}
30+
if (!event.detail.disableBase) {
31+
injectStyle({ css: TooltipStyles, type: 'base' })
32+
}
33+
}) as EventListener)
2834
}
2935

3036
export { TooltipController as Tooltip } from './components/TooltipController'
@@ -42,5 +48,3 @@ export type {
4248
IPosition,
4349
Middleware,
4450
}
45-
46-
export { removeStyle } from './utils/handle-style'

src/utils/handle-style.ts

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ const REACT_TOOLTIP_CORE_STYLES_ID = 'react-tooltip-core-styles'
33
// This is the ID for the visual styles of ReactTooltip
44
const REACT_TOOLTIP_BASE_STYLES_ID = 'react-tooltip-base-styles'
55

6+
const injected = {
7+
core: false,
8+
base: false,
9+
}
10+
611
function injectStyle({
712
css,
813
id = REACT_TOOLTIP_BASE_STYLES_ID,
@@ -11,26 +16,10 @@ function injectStyle({
1116
}: {
1217
css: string
1318
id?: string
14-
type?: string
19+
type?: 'core' | 'base'
1520
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1621
ref?: any
1722
}) {
18-
if (
19-
type === 'core' &&
20-
typeof process !== 'undefined' && // this validation prevents docs from breaking even with `process?`
21-
process?.env?.REACT_TOOLTIP_DISABLE_CORE_STYLES
22-
) {
23-
return
24-
}
25-
26-
if (
27-
type !== 'core' &&
28-
typeof process !== 'undefined' && // this validation prevents docs from breaking even with `process?`
29-
process?.env?.REACT_TOOLTIP_DISABLE_BASE_STYLES
30-
) {
31-
return
32-
}
33-
3423
if (type === 'core') {
3524
// eslint-disable-next-line no-param-reassign
3625
id = REACT_TOOLTIP_CORE_STYLES_ID
@@ -42,7 +31,18 @@ function injectStyle({
4231
}
4332
const { insertAt } = ref
4433

45-
if (!css || typeof document === 'undefined' || document.getElementById(id)) {
34+
if (!css || typeof document === 'undefined' || injected[type]) {
35+
return
36+
}
37+
38+
if (document.getElementById(id)) {
39+
// this should never happen because of `injected[type]`
40+
if (process.env.NODE_ENV !== 'production') {
41+
// eslint-disable-next-line no-console
42+
console.warn(
43+
`[react-tooltip] Element with id '${id}' already exists. Call \`removeStyle()\` first`,
44+
)
45+
}
4646
return
4747
}
4848

@@ -67,22 +67,37 @@ function injectStyle({
6767
} else {
6868
style.appendChild(document.createTextNode(css))
6969
}
70+
71+
injected[type] = true
7072
}
7173

7274
function removeStyle({
7375
type = 'base',
7476
id = REACT_TOOLTIP_BASE_STYLES_ID,
7577
}: {
76-
type?: string
78+
type?: 'core' | 'base'
7779
id?: string
7880
} = {}) {
81+
if (!injected[type]) {
82+
return
83+
}
84+
7985
if (type === 'core') {
8086
// eslint-disable-next-line no-param-reassign
8187
id = REACT_TOOLTIP_CORE_STYLES_ID
8288
}
8389

8490
const style = document.getElementById(id)
85-
style?.remove()
91+
if (style?.tagName === 'style') {
92+
style?.remove()
93+
} else if (process.env.NODE_ENV !== 'production') {
94+
// eslint-disable-next-line no-console
95+
console.warn(
96+
`[react-tooltip] Failed to remove 'style' element with id '${id}'. Call \`injectStyle()\` first`,
97+
)
98+
}
99+
100+
injected[type] = false
86101
}
87102

88103
export { injectStyle, removeStyle }

0 commit comments

Comments
 (0)