question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using component children

See original GitHub issue

The current way to use a component children with tippy is to either use forwardRef or to wrap the component in a span tag.

However, I was wondering if by any chance there was another way to make it work ?

I just updated to the latest version of tippy and putting forwardRef everywhere is not maintainable. I would like to keep the accessibility so the span is also a problem (and it break the design sometimes as well). I don’t use styled components either.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
Arkellyscommented, Mar 23, 2019

Oh ok I see, thank you for the explanation, this change is understandable then! Yes I meant a class component, I have just tried your solution and it work well!

Thank you for your help, and for this great library. 😃

3reactions
sidx1024commented, Jun 24, 2021

I don’t like these solutions where you need to use forwardRef and make things complicated. So I’ve made a wrapper that gets the reference to your DOM element by sibling reference. Sharing it here:

/**
 * A tooltip component which does not wrap the child component in a <span> element and does not require to passing a forwardRef.
 * It gets the child's reference by inserting an adjacent element.
 * This adjacent element is removed from the DOM when the sibling's ref is available.
 *
 * @param options
 * @param children
 * @returns {JSX.Element}
 * @constructor
 */
export function Tooltip({ options, children }) {
  /**
   * Reference for the temporary span element.
   */
  const spanRef = useRef(null);
  const [childRef, setChildRef] = useState(null);

  /**
   * Mount the temporary span element.
   * retrieve and store the target element's reference.
   */
  useEffect(() => {
    if (spanRef.current) {
      setChildRef(spanRef.current.previousElementSibling);
    }
    return () => setChildRef(null);
  }, []);

  return (
    <React.Fragment>
      {children}
      {childRef ? (
        <Tippy {...options} reference={childRef} />
      ) : (
        <span ref={spanRef} style={{ display: "none" }} />
      )}
    </React.Fragment>
  );
}

Tooltip.propTypes = {
  options: PropTypes.object,
  /**
   * Custom PropType to check for a single child.
   */
  children: (props, propName, componentName) => {
    const prop = props[propName];
    if (React.Children.count(prop) > 1) {
      return new Error(`${componentName} cannot have multiple children.`);
    }
    if (!React.isValidElement(prop)) {
      return new Error(`${componentName} has a child which is not a DOM element.`);
    }
  },
};

Tooltip.defaultProps = {
  options: {},
  children: null,
};

// Usage
function MyComponent() {
  return (
    <Tooltip content="Click to submit">
      <Button>Submit</Button>
    </Tooltip>
  );
}

The only thing you need to make sure is to have only one child component inside <Tooltip> to make it work.

Read more comments on GitHub >

github_iconTop Results From Across the Web

A Complete Guide To props.children In React - codeburst
Essentially, props.children is a special prop, automatically passed to every component, that can be used to render the content included between the opening...
Read more >
Composition vs Inheritance - React
React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components. In this section, we...
Read more >
Using Children in React - We Learn Code
Using Children in React. You can use props.children in React in order to access and utilize what you put inside the open and...
Read more >
Component Children | Build with React JS
Children allow you to pass components as data to other components, just like any other prop you use. The special thing about children...
Read more >
React Children And Iteration Methods - Smashing Magazine
In this article, we'll discuss and learn about the use case of iterating over React children and the ways to do it. In...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found