Skip to content
This repository was archived by the owner on Nov 9, 2024. It is now read-only.

Commit 05010b6

Browse files
committed
fix(useSingleton): className prop
1 parent da91329 commit 05010b6

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

src/Tippy.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import {
55
preserveRef,
66
ssrSafeCreateDiv,
77
toDataAttributes,
8-
updateClassName,
98
deepPreserveProps,
9+
updateClassName,
1010
} from './utils';
1111
import {useMutableBox, useIsomorphicLayoutEffect} from './util-hooks';
1212

@@ -116,6 +116,7 @@ export default function TippyGenerator(tippy) {
116116
instance,
117117
content,
118118
props: computedProps,
119+
className,
119120
});
120121
}
121122

@@ -157,7 +158,8 @@ export default function TippyGenerator(tippy) {
157158
singleton.hook({
158159
instance,
159160
content,
160-
props: computedProps,
161+
props,
162+
className,
161163
});
162164
}
163165
});

src/useSingleton.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {useMutableBox, useIsomorphicLayoutEffect} from './util-hooks';
2-
import {deepPreserveProps} from './utils';
2+
import {deepPreserveProps, updateClassName} from './utils';
33
import {useMemo} from 'react';
44

55
export default function useSingletonGenerator(createSingleton) {
@@ -77,6 +77,34 @@ export default function useSingletonGenerator(createSingleton) {
7777
}
7878
});
7979

80+
useIsomorphicLayoutEffect(() => {
81+
const className = mutableBox.sourceData?.className;
82+
83+
if (className) {
84+
if (mutableBox.sourceData?.props.render) {
85+
if (process.env.NODE_ENV !== 'production') {
86+
console.warn(
87+
[
88+
'@tippyjs/react: Cannot use `className` prop in conjunction',
89+
'with the `render` prop. Place the className on the element',
90+
'you are rendering.',
91+
].join(' '),
92+
);
93+
}
94+
95+
return;
96+
}
97+
98+
const box = mutableBox.instance.popper.firstElementChild;
99+
100+
updateClassName(box, 'add', className);
101+
102+
return () => {
103+
updateClassName(box, 'remove', className);
104+
};
105+
}
106+
});
107+
80108
return useMemo(() => {
81109
const source = {
82110
data: mutableBox,

test/useSingleton.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,36 @@ it('changes the singleton content correctly', () => {
5151
expect(instance.props.content.textContent).toBe('b');
5252
});
5353

54+
it('updates `className` correctly', () => {
55+
function App({className}) {
56+
const [source, target] = useSingleton();
57+
58+
return (
59+
<>
60+
<Tippy onCreate={onCreate} className={className} singleton={source} />
61+
<Tippy content="a" singleton={target}>
62+
<button data-testid="a" />
63+
</Tippy>
64+
<Tippy content="b" singleton={target}>
65+
<button data-testid="b" />
66+
</Tippy>
67+
</>
68+
);
69+
}
70+
71+
const {rerender} = render(<App className="some class names" />);
72+
73+
expect(
74+
instance.popper.firstElementChild.className.includes('some class names'),
75+
).toBe(true);
76+
77+
rerender(<App className="other names" />);
78+
79+
expect(
80+
instance.popper.firstElementChild.className.includes('other names'),
81+
).toBe(true);
82+
});
83+
5484
describe('disabled prop', () => {
5585
function App({disabled}) {
5686
const [source, target] = useSingleton({disabled});

0 commit comments

Comments
 (0)