@limetech/lime-elements
Version:
218 lines (217 loc) • 7.19 kB
JavaScript
import { h, Host, } from '@stencil/core';
import { createFileInfo, isTypeAccepted } from '../../util/files';
import { partition } from 'lodash-es';
/**
* This component enables you to seamlessly convert any region of the user interface into
* a file dropzone area, just by wrapping it inside the `limel-file-dropzone`.
*
* The file dropzone can then be used to allow end-users to upload files
* by dragging and dropping them into the specified area, for example to trigger an upload process.
*
* After receiving the files, the component emits a `filesSelected` event. For unsupported
* files (specified with the `accept` prop) a `filesRejected` event will be emitted.
*
* The event detail would be an array of `FileInfo` objects,
* each representing a file dropped into the dropzone.
*
* @exampleComponent limel-example-file-dropzone
* @exampleComponent limel-example-file-dropzone-type-filtering
* @private
*/
export class FileDropzone {
constructor() {
this.renderOnDragLayout = () => {
if (this.disabled || !this.hasFileToDrop) {
return;
}
return (h("div", { class: "has-file-to-drop" }, h("limel-icon", { class: "icon", name: "upload_2" }), h("div", { class: "text-helpertext" }, this.renderText(), this.renderHelperText())));
};
this.renderText = () => {
if (!this.text) {
return;
}
return h("span", { class: "text" }, this.text);
};
this.renderHelperText = () => {
if (!this.helperText) {
return;
}
return h("span", { class: "helper-text" }, this.helperText);
};
this.handleDrop = (event) => {
event.stopPropagation();
event.preventDefault();
this.hasFileToDrop = false;
if (this.disabled) {
return;
}
const files = [...event.dataTransfer.files];
const fileInfos = files.map(createFileInfo);
const [acceptedFileInfos, rejectedFileInfos] = partition(fileInfos, (file) => isTypeAccepted(file, this.accept));
if (acceptedFileInfos.length > 0) {
this.filesSelected.emit(acceptedFileInfos);
}
if (rejectedFileInfos.length > 0) {
this.filesRejected.emit(rejectedFileInfos);
}
};
this.handleDragOver = (event) => {
this.hasFileToDrop = true;
event.preventDefault();
};
this.handleDragLeave = (event) => {
this.hasFileToDrop = false;
event.preventDefault();
};
this.accept = '*';
this.disabled = false;
this.text = undefined;
this.helperText = '';
this.hasFileToDrop = false;
}
render() {
return (h(Host, { onDrop: this.handleDrop, onDragOver: this.handleDragOver, onDragLeave: this.handleDragLeave }, h("slot", null), this.renderOnDragLayout()));
}
static get is() { return "limel-file-dropzone"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["file-dropzone.scss"]
};
}
static get styleUrls() {
return {
"$": ["file-dropzone.css"]
};
}
static get properties() {
return {
"accept": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [{
"name": "see",
"text": "[HTML attribute: accept](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept) for more\ndetails."
}],
"text": "Specifies the types of files that the dropzone will accept. By default, all file types are accepted.\n\nFor media files, formats can be specified using: `audio/*`, `video/*`, `image/*`.\nUnique file type specifiers can also be used, for example: `.jpg`, `.pdf`.\nA comma-separated list of file extensions or MIME types is also acceptable, e.g., `image/png, image/jpeg` or\n`.png, .jpg, .jpeg`."
},
"attribute": "accept",
"reflect": true,
"defaultValue": "'*'"
},
"disabled": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Set to `true` to disable the file dropzone."
},
"attribute": "disabled",
"reflect": false,
"defaultValue": "false"
},
"text": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Is displayed when the user is dragging a file over the dropzone.\nA suitable text could for instance be \"Drop your files here\"."
},
"attribute": "text",
"reflect": false
},
"helperText": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Is displayed to provide supplementary information to the end users,\nfor instance, which filetypes or file sizes are accepted."
},
"attribute": "helper-text",
"reflect": false,
"defaultValue": "''"
}
};
}
static get states() {
return {
"hasFileToDrop": {}
};
}
static get events() {
return [{
"method": "filesSelected",
"name": "filesSelected",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted when files are selected"
},
"complexType": {
"original": "FileInfo[]",
"resolved": "FileInfo[]",
"references": {
"FileInfo": {
"location": "import",
"path": "../../global/shared-types/file.types"
}
}
}
}, {
"method": "filesRejected",
"name": "filesRejected",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [{
"name": "see",
"text": " `accept` for details on how to specify acceptable file types."
}],
"text": "Emitted when files are selected but do not conform with the `accept` property specifications.\nThis can happen when the file types or formats of the selected files are not among the ones allowed by the dropzone,\nas defined by the `accept` property."
},
"complexType": {
"original": "FileInfo[]",
"resolved": "FileInfo[]",
"references": {
"FileInfo": {
"location": "import",
"path": "../../global/shared-types/file.types"
}
}
}
}];
}
}
//# sourceMappingURL=file-dropzone.js.map