Skip to content

Commit a013f2e

Browse files
[Popper] Fix deep merge of PopperProps (#19851)
1 parent 4548eef commit a013f2e

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

docs/pages/api/tooltip.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
4141
| <span class="prop-name">onOpen</span> | <span class="prop-type">func</span> | | Callback fired when the component requests to be open.<br><br>**Signature:**<br>`function(event: object) => void`<br>*event:* The event source of the callback. |
4242
| <span class="prop-name">open</span> | <span class="prop-type">bool</span> | | If `true`, the tooltip is shown. |
4343
| <span class="prop-name">placement</span> | <span class="prop-type">'bottom-end'<br>&#124;&nbsp;'bottom-start'<br>&#124;&nbsp;'bottom'<br>&#124;&nbsp;'left-end'<br>&#124;&nbsp;'left-start'<br>&#124;&nbsp;'left'<br>&#124;&nbsp;'right-end'<br>&#124;&nbsp;'right-start'<br>&#124;&nbsp;'right'<br>&#124;&nbsp;'top-end'<br>&#124;&nbsp;'top-start'<br>&#124;&nbsp;'top'</span> | <span class="prop-default">'bottom'</span> | Tooltip placement. |
44-
| <span class="prop-name">PopperProps</span> | <span class="prop-type">object</span> | | Props applied to the [`Popper`](/api/popper/) element. |
44+
| <span class="prop-name">PopperProps</span> | <span class="prop-type">object</span> | <span class="prop-default">{}</span> | Props applied to the [`Popper`](/api/popper/) element. |
4545
| <span class="prop-name required">title&nbsp;*</span> | <span class="prop-type">node</span> | | Tooltip title. Zero-length titles string are never displayed. |
4646
| <span class="prop-name">TransitionComponent</span> | <span class="prop-type">elementType</span> | <span class="prop-default">Grow</span> | The component used for the transition. [Follow this guide](/components/transitions/#transitioncomponent-prop) to learn more about the requirements for this component. |
4747
| <span class="prop-name">TransitionProps</span> | <span class="prop-type">object</span> | | Props applied to the [`Transition`](http://reactcommunity.org/react-transition-group/transition#Transition-props) element. |

packages/material-ui/src/Tooltip/Tooltip.js

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react';
22
import * as ReactDOM from 'react-dom';
33
import PropTypes from 'prop-types';
44
import clsx from 'clsx';
5-
import { elementAcceptingRef } from '@material-ui/utils';
5+
import { deepmerge, elementAcceptingRef } from '@material-ui/utils';
66
import { fade } from '../styles/colorManipulator';
77
import withStyles from '../styles/withStyles';
88
import capitalize from '../utils/capitalize';
@@ -194,7 +194,7 @@ const Tooltip = React.forwardRef(function Tooltip(props, ref) {
194194
onOpen,
195195
open: openProp,
196196
placement = 'bottom',
197-
PopperProps,
197+
PopperProps = {},
198198
title,
199199
TransitionComponent = Grow,
200200
TransitionProps,
@@ -484,18 +484,21 @@ const Tooltip = React.forwardRef(function Tooltip(props, ref) {
484484
}
485485
}
486486

487-
// Avoid the creation of a new Popper.js instance at each render.
488-
const popperOptions = React.useMemo(
489-
() => ({
490-
modifiers: {
491-
arrow: {
492-
enabled: Boolean(arrowRef),
493-
element: arrowRef,
487+
const mergedPopperProps = React.useMemo(() => {
488+
return deepmerge(
489+
{
490+
popperOptions: {
491+
modifiers: {
492+
arrow: {
493+
enabled: Boolean(arrowRef),
494+
element: arrowRef,
495+
},
496+
},
494497
},
495498
},
496-
}),
497-
[arrowRef],
498-
);
499+
PopperProps,
500+
);
501+
}, [arrowRef, PopperProps]);
499502

500503
return (
501504
<React.Fragment>
@@ -510,9 +513,8 @@ const Tooltip = React.forwardRef(function Tooltip(props, ref) {
510513
open={childNode ? open : false}
511514
id={childrenProps['aria-describedby']}
512515
transition
513-
popperOptions={popperOptions}
514516
{...interactiveWrapperListeners}
515-
{...PopperProps}
517+
{...mergedPopperProps}
516518
>
517519
{({ placement: placementInner, TransitionProps: TransitionPropsInner }) => (
518520
<TransitionComponent

packages/material-ui/src/Tooltip/Tooltip.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,38 @@ describe('<Tooltip />', () => {
397397
});
398398
});
399399

400+
describe('prop: PopperProps', () => {
401+
it('should pass PopperProps to Popper Component', () => {
402+
const { getByTestId } = render(
403+
<Tooltip {...defaultProps} open PopperProps={{ 'data-testid': 'popper' }} />,
404+
);
405+
406+
expect(getByTestId('popper')).to.be.ok;
407+
});
408+
409+
it('should merge popperOptions with arrow modifier', () => {
410+
const popperRef = React.createRef();
411+
render(
412+
<Tooltip
413+
{...defaultProps}
414+
open
415+
arrow
416+
PopperProps={{
417+
popperRef,
418+
popperOptions: {
419+
modifiers: {
420+
arrow: {
421+
foo: 'bar',
422+
},
423+
},
424+
},
425+
}}
426+
/>,
427+
);
428+
expect(popperRef.current.modifiers.find(x => x.name === 'arrow').foo).to.equal('bar');
429+
});
430+
});
431+
400432
describe('forward', () => {
401433
it('should forward props to the child element', () => {
402434
const wrapper = mount(

0 commit comments

Comments
 (0)