@uppy/dashboard
Version:
Universal UI plugin for Uppy.
329 lines (324 loc) • 13.2 kB
JavaScript
let _Symbol$for;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck Typing this file requires more work, skipping it to unblock the rest of the transition.
/* eslint-disable react/destructuring-assignment */
import { h, Component, Fragment } from 'preact';
_Symbol$for = Symbol.for('uppy test: disable unused locale key warning');
class AddFiles extends Component {
constructor() {
super(...arguments);
this.triggerFileInputClick = () => {
this.fileInput.click();
};
this.triggerFolderInputClick = () => {
this.folderInput.click();
};
this.triggerVideoCameraInputClick = () => {
this.mobileVideoFileInput.click();
};
this.triggerPhotoCameraInputClick = () => {
this.mobilePhotoFileInput.click();
};
this.onFileInputChange = event => {
this.props.handleInputChange(event);
// We clear the input after a file is selected, because otherwise
// change event is not fired in Chrome and Safari when a file
// with the same name is selected.
// ___Why not use value="" on <input/> instead?
// Because if we use that method of clearing the input,
// Chrome will not trigger change if we drop the same file twice (Issue #768).
event.target.value = null; // eslint-disable-line no-param-reassign
};
this.renderHiddenInput = (isFolder, refCallback) => {
return h("input", {
className: "uppy-Dashboard-input",
hidden: true,
"aria-hidden": "true",
tabIndex: -1,
webkitdirectory: isFolder,
type: "file",
name: "files[]",
multiple: this.props.maxNumberOfFiles !== 1,
onChange: this.onFileInputChange,
accept: this.props.allowedFileTypes,
ref: refCallback
});
};
this.renderHiddenCameraInput = (type, nativeCameraFacingMode, refCallback) => {
const typeToAccept = {
photo: 'image/*',
video: 'video/*'
};
const accept = typeToAccept[type];
return h("input", {
className: "uppy-Dashboard-input",
hidden: true,
"aria-hidden": "true",
tabIndex: -1,
type: "file",
name: `camera-${type}`,
onChange: this.onFileInputChange,
capture: nativeCameraFacingMode,
accept: accept,
ref: refCallback
});
};
this.renderMyDeviceAcquirer = () => {
return h("div", {
className: "uppy-DashboardTab",
role: "presentation",
"data-uppy-acquirer-id": "MyDevice"
}, h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn",
role: "tab",
tabIndex: 0,
"data-uppy-super-focusable": true,
onClick: this.triggerFileInputClick
}, h("div", {
className: "uppy-DashboardTab-inner"
}, h("svg", {
className: "uppy-DashboardTab-iconMyDevice",
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("path", {
d: "M8.45 22.087l-1.305-6.674h17.678l-1.572 6.674H8.45zm4.975-12.412l1.083 1.765a.823.823 0 00.715.386h7.951V13.5H8.587V9.675h4.838zM26.043 13.5h-1.195v-2.598c0-.463-.336-.75-.798-.75h-8.356l-1.082-1.766A.823.823 0 0013.897 8H7.728c-.462 0-.815.256-.815.718V13.5h-.956a.97.97 0 00-.746.37.972.972 0 00-.19.81l1.724 8.565c.095.44.484.755.933.755H24c.44 0 .824-.3.929-.727l2.043-8.568a.972.972 0 00-.176-.825.967.967 0 00-.753-.38z",
fill: "currentcolor",
"fill-rule": "evenodd"
}))), h("div", {
className: "uppy-DashboardTab-name"
}, this.props.i18n('myDevice'))));
};
this.renderPhotoCamera = () => {
return h("div", {
className: "uppy-DashboardTab",
role: "presentation",
"data-uppy-acquirer-id": "MobilePhotoCamera"
}, h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn",
role: "tab",
tabIndex: 0,
"data-uppy-super-focusable": true,
onClick: this.triggerPhotoCameraInputClick
}, h("div", {
className: "uppy-DashboardTab-inner"
}, h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("path", {
d: "M23.5 9.5c1.417 0 2.5 1.083 2.5 2.5v9.167c0 1.416-1.083 2.5-2.5 2.5h-15c-1.417 0-2.5-1.084-2.5-2.5V12c0-1.417 1.083-2.5 2.5-2.5h2.917l1.416-2.167C13 7.167 13.25 7 13.5 7h5c.25 0 .5.167.667.333L20.583 9.5H23.5zM16 11.417a4.706 4.706 0 00-4.75 4.75 4.704 4.704 0 004.75 4.75 4.703 4.703 0 004.75-4.75c0-2.663-2.09-4.75-4.75-4.75zm0 7.825c-1.744 0-3.076-1.332-3.076-3.074 0-1.745 1.333-3.077 3.076-3.077 1.744 0 3.074 1.333 3.074 3.076s-1.33 3.075-3.074 3.075z",
fill: "#02B383",
"fill-rule": "nonzero"
}))), h("div", {
className: "uppy-DashboardTab-name"
}, this.props.i18n('takePictureBtn'))));
};
this.renderVideoCamera = () => {
return h("div", {
className: "uppy-DashboardTab",
role: "presentation",
"data-uppy-acquirer-id": "MobileVideoCamera"
}, h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn",
role: "tab",
tabIndex: 0,
"data-uppy-super-focusable": true,
onClick: this.triggerVideoCameraInputClick
}, h("div", {
className: "uppy-DashboardTab-inner"
}, h("svg", {
"aria-hidden": "true",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("path", {
fill: "#FF675E",
fillRule: "nonzero",
d: "m21.254 14.277 2.941-2.588c.797-.313 1.243.818 1.09 1.554-.01 2.094.02 4.189-.017 6.282-.126.915-1.145 1.08-1.58.34l-2.434-2.142c-.192.287-.504 1.305-.738.468-.104-1.293-.028-2.596-.05-3.894.047-.312.381.823.426 1.069.063-.384.206-.744.362-1.09zm-12.939-3.73c3.858.013 7.717-.025 11.574.02.912.129 1.492 1.237 1.351 2.217-.019 2.412.04 4.83-.03 7.239-.17 1.025-1.166 1.59-2.029 1.429-3.705-.012-7.41.025-11.114-.019-.913-.129-1.492-1.237-1.352-2.217.018-2.404-.036-4.813.029-7.214.136-.82.83-1.473 1.571-1.454z "
}))), h("div", {
className: "uppy-DashboardTab-name"
}, this.props.i18n('recordVideoBtn'))));
};
this.renderBrowseButton = (text, onClickFn) => {
const numberOfAcquirers = this.props.acquirers.length;
return h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-Dashboard-browse",
onClick: onClickFn,
"data-uppy-super-focusable": numberOfAcquirers === 0
}, text);
};
this.renderDropPasteBrowseTagline = numberOfAcquirers => {
const browseFiles = this.renderBrowseButton(this.props.i18n('browseFiles'), this.triggerFileInputClick);
const browseFolders = this.renderBrowseButton(this.props.i18n('browseFolders'), this.triggerFolderInputClick);
// in order to keep the i18n CamelCase and options lower (as are defaults) we will want to transform a lower
// to Camel
const lowerFMSelectionType = this.props.fileManagerSelectionType;
const camelFMSelectionType = lowerFMSelectionType.charAt(0).toUpperCase() + lowerFMSelectionType.slice(1);
return h("div", {
class: "uppy-Dashboard-AddFiles-title"
},
// eslint-disable-next-line no-nested-ternary
this.props.disableLocalFiles ? this.props.i18n('importFiles') : numberOfAcquirers > 0 ? this.props.i18nArray(`dropPasteImport${camelFMSelectionType}`, {
browseFiles,
browseFolders,
browse: browseFiles
}) : this.props.i18nArray(`dropPaste${camelFMSelectionType}`, {
browseFiles,
browseFolders,
browse: browseFiles
}));
};
this.renderAcquirer = acquirer => {
var _this$props$activePic;
return h("div", {
className: "uppy-DashboardTab",
role: "presentation",
"data-uppy-acquirer-id": acquirer.id
}, h("button", {
type: "button",
className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn",
role: "tab",
tabIndex: 0,
"data-cy": acquirer.id,
"aria-controls": `uppy-DashboardContent-panel--${acquirer.id}`,
"aria-selected": ((_this$props$activePic = this.props.activePickerPanel) == null ? void 0 : _this$props$activePic.id) === acquirer.id,
"data-uppy-super-focusable": true,
onClick: () => this.props.showPanel(acquirer.id)
}, h("div", {
className: "uppy-DashboardTab-inner"
}, acquirer.icon()), h("div", {
className: "uppy-DashboardTab-name"
}, acquirer.name)));
};
this.renderAcquirers = acquirers => {
// Group last two buttons, so we don’t end up with
// just one button on a new line
const acquirersWithoutLastTwo = [...acquirers];
const lastTwoAcquirers = acquirersWithoutLastTwo.splice(acquirers.length - 2, acquirers.length);
return h(Fragment, null, acquirersWithoutLastTwo.map(acquirer => this.renderAcquirer(acquirer)), h("span", {
role: "presentation",
style: {
'white-space': 'nowrap'
}
}, lastTwoAcquirers.map(acquirer => this.renderAcquirer(acquirer))));
};
this.renderSourcesList = (acquirers, disableLocalFiles) => {
const {
showNativePhotoCameraButton,
showNativeVideoCameraButton
} = this.props;
let list = [];
const myDeviceKey = 'myDevice';
if (!disableLocalFiles) list.push({
key: myDeviceKey,
elements: this.renderMyDeviceAcquirer()
});
if (showNativePhotoCameraButton) list.push({
key: 'nativePhotoCameraButton',
elements: this.renderPhotoCamera()
});
if (showNativeVideoCameraButton) list.push({
key: 'nativePhotoCameraButton',
elements: this.renderVideoCamera()
});
list.push(...acquirers.map(acquirer => ({
key: acquirer.id,
elements: this.renderAcquirer(acquirer)
})));
// doesn't make sense to show only a lonely "My Device"
const hasOnlyMyDevice = list.length === 1 && list[0].key === myDeviceKey;
if (hasOnlyMyDevice) list = [];
// Group last two buttons, so we don’t end up with
// just one button on a new line
const listWithoutLastTwo = [...list];
const lastTwo = listWithoutLastTwo.splice(list.length - 2, list.length);
const renderList = l => l.map(_ref => {
let {
key,
elements
} = _ref;
return h(Fragment, {
key: key
}, elements);
});
return h(Fragment, null, this.renderDropPasteBrowseTagline(list.length), h("div", {
className: "uppy-Dashboard-AddFiles-list",
role: "tablist"
}, renderList(listWithoutLastTwo), h("span", {
role: "presentation",
style: {
'white-space': 'nowrap'
}
}, renderList(lastTwo))));
};
}
[_Symbol$for]() {
// Those are actually used in `renderDropPasteBrowseTagline` method.
this.props.i18nArray('dropPasteBoth');
this.props.i18nArray('dropPasteFiles');
this.props.i18nArray('dropPasteFolders');
this.props.i18nArray('dropPasteImportBoth');
this.props.i18nArray('dropPasteImportFiles');
this.props.i18nArray('dropPasteImportFolders');
}
renderPoweredByUppy() {
const {
i18nArray
} = this.props;
const uppyBranding = h("span", null, h("svg", {
"aria-hidden": "true",
focusable: "false",
className: "uppy-c-icon uppy-Dashboard-poweredByIcon",
width: "11",
height: "11",
viewBox: "0 0 11 11"
}, h("path", {
d: "M7.365 10.5l-.01-4.045h2.612L5.5.806l-4.467 5.65h2.604l.01 4.044h3.718z",
fillRule: "evenodd"
})), h("span", {
className: "uppy-Dashboard-poweredByUppy"
}, "Uppy"));
const linkText = i18nArray('poweredBy', {
uppy: uppyBranding
});
return h("a", {
tabIndex: -1,
href: "https://uppy.io",
rel: "noreferrer noopener",
target: "_blank",
className: "uppy-Dashboard-poweredBy"
}, linkText);
}
render() {
const {
showNativePhotoCameraButton,
showNativeVideoCameraButton,
nativeCameraFacingMode
} = this.props;
return h("div", {
className: "uppy-Dashboard-AddFiles"
}, this.renderHiddenInput(false, ref => {
this.fileInput = ref;
}), this.renderHiddenInput(true, ref => {
this.folderInput = ref;
}), showNativePhotoCameraButton && this.renderHiddenCameraInput('photo', nativeCameraFacingMode, ref => {
this.mobilePhotoFileInput = ref;
}), showNativeVideoCameraButton && this.renderHiddenCameraInput('video', nativeCameraFacingMode, ref => {
this.mobileVideoFileInput = ref;
}), this.renderSourcesList(this.props.acquirers, this.props.disableLocalFiles), h("div", {
className: "uppy-Dashboard-AddFiles-info"
}, this.props.note && h("div", {
className: "uppy-Dashboard-note"
}, this.props.note), this.props.proudlyDisplayPoweredByUppy && this.renderPoweredByUppy(this.props)));
}
}
export default AddFiles;