Reputation: 2025
I'm using React material
framework in one of my projects. I'm trying to add multiple controlled tooltips
which are going to be visible only when their respective state
is visible
.
Unfortunately, right now I'm stuck because I'm sharing the same state with multiple components hence all the tooltips are visible once you hover on any one of them. Is there any way to do so ? I think this can be done by array.
P.S there are going to be multiple parent components
inside a page each having three set of tooltip i.e Edit, Delete, View
class ControlledTooltips extends React.Component {
state = {
open: false,
};
handleTooltipClose = () => {
this.setState({ open: false });
};
handleTooltipOpen = () => {
this.setState({ open: true });
};
render() {
return (
<div>
<Tooltip
enterDelay={300}
id="tooltip-controlled"
leaveDelay={300}
onClose={this.handleTooltipClose}
onOpen={this.handleTooltipOpen}
open={this.state.open}
placement="bottom"
title="Edit"
>
<IconButton aria-label="Delete">
<Edit />
</IconButton>
</Tooltip>
<Tooltip
enterDelay={300}
id="tooltip-controlled"
leaveDelay={300}
onClose={this.handleTooltipClose}
onOpen={this.handleTooltipOpen}
open={this.state.open}
placement="bottom"
title="view"
>
<IconButton aria-label="view">
<Visibility />
</IconButton>
</Tooltip>
<Tooltip
enterDelay={300}
id="tooltip-controlleded"
leaveDelay={300}
onClose={this.handleTooltipClose}
onOpen={this.handleTooltipOpen}
open={this.state.open}
placement="bottom"
title="Delete"
>
<IconButton aria-label="Delete">
<DeleteOutlined />
</IconButton>
</Tooltip>
</div>
);
}
}
Any help will be appreciated :)
Upvotes: 1
Views: 2608
Reputation: 3187
I would advise against complicating your component state too much. In my opinion, each component should control a very precise part of its state.
What I would recommend is to create a custom tooltip that will handle the state for each element. You can build your 3 Edit, Delete, View
width them.
class TooltipCustom extends React.Component {
state = {
open: false
};
toggleState = () => {
this.setState({ open: !this.state.open });
};
render() {
return (
<IconButton aria-label={this.props.title}>
<Tooltip
enterDelay={300}
leaveDelay={300}
onClose={this.toggleState}
onOpen={this.toggleState}
open={this.state.open}
placement="bottom"
title={this.props.title}
>
{this.props.children}
</Tooltip>
</IconButton>
);
}
}
const Delete = () => (
<TooltipCustom title="delete">
<DeleteIcon />
</TooltipCustom>
);
const Edit = () => (
<TooltipCustom title="Edit">
<EditIcon />
</TooltipCustom>
);
const View = () => (
<TooltipCustom title="View">
<VisibilityIcon />
</TooltipCustom>
);
const ControlledTooltips = () => (
<div>
<Delete />
<Edit />
<View />
</div>
);
Upvotes: 2
Reputation: 2025
In case someone is looking for an answer. As suggested by @Einar Ólafsson, I made a custom tooltip wrapper which had all three tooltips inside it.
Tooltip name
which was needed to be shown was passed to handleTooltipOpen() and handleTooltipClose()
function. Inside this function, I changed the state of the individual tooltip.
class ControlledTooltips extends React.Component {
state = {
edit: false,
delete: false,
view: false
};
handleTooltipClose = (name) => {
this.setState({ [name]: false });
};
handleTooltipOpen = (name) => {
this.setState({ [name]: true });
};
render() {
return (
<div>
<Tooltip
id="tooltip-controlled-delete"
onClose={() => this.handleTooltipClose("delete")}
onOpen={() => this.handleTooltipOpen("delete")}
open={this.state.delete}
placement="bottom"
title="Delete"
>
<IconButton name="delete" aria-label="Delete">
<DeleteOutlined name="delete" />
</IconButton>
</Tooltip>
<Tooltip
id="tooltip-controlled-edit"
onClose={() => this.handleTooltipClose("edit")}
onOpen={() => this.handleTooltipOpen("edit")}
open={this.state.edit}
placement="bottom"
title="edit"
>
<IconButton name="edit" aria-label="edit">
<Edit />
</IconButton>
</Tooltip>
<Tooltip
id="tooltip-controlled-view"
onClose={() => this.handleTooltipClose("view")}
onOpen={() => this.handleTooltipOpen("view")}
open={this.state.view}
placement="bottom"
title="view"
>
<IconButton name="view" aria-label="view">
<Visibility />
</IconButton>
</Tooltip>
</div>
);
}
}
Upvotes: 0