@discoveryjs/discovery
Version:
Frontend framework for rapid data (JSON) analysis, shareable serverless reports and dashboards
86 lines (85 loc) • 2.79 kB
JavaScript
import { createElement } from "../core/utils/dom.js";
export default Object.assign(setup(), { setup });
const isExtension = (value) => /^\./.test(value);
function setup(options) {
options = {
accept: "application/json,application/jsonxl,.json,.jsonxl",
useAcceptForFilePicker: false,
dragdrop: true,
clipboard: false,
...options
};
return function(host) {
const useAcceptForFilePicker = Boolean(options.useAcceptForFilePicker);
const dragdrop = Boolean(options.dragdrop);
const clipboard = Boolean(options.clipboard);
const accept = String(options.accept);
const acceptTokens = accept.split(",");
if (dragdrop) {
host.dom.container.addEventListener("drop", (event) => {
host.loadDataFromEvent(event);
}, true);
host.dom.container.addEventListener("dragover", (event) => {
event.stopPropagation();
event.preventDefault();
}, true);
document.addEventListener("paste", (e) => {
const { files } = e.clipboardData || { files: [] };
if (files?.length > 0) {
host.loadDataFromEvent(e);
}
});
}
host.preset.define("upload", [
{
view: "button-primary",
text: '=`Open file${#.actions.uploadFile.fileExtensions |? " (" + join(", ") + ")" : "" | size() > 1 and size() <= 17 ?: "\u2026"}`',
onClick: "=#.actions.uploadFile"
},
{
view: "context",
when: "#.actions.uploadDataFromClipboard",
content: [
'html:"<span style=\\"color: #888; padding: 0 1ex\\"> or </span>"',
{
view: "button",
text: "Paste from clipboard",
onClick: "=#.actions.uploadDataFromClipboard"
}
]
},
{
view: "context",
when: "#.actions.uploadFile.dragdrop",
content: [
'html:"<span style=\\"color: #888; padding: 0 1ex\\"> or </span>"',
'text:"drop a file on the page"'
]
}
]);
host.action.define("unloadData", () => {
host.unloadData();
});
host.action.define("uploadFile", Object.assign(
() => {
createElement("input", {
type: "file",
accept: useAcceptForFilePicker ? accept : void 0,
onchange: (event) => host.loadDataFromEvent(event)
}).click();
},
{
fileExtensions: acceptTokens.filter((token) => isExtension(token)),
mimeTypes: acceptTokens.filter((token) => !isExtension(token)),
dragdrop,
clipboard
}
));
if (clipboard) {
host.action.define("uploadDataFromClipboard", async () => {
const items = await navigator.clipboard.readText();
host.loadDataFromStream(new Blob([items]).stream());
});
}
};
}