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

Dropdown does not work properly in the Shadow DOM #35897

Closed
Jaggler3 opened this issue Jun 2, 2022 · 5 comments
Closed

Dropdown does not work properly in the Shadow DOM #35897

Jaggler3 opened this issue Jun 2, 2022 · 5 comments

Comments

@Jaggler3
Copy link

Jaggler3 commented Jun 2, 2022

Reproduction link

Edit on CodeSandbox

Steps to reproduce

Click each dropdown/trigger twice and observe the open/closing effect.

What is expected?

It is expected for the dropdown in the web component to open on the first click and close on the 2nd click

What is actually happening?

The dropdown in the web component is opening on the first click, and closing of the 2nd mouse-down, and reopening on the following mouse-up.

Environment Info
antd 4.20.7
React (latest) 18.1.0
System macOS 12.3.1
Browser Brave: Version 1.39.111 Chromium: 102.0.5005.61 (Official Build) (x86_64)

The actual problem lies in rc-trigger, which is used by rc-dropdown which Ant Design uses for it's Dropdown component. It tries to reference the root of the element by using element.ownerDocument, which returns the #document almost always, when in certain cases we would want it to return a #shadow-root.

My current workaround:

const CustomDropdown = (props) =>

  const documentElement = useMemo(() => {
    if (!props.getPopupContainer) return
    const popupContainer = props.getPopupContainer()
    if (!popupContainer) return
    const newDocumentElement = popupContainer.getRootNode()
    const owner = popupContainer.ownerDocument
    if (newDocumentElement !== owner && !newDocumentElement.createElement) {
      newDocumentElement.createElement = (...args) => document.createElement(...args)
    }
    return newDocumentElement
  }, [props.getPopupContainer])

  return (
    <AntdDropdown
      // begin rc-trigger props
      getDocument={documentElement && (() => documentElement)}
      // end rc-trigger props
      {...props}
    > ...

I'm using a prop that is eventually passed down to rc-trigger, though I do not think it is specified anywhere in the documentation that this is possible.

@Jaggler3
Copy link
Author

Jaggler3 commented Jun 3, 2022

I've updated the CodeSandbox to include all broken components, which are:

Dropdown,
Menu,
Popover,
Tooltip,
Popconfirm

@MadCcc
Copy link
Member

MadCcc commented Jun 6, 2022

Your workaround is reasonable, and you can config this with ConfigProvider.
getDocument is not stable currently and we may not specify it in docs of antd.

@errolgr
Copy link

errolgr commented Mar 14, 2023

I ran into this issue and was able to resolve this by using a ref from the parent component

  <Dropdown
             getPopupContainer={() => ref.current}
>...

@scarqin
Copy link

scarqin commented Jan 19, 2024

or

const shadowRoot = root.attachShadow({ mode: 'open' })

...

  <ConfigProvider>
...
          getPopupContainer={(node) => {
            return shadowRoot
          }}
</ConfigProvider>

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

No branches or pull requests

4 participants