Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use within iframe #121

Closed
NerdCowboy opened this issue Sep 13, 2019 · 5 comments · Fixed by atomiks/tippyjs#586
Closed

Can't use within iframe #121

NerdCowboy opened this issue Sep 13, 2019 · 5 comments · Fixed by atomiks/tippyjs#586

Comments

@NerdCowboy
Copy link

I'm using React Frame component to wrap my entire app in an iframe as I'm building a widget.

I'm getting the following errors when I try to use Tippy
index.js:159 Uncaught TypeError: instance.set is not a function
index.js:148 Uncaught TypeError: instance.destroy is not a function
index.js:1437 The above error occurred in the <Tippy> component: in Tippy (created by ForwardRef(TippyWrapper)) in ForwardRef(TippyWrapper) (at ItemDetail/index.js:84)…

I assumed the issue was that Tippy was trying to inject itself to the document body instead of the iframe's document body, so I used React Frame's context consumer and passed its document to my component and added it to appendTo.

<FrameContextConsumer>
  {
  ({ document, window }) => {  
    return (
      <Tippy appendTo={document.body} content="Text" >
        <button>Button</button>
      </Tippy>
    )
  }}
</FrameContextConsumer>
)

I tried console.logging the instance in the onCreate prop and it just returned an empty array, so that'd explain why there's no methods on instance

Digging into Tippy's code, it appears the creation of the Tippy div is hardcoded to the main document

export function ssrSafeCreateDiv() {
  return isBrowser && document.createElement('div')
}

Is there something I'm missing to allow usage within an iframe? Or am I correct that ssrSafeCreateDiv would need to be refactored to allow passing in a different document?

@Nantris
Copy link

Nantris commented Sep 30, 2019

I'm seeing this randomly in an Electron environment, but pretty frequently. I recently updated from 2.2.0 to 2.2.3. and from react@16.8.6 to react@16.9.0.

@NerdCowboy can you change the title to reflect that the issue affects more than just iframes.

@atomiks this is created 50 errors per second or more and freezes the process completely usually. Any thoughts?

Looks like I had a typo that caused a nesting of Tippy's in a way I hadn't intended.

@atomiks
Copy link
Owner

atomiks commented Sep 30, 2019

I tried console.logging the instance in the onCreate prop and it just returned an empty array, so that'd explain why there's no methods on instance

Means an invalid targets argument (the button ref was not defined) was being passed to tippy() core which seems odd

@atomiks
Copy link
Owner

atomiks commented Sep 30, 2019

Found the issue in tippy core:

value instanceof Element (value === <button> node) this is returning false.

So somehow the button node within the frame's context is not an instanceof Element


To make it work we need a different technique (weird how this issue has never come up before. I'm guessing it happens only when the tippy script is in a different document, since CodePen/Sandbox work fine in the frames)

This fixes it:

function isElement(value) {
  return isType(value, 'Element');
}

function isNodeList(value) {
  return isType(value, 'NodeList');
}

function isType(value, type) {
  const str = {}.toString.call(value);
  return str.indexOf('[object') === 0 && str.indexOf(`${type}]`) > -1;
}

That said this also opens up a host of other issues surrounding tippy's hardcoded use of document, such as the hideOnClick listeners. I'm pretty sure Popper handles all of this elegantly so I'll dive into its code to ensure tippy works better here.

@atomiks
Copy link
Owner

atomiks commented Oct 1, 2019

Run:

npm i @tippy.js/react@latest

iframes should be supported now

@NerdCowboy
Copy link
Author

Awesome! 🎉 Got temporarily pulled onto a different project, but I'll try to check it out sometime this week. Thanks @atomiks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants