I'm using Material-UI's Select component with a Tooltip surrounding it, like so:
<Tooltip title="Tooltip Test">
<Select value={this.state.age} onChange={this.handleChange}
inputProps={{ name: "age", id: "age-simple" }}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>...</MenuItem>
</Select>
</Tooltip>
My problem is that when I click the Select component, the Tooltip stays displayed, during the use of the Select, and even after an item was selected.
I want it to disappear as soon as the Select is clicked so that it doesn't stay over the MenuItems (Changing the zIndex is not the solution I want) and also still is not displayed even after selecting an item in the menu.
I made a codesandbox with the simple issue I have: https://codesandbox.io/s/yvloqr5qoj
But I am using typescript and this is the actual code I'm working with:
import * as React from 'react';
import PropTypes from 'prop-types';
import withStyles, { WithStyles } from 'material-ui/styles/withStyles';
import { Tooltip } from 'material-ui';
const styles = {
}
type State = {
open: boolean,
};
type Props = {
id: string,
msg: string,
children: PropTypes.node,
};
class ControlledTooltip extends React.PureComponent<Props & WithStyles<keyof typeof styles>, State> {
constructor(props) {
super(props);
this.state = {
open: false,
};
}
private handleTooltipClose(): void {
this.setState({ open: false });
}
private handleTooltipOpen(): void {
this.setState({ open: true });
}
render() {
const { id, msg, children } = this.props;
const { open } = this.state;
return(
<div>
<Tooltip id={id}
title={msg}
open={open}
onClose={this.handleTooltipClose}
onOpen={this.handleTooltipOpen}
>
{children ? children : null}
</Tooltip>
</div>
);
}
}
export default withStyles(styles)(ControlledTooltip);
<ControlledTooltip msg={'Filter'}>
<Select value={this.state.type} onChange={this.handleChange.bind(this, Filter.Type)}>
{this.docTypeFilters.map(item => {
return (<MenuItem key={item} value={item}>{item}</MenuItem>);
})}
</Select>
</ControlledTooltip>
TL;DR: You have to make your tooltip controlled.
UPDATE:
Based on your actual code, replace the return of your render()
with this:
<Tooltip id={id}
title={msg}
open={open}
>
<div onMouseEnter={this.handleTooltipOpen}
onMouseLeave={this.handleTooltipClose}
onClick={this.handleTooltipClose}
>
{children ? children : null}
</div>
</Tooltip>
The problem was that you were using onClose/onOpen from the tooltip, which works as is uncontrolled. Now the div
containing the select(or any children) has the control over the tooltip.
ANSWER FOR THE PASTEBINS
You will need to handle the open prop of the Tooltip:
class SimpleSelect ...
constructor(...
state = {..., open: false}; // the variable to control the tooltip
Alter your change handling:
handleChange = event => {
this.setState({ [event.target.name]: event.target.value, open: false });// keeps the tooltip hidding on the select changes
};
handleOpen = (open) => {
this.setState({ open }); // will show/hide tooltip when called
}
And reflect it in your render()
:
const { open } = this.state; // obtains the current value for the tooltip prop
...
<Tooltip title="Tooltip Test" open={open}>
...
<Select ... onMouseEnter={() => this.handleOpen(true)}
onMouseLeave={() => this.handleOpen(false)}
onClick={() => this.handleOpen(false)} >
The event handlers(onMouseEnter, onMouseLeave, onClick) in Select now control the tooltip show/hide behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With