Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions packages/@uppy/dashboard/src/components/FileCard/index.tsx
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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])
Expand All @@ -87,6 +110,7 @@ export default function FileCard(props: $TSFixMe) {
onDragLeave={ignoreEvent}
onDrop={ignoreEvent}
onPaste={ignoreEvent}
ref={domRef}
>
<div className="uppy-DashboardContent-bar">
<div
Expand Down
6 changes: 3 additions & 3 deletions private/dev/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function getCompanionKeysParams(name) {

// Rest is implementation! Obviously edit as necessary...

export default () => {
export default (options) => {
const restrictions = undefined
// const restrictions = {
// maxFileSize: 1 * 1000000, // 1mb
Expand All @@ -104,9 +104,9 @@ export default () => {
restrictions,
})
.use(Dashboard, {
trigger: '#pick-files',
trigger: options.trigger,
// inline: true,
target: '.foo',
target: options.target,
metaFields: [
{ id: 'license', name: 'License', placeholder: 'specify license' },
{ id: 'caption', name: 'Caption', placeholder: 'add caption' },
Expand Down
82 changes: 82 additions & 0 deletions private/dev/dashboard_shadow.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Dashboard</title>
<link rel="icon" type="image/png" href="https://uppy.io/img/logo.svg" />
<style>
host-element {
display: block;
outline: 1px dashed royalblue;
}
</style>
</head>

<body>
<host-element id="shadow-host">
<!-- Creates a ShadowRoot declaratively, see: https://web.dev/articles/declarative-shadow-dom -->
<template shadowrootmode="open">
<main class="foo">
<h1>Dashboard is here (Shadow DOM edition)</h1>

<!-- some inputs in a form to check focus management in Dashboard -->
<form id="upload-form" action="/">
<button type="button" id="pick-files">Pick Files</button><br />
True ?
<input type="checkbox" name="check_test" value="1" checked /><br />
Something: <input type="text" name="yo" value="1" /><br />
<input type="hidden" name="bla" value="12333" /><br />
<button type="submit">Submit</button>
</form>
</main>
<style>
main {
display: block;
width: fit-content;
margin: 100px auto;
}

h1 {
text-align: center;
}

#upload-form {
max-width: 400px;
text-align: left;
margin: auto;
}

/* css to make sure that Dashboard's css overrides page css */
button,
input {
color: green;
font-size: 30px;
text-align: right;
border: 2px solid purple;
}
ul {
margin: 60px;
}
li {
margin: 60px;
}
a {
color: purple;
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: green;
}
</style>
</template>
</host-element>


<script src="./index.js" type="module"></script>
</body>
</html>
22 changes: 21 additions & 1 deletion private/dev/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
import 'uppy/dist/uppy.css'
import uppyStyles from 'uppy/dist/uppy.css?inline'

import Dashboard from './Dashboard.js'
import DragDrop from './DragDrop.js'

switch (window.location.pathname.toLowerCase()) {
case '/':
case '/dashboard.html':
Dashboard()
Dashboard({
trigger: '#pick-files',
target: '.foo',
})
break
case '/dragdrop.html':
DragDrop()
break
case '/dashboard_shadow.html':
const shadowRoot = document.getElementById('shadow-host').shadowRoot;
if (!shadowRoot) break;
// Apply Uppy styles to the Shadow DOM
const uppyCSS = new CSSStyleSheet();
uppyCSS.replaceSync(uppyStyles)
shadowRoot.adoptedStyleSheets = [
...shadowRoot.adoptedStyleSheets,
uppyCSS,
];
// Run in the Shadow DOM
Dashboard({
trigger: shadowRoot.querySelector('#pick-files'),
target: shadowRoot.querySelector('.foo'),
})
break
default:
throw new Error('404')
}
Expand Down
Loading