mirror of
https://github.com/transloadit/uppy.git
synced 2026-01-23 02:25:07 +00:00
@uppy/dashboard: fix form appending for shadow dom (#6031)
Fixes #6028
I've also added `private/dev/dashboard_shadow.html` to more easily test
ShadowDOM-specific bugs.
I looked into writing a test case under
`packages/@uppy/dashboard/src/index.browser.test.ts` but couldn't get it
to work locally on Windows.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Ensure FileCard’s hidden form is appended/cleaned up in the correct
root (Document body or ShadowRoot) using a ref-derived root node, and
add a patch changeset.
>
> - **@uppy/dashboard – FileCard**:
> - Append hidden `form` to the correct root using `getRootNode()`
(handles Light DOM/iframes via `Document.body`, and Shadow DOM via
`ShadowRoot`).
> - Add `domRef` to root element to detect rendering context; attach
`ref` and update effect accordingly.
> - Clean up by removing the `form` from its actual `parentNode`.
> - **Release**:
> - Add changeset for patch: `Fix form appending for shadow dom`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
edf81e871c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Murderlon <merlijn@soverin.net>
This commit is contained in:
parent
b1e33bcef7
commit
5e166a101d
2 changed files with 32 additions and 3 deletions
5
.changeset/funny-insects-clean.md
Normal file
5
.changeset/funny-insects-clean.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@uppy/dashboard": patch
|
||||
---
|
||||
|
||||
Fix form appending for shadow dom
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import classNames from 'classnames'
|
||||
import { nanoid } from 'nanoid/non-secure'
|
||||
import { useCallback, useEffect, useState } from 'preact/hooks'
|
||||
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
|
||||
import getFileTypeIcon from '../../utils/getFileTypeIcon.js'
|
||||
import ignoreEvent from '../../utils/ignoreEvent.js'
|
||||
import FilePreview from '../FilePreview.js'
|
||||
|
|
@ -66,14 +66,37 @@ export default function FileCard(props: $TSFixMe) {
|
|||
return formEl
|
||||
})
|
||||
|
||||
// We need to know where Uppy is being rendered
|
||||
const domRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
document.body.appendChild(form)
|
||||
/**
|
||||
* Use the "rootNode" of whereever Uppy is rendered, falling back
|
||||
* to `window.document` if domRef isn't initialized for some reason
|
||||
*/
|
||||
const rootNode = domRef.current?.getRootNode() ?? (document as Node)
|
||||
/**
|
||||
* This is the case for the Light DOM and <iframes>.
|
||||
* In these scenarios, we don't want to append a child to an
|
||||
* <html> element, but to the <body>
|
||||
*/
|
||||
if (rootNode instanceof Document) {
|
||||
rootNode.body.appendChild(form)
|
||||
}
|
||||
// This is the case for the Shadow DOM
|
||||
else if (rootNode instanceof ShadowRoot) {
|
||||
rootNode.appendChild(form)
|
||||
}
|
||||
// Everything else (realistically there isn't)
|
||||
else {
|
||||
rootNode.appendChild(form)
|
||||
}
|
||||
form.addEventListener('submit', handleSave)
|
||||
return () => {
|
||||
form.removeEventListener('submit', handleSave)
|
||||
// check if form is still in the DOM before removing
|
||||
if (form.parentNode) {
|
||||
document.body.removeChild(form)
|
||||
form.parentNode.removeChild(form)
|
||||
}
|
||||
}
|
||||
}, [form, handleSave])
|
||||
|
|
@ -87,6 +110,7 @@ export default function FileCard(props: $TSFixMe) {
|
|||
onDragLeave={ignoreEvent}
|
||||
onDrop={ignoreEvent}
|
||||
onPaste={ignoreEvent}
|
||||
ref={domRef}
|
||||
>
|
||||
<div className="uppy-DashboardContent-bar">
|
||||
<div
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue