@limetech/lime-elements
Version:
160 lines (159 loc) • 5.17 kB
JavaScript
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