UNPKG

@limetech/lime-elements

Version:
218 lines (217 loc) • 7.19 kB
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