1

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>
    );
  }
}

codesandbox link

Any help will be appreciated :)

3
  • Can you demonstrate the actual problem in your sandbox demo? Commented Dec 1, 2018 at 22:07
  • 1
    @EinarÓlafsson I have updated the link. Commented Dec 1, 2018 at 22:18
  • 1
    I've written a suggestion for you @vijayscode, hope it helps. Commented Dec 2, 2018 at 21:30

2 Answers 2

2

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>
);
Sign up to request clarification or add additional context in comments.

Comments

0

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>
    );
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.