UNPKG

@limetech/lime-elements

Version:
160 lines (159 loc) 5.17 kB
import { h, Host, } from '@stencil/core'; import { createRandomString } from '../../util/random-string'; import { createFileInfo } from '../../util/files'; /** * This component enables you to seamlessly transform any other clickable component that * generates a `click` event into a file input selector. * * To use it, just wrap any clickable component inside the `limel-file-input` component. * Upon reception of the `click` event this component will open the native file selection * dialog. * * After receiving the files, the component emits a `filesSelected` event. * * The event detail would be an array of `FileInfo` objects, * each representing a file dropped into the dropzone. * * @exampleComponent limel-example-file-input * @exampleComponent limel-example-file-input-type-filtering * @private */ export class FileInput { constructor() { this.fileInputId = createRandomString(); this.handleClick = (event) => { if (this.disabled) { event.stopPropagation(); event.preventDefault(); return; } this.triggerFileDialog(); event.stopPropagation(); }; this.handleKeyUp = (event) => { event.stopPropagation(); event.preventDefault(); if (event.code === 'Enter') { this.triggerFileDialog(); } }; this.handleFileChange = (event) => { const files = [...this.fileInput.files]; if (files.length > 0) { event.stopPropagation(); this.filesSelected.emit(files.map(createFileInfo)); this.fileInput.value = ''; } }; this.accept = '*'; this.disabled = false; this.multiple = false; } componentDidLoad() { // eslint-disable-next-line unicorn/prefer-query-selector this.fileInput = this.element.shadowRoot.getElementById(this.fileInputId); } render() { return (h(Host, { onClick: this.handleClick, onKeyUp: this.handleKeyUp, onKeyDown: this.handleKeyDown }, h("input", { hidden: true, id: this.fileInputId, onChange: this.handleFileChange, type: "file", accept: this.accept, disabled: this.disabled, multiple: this.multiple }), h("slot", null))); } handleKeyDown(event) { if (event.code === 'Tab' || event.code === 'Backspace' || event.code === 'Enter') { return; } event.preventDefault(); event.stopPropagation(); } triggerFileDialog() { this.fileInput.click(); } static get is() { return "limel-file-input"; } static get encapsulation() { return "shadow"; } 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 file input selection." }, "attribute": "disabled", "reflect": true, "defaultValue": "false" }, "multiple": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set to `true` to enable selection of multiple files" }, "attribute": "multiple", "reflect": true, "defaultValue": "false" } }; } 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" } } } }]; } static get elementRef() { return "element"; } } //# sourceMappingURL=file-input.js.map