-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Initial checklist
- I understand this is a bug report and questions should be posted in the Community Forum
- I searched issues and couldn’t find anything (or linked relevant results below)
Link to runnable example
https://stackblitz.com/edit/vitejs-vite-afcpwuqt?file=custom-element.ts
Steps to reproduce
- Open runnable example
- Repeat the following steps for both the "Shadow DOM" and "Light DOM" examples (there are 2 visible on the page)
- Attach a file
- Click "Edit" (pencil) button to edit the meta fields of your file (one is required)
- Enter some text into the custom meta field "My Meta Field"
- Click "Save Changes"
Expected behavior
After clicking "Save Changes" in either the "Shadow DOM" example or the "Light DOM" example, the text entered into the "My Meta Field" textbox should be accepted and the overlay should close.
Actual behavior
After clicking "Save Changes" in the "Light DOM" example, things work as expected.
After clicking "Save Changes" in the "Shadow DOM" example, nothing happens. The save isn't accepted.
This is because the mechanism for handling saves and edits is via a <form>, and the form element is initialized in the document.body instead of the nearest parent Document/ShadowRoot for where the Uppy Dashboard is rendered (this can be acquired via Node.getRootNode()). Form submits cannot cross Document/ShadowRoot boundaries, which is why the <button type="submit"> doesn't do anything.
uppy/packages/@uppy/dashboard/src/components/FileCard/index.tsx
Lines 69 to 79 in 55e926c
| useEffect(() => { | |
| document.body.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, handleSave]) |
uppy/packages/@uppy/dashboard/src/components/FileCard/index.tsx
Lines 155 to 163 in 55e926c
| <button | |
| className="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Dashboard-FileCard-actionsBtn" | |
| // If `form` attribute is supported, we want a submit button to trigger the form validation. | |
| // Otherwise, fallback to a classic button with a onClick event handler. | |
| type="submit" | |
| form={form.id} | |
| > | |
| {i18n('saveChanges')} | |
| </button> |
The runnable example uses Lit as an example using the ShadowDOM, as it's a popular library for creating custom elements.