/*!
 * Custom elements for Nanopore-Digital Web applications
 */
import { Host, } from "@stencil/core";
import { h } from "../../utils/renderer";
let fileInputIds = 0;
let getDataTransfer = () => new DataTransfer();
try {
    getDataTransfer();
}
catch {
    try {
        getDataTransfer = () => new ClipboardEvent('').clipboardData;
        getDataTransfer();
    }
    catch {
        getDataTransfer = null;
    }
}
/**
 * Enables the selection of files for upload.
 *
 * @version 1.0.0
 * @status stable
 *
 * @slot label - A label for the file input. If not provided, the `label` prop will be used.
 * @slot helper - A helper text to display below the input.
 * @slot - The default slot can be used to add additional content, such as instructions or a message.
 */
export class FileUpload {
    inputEl;
    publicInputEl;
    mo;
    fileInputId = `nano-file-upload-${fileInputIds++}`;
    canChangeFileList = !!getDataTransfer;
    removeFiles = [];
    hasHelperSlot;
    hasLabelSlot;
    errorMessage = '';
    isDragging = false;
    fileList = [];
    fileListChange() {
        if (this.canChangeFileList) {
            this.publicInputEl.value = '';
            this.inputEl.files = this.arrToFileList(this.fileList.map((file) => file.file));
            setTimeout(() => {
                this.nanoChange.emit({ value: this.value, files: this.files });
            }, 20);
        }
    }
    hasFocus;
    host;
    // public props
    /** Name of the form control. Submitted with the form as part of a name/value pair. */
    name;
    /** The accept attribute value is a string that defines the file types the file input should accept.
     * E.g. for a MS Word file: `.doc, .docx,application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document` */
    accept;
    /** Specifies which camera to use for capture of image or video data. `user` for the user-facing camera and/or microphone.
     * `environment` specifies the the outward-facing camera and/or microphone. If the requested facing mode isn't available,
     * the user agent may fall back to its preferred default mode. */
    capture;
    /** The maximum file size allowed per file (Megabytes) */
    maxFileSize = 1;
    /** The maximum number of files that can be selected. Defaults to 1 */
    maxFiles = 1;
    _label = '';
    /** String to place within a label element. */
    get label() {
        return this.required && !this._label.endsWith('*')
            ? this._label + ' *'
            : this._label;
    }
    set label(value) {
        this._label = value;
    }
    /** Placeholder only used within single file uploads. */
    placeholder = 'Choose a file';
    /** Visually hide the label - but make it accessible. */
    hideLabel = false;
    /** If `true`, the user must select a file to upload before submitting a form. */
    required = false;
    /** If `true`, the user cannot interact with the select. */
    disabled = false;
    /** If `true`, a clear icon will appear in the input when there is a value.
     * Clicking it clears the input. Only used within single file uploads. */
    clearable = false;
    /** Whether to show validation errors underneath input */
    showInlineError = true;
    /** When should the field perform validation */
    validateOn = 'submitThenDirty';
    /** The form element to associate with this input (its form owner). Must be the id of a form. */
    form;
    shouldValidate() {
        if (!this.inputEl)
            return;
        this.validate();
        requestAnimationFrame(() => {
            if (this.validateOn === 'dirty')
                this.showInlineValidation();
        });
    }
    _invalid = null;
    /** This will be true when the control is in an invalid state.
     * Validity is determined by the `required` prop. Or if custom validity message is set. @readonly */
    get invalid() {
        return this._invalid;
    }
    /**
     * Current validation message - if any. @readonly
     */
    get validityMessage() {
        if (!this.inputEl)
            return '';
        return this.inputEl.validationMessage;
    }
    /** A File array that lists every selected file.
     * Has an added `objectURL` property returning a `DOMString`
     * containing an object URL that can be used to reference the contents of the specified source
     * This list has no more than one member unless the multiple attribute is specified */
    get files() {
        return this.inputEl
            ? Array.from(this.inputEl.files).map((file) => {
                file.objectURL = URL.createObjectURL(file);
                return file;
            })
            : [];
    }
    set files(fs) {
        this.addNewFiles(this.arrToFileList(fs));
    }
    /** A file input's value attribute contains a DOMString that represents the path to the selected file(s).
     * If the user selected multiple files, the value represents the first file in the list of files they selected.
     * You can reset the file-upload control by setting the value to an empty string e.g. `var input.value = ''` */
    get value() {
        return this.inputEl ? this.inputEl.value : '';
    }
    set value(val) {
        if (val === '' && this.inputEl) {
            this.fileList = [];
            this.inputEl.value = '';
        }
    }
    // Events
    /** Emitted when the value has changed. */
    nanoChange;
    /** Emited when the checkbox is focused */
    nanoFocus;
    /** Emited when the checkbox is blurred */
    nanoBlur;
    /** Called when validation is performed (which depends on `validateOn`).
     * @returns event.detail: `{ isValid: boolean, errorMessage: string, originalEvent: Event }`. */
    nanoValidate;
    // Public methods
    /** Get the current state of the control.
     * @param validateFirst - perform validation first before reporting
     * @returns `{ isValid: boolean, errorMessage: string }` */
    async reportValidity(validateFirst) {
        if (validateFirst) {
            this.validate();
            this.showInlineValidation();
        }
        return {
            isValid: !this.invalid,
            errorMessage: this.inputEl.validationMessage,
        };
    }
    /** Sets focus on the specified `nano-input`. Use this method instead of the global
     * `input.focus()`. */
    async setFocus() {
        if (this.inputEl)
            this.inputEl.focus();
    }
    /** @returns the native `<input>` element used under the hood */
    getInputElement() {
        return Promise.resolve(this.inputEl);
    }
    /** Invalidate the field and show a custom error message. To clear the error you will need to re-call this method with an empty string.
     * @param message */
    async showError(message) {
        if (this.inputEl) {
            this.inputEl.setCustomValidity(message);
            this.showInlineValidation();
        }
    }
    // Listeners
    globalClickHandler(e) {
        if (!this.hasFocus)
            return;
        if (e.composedPath().every((node) => node !== this.host))
            this.onBlur();
    }
    globalKeydownHandler(e) {
        if (!this.hasFocus || e.key !== 'Tab')
            return;
        if (e.target !== this.inputEl)
            this.onBlur();
    }
    onReset(e) {
        const form = this.form
            ? document.querySelector('#' + this.form)
            : this.host.closest('form');
        if (!form || e.target !== this.host.closest('form'))
            return;
        this.value = '';
    }
    // Private methods
    onClearClick = () => {
        this.value = '';
    };
    onBlur = () => {
        this.hasFocus = false;
        this.validate();
        if (this.validateOn === 'dirty')
            this.showInlineValidation();
        this.nanoBlur.emit();
    };
    onFocus = () => {
        this.hasFocus = true;
        this.nanoFocus.emit();
    };
    arrToFileList(files) {
        const fileList = getDataTransfer();
        for (let i = 0, len = files.length; i < len; i++)
            fileList.items.add(files[i]);
        return fileList.files;
    }
    checkFileSize(size) {
        return size / 1000000 <= this.maxFileSize;
    }
    checkFileType(type) {
        if (!this.accept)
            return true;
        return (!!type && this.accept.match(type) && this.accept.match(type).length > 0);
    }
    validate = () => {
        this.errorMessage = '';
        this.inputEl.setCustomValidity('');
        let error;
        if (!this.inputEl.validity.valid) {
            error = this.inputEl.validationMessage;
        }
        else {
            if (this.fileList.length > this.maxFiles) {
                error = `Maximum number of files exceeded (${this.maxFiles})`;
            }
            else {
                this.fileList.forEach((fileItem) => {
                    let listeItemError = null;
                    if (!this.checkFileSize(fileItem.file.size)) {
                        listeItemError =
                            'Maximum file size exceeded. Max file size is ' +
                                this.maxFileSize +
                                'Mb';
                    }
                    else if (!this.checkFileType(fileItem.file.type)) {
                        listeItemError = `File type is not allowed (${this.accept})`;
                    }
                    fileItem.validationMessage = listeItemError;
                    fileItem.valid = !listeItemError;
                    if (listeItemError) {
                        error = listeItemError;
                    }
                });
            }
        }
        if (error) {
            this.inputEl.setCustomValidity(error);
        }
        else {
            this.inputEl.setCustomValidity('');
            this.errorMessage = '';
        }
    };
    showInlineValidation(ev) {
        if (this.validateOn === 'submitThenDirty')
            this.validateOn = 'dirty';
        this._invalid = false;
        this.errorMessage = '';
        if (!this.inputEl.validity.valid) {
            this.errorMessage = this.inputEl.validationMessage;
            this._invalid = true;
        }
        this.nanoValidate.emit({
            isValid: !this._invalid,
            errorMessage: this.inputEl.validationMessage,
            originalEvent: ev,
        });
    }
    slotChangeObserver() {
        if (this.mo)
            this.mo.disconnect();
        const mo = (this.mo = new MutationObserver(() => this.processSlottedContent()));
        mo.observe(this.host, { childList: true, subtree: true });
    }
    processSlottedContent() {
        // see if we have slot content
        this.hasLabelSlot = !!this.host.querySelectorAll('[slot="label"]');
        this.hasHelperSlot = !!this.host.querySelector('[slot="helper"]');
    }
    addNewFiles(files) {
        const fileList = Array.from(files).map((file) => {
            return {
                file: file,
                location: URL.createObjectURL(file),
                valid: true,
                validationMessage: null,
            };
        });
        // if we have a list and we're in a browser that can amend files
        // append files to the list, otherwise replace
        if (this.canChangeFileList && this.maxFiles > 1) {
            const newFiles = fileList.filter((findFile) => !this.fileList.find((file) => file.file.name === findFile.file.name));
            this.fileList = [...this.fileList, ...newFiles];
        }
        else
            this.fileList = fileList;
    }
    // event handlers & hooks
    onInvalid = (ev) => {
        if (this.showInlineError)
            ev.preventDefault();
        this.validate();
        this.showInlineValidation(ev);
    };
    onFileChoose = (e) => {
        const files = e.target.files;
        if (files && files.length)
            this.addNewFiles(e.target.files);
    };
    onFileRemoveFileClick = (e, file) => {
        if (!this.canChangeFileList)
            return;
        this.removeFiles.push(file);
        e.target
            .closest('.file-upload__list-item--active')
            .classList.remove('file-upload__list-item--active');
    };
    onFileRemoveAnim = () => {
        if (!this.canChangeFileList || !this.removeFiles.length)
            return;
        this.fileList = this.fileList.filter((fileItem) => !this.removeFiles.find((rmFile) => rmFile === fileItem));
        try {
            this.removeFiles.forEach((f) => f.location ? URL.revokeObjectURL(f.location) : '');
        }
        catch (e) {
            console.error(e);
        }
        this.removeFiles = [];
    };
    onInputChange = () => {
        this.nanoChange.emit({ value: this.value, files: this.files });
    };
    onDragStop = (e) => {
        e.preventDefault();
        e.stopPropagation();
        this.isDragging = false;
    };
    onDragStart = (e) => {
        e.preventDefault();
        e.stopPropagation();
        this.isDragging = true;
    };
    onDrop = (e) => {
        this.onDragStop(e);
        if (e.dataTransfer.files && e.dataTransfer.files.length)
            this.addNewFiles(e.dataTransfer.files);
    };
    // Component lifecycle
    disconnectedCallback() {
        if (this.mo)
            this.mo.disconnect();
    }
    componentDidLoad() {
        this.slotChangeObserver();
    }
    componentWillLoad() {
        this.processSlottedContent();
    }
    FileUploadInput = (eleType, listId) => {
        const labelId = this.fileInputId + '-lbl';
        const moreId = this.showInlineError || this.hasHelperSlot
            ? this.fileInputId + '-more'
            : '';
        return [
            h("div", { class: 'file-upload__' + eleType + '-wrap' }, h("label", { class: `file-upload__` + eleType, htmlFor: this.fileInputId, id: labelId, onDrop: (e) => {
                    this.onDrop(e);
                    this.onDragStop(e);
                }, onDragEnd: this.onDragStop, onDragLeave: this.onDragStop, onDragEnter: this.onDragStart, onDragOver: this.onDragStart }, (!!this.label || (this.hasLabelSlot && eleType !== 'drop')) && (h("div", { class: `file-upload__label ${this.hideLabel ? 'visually-hide' : ''}` }, !!this.label && !!this.label.length ? this.label : '', !this.label && this.hasLabelSlot && eleType !== 'drop' && (h("slot", { name: "label" })))), eleType === 'drop' && (h("div", { class: "file-upload__drop-area" }, h("div", null, this.hasLabelSlot && h("slot", { name: "label" })), h("div", null, "Drag and drop or\u00A0", h("span", null, "browse")))), eleType === 'btn' && (h("div", { class: `file-upload__button button--keyline button--icon-start ${this.hasFocus ? 'button--focus' : ''}` }, h("nano-cta", { secondary: true, class: `file-upload__btn-content` }, h("div", { class: "button", disabled: this.disabled }, this.fileList.length
                ? this.fileList[0].file.name
                : this.placeholder)), !!this.value && this.clearable && !this.disabled && (h("button", { type: "button", class: "icon file-upload__clear-btn", tabindex: "0", "aria-label": "Clear selected file", onClick: this.onClearClick }, h("nano-icon", { name: "light/xmark" }))), !this.disabled &&
                this.showInlineError &&
                (this._invalid ? (h("nano-icon", { name: "solid/circle-xmark", class: "file-upload__icon file-upload__icon-error" })) : (h("nano-icon", { name: "solid/circle-check", class: "file-upload__icon file-upload__icon-success" }))))), h("input", { "aria-labelledby": labelId + ' ' + moreId + ' ' + listId, type: "file", id: this.fileInputId, accept: this.accept, class: "file-upload__input", multiple: this.maxFiles > 1, disabled: this.disabled, name: this.canChangeFileList ? undefined : this.name, form: this.form, ref: (input) => {
                    if (this.canChangeFileList) {
                        this.publicInputEl = input;
                        return;
                    }
                    this.inputEl = input;
                }, onChange: this.onFileChoose, onFocus: this.onFocus, onReset: this.onInputChange })), h("input", { name: !this.canChangeFileList ? undefined : this.name, form: this.form, ref: (input) => {
                    if (!this.canChangeFileList)
                        return;
                    this.inputEl = input;
                }, type: "file", id: this.fileInputId + '-hidden', tabIndex: -1, multiple: true, class: "file-upload__input", disabled: this.disabled, required: this.required, accept: this.accept, onInvalid: this.onInvalid, onChange: this.onInputChange })),
            this.showInlineError || this.hasHelperSlot ? (h("div", { class: "file-upload__more", id: moreId }, this.showInlineError && !!this.errorMessage.length ? (h("div", { class: "file-upload__error" }, this.errorMessage)) : (''), h("div", { class: "file-upload__help" }, h("slot", { name: "helper" })))) : (''),
        ];
    };
    button = () => {
        return this.FileUploadInput('btn');
    };
    dropArea = () => {
        const listId = this.fileInputId + '-list';
        return [
            this.FileUploadInput('drop', listId),
            h("output", { class: "file-upload__list-wrap", id: listId }, !!this.fileList && this.fileList.length > 0 && (h("ul", { class: "file-upload__list list" }, this.fileList.map((file) => {
                return (h("li", { key: file.file.name, class: "file-upload__list-item file-upload__list-item--active list-item", onAnimationEnd: (_) => this.onFileRemoveAnim() }, h("span", { class: "list-title" }, file.file.name), !file.valid && (h("nano-tooltip", { content: file.validationMessage, placement: "left" }, h("nano-icon-button", { class: "list-button list-error", iconName: "light/triangle-exclamation", label: "File error" }))), this.canChangeFileList && (h("nano-icon-button", { class: "list-button list-button--view", type: "button", iconName: "light/eye", label: "View file", target: "_blank", href: file.location })), this.canChangeFileList && (h("nano-icon-button", { onClick: (e) => this.onFileRemoveFileClick(e, file), class: "list-button list-button--remove", iconName: "light/xmark", label: "Remove file" }))));
            })))),
        ];
    };
    render() {
        return (h(Host, { key: 'c6fc291c7ac3c990d5304a2589c7dd1a0193333e', class: "nano-file-upload" }, h("div", { key: '12fd1e6551fe6ff6e1eb6a84000a21e526c61c36', class: {
                'file-upload': true,
                'file-upload--dragging': this.isDragging,
                'file-upload--focus': this.hasFocus,
                'file-upload--invalid': this._invalid === true,
                'file-upload--valid': this._invalid === false,
            } }, this.maxFiles > 1 ? h(this.dropArea, null) : h(this.button, null))));
    }
    static get is() { return "nano-file-upload"; }
    static get encapsulation() { return "scoped"; }
    static get originalStyleUrls() {
        return {
            "$": ["file-upload.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["file-upload.css"]
        };
    }
    static get properties() {
        return {
            "name": {
                "type": "string",
                "attribute": "name",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Name of the form control. Submitted with the form as part of a name/value pair."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "accept": {
                "type": "string",
                "attribute": "accept",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The accept attribute value is a string that defines the file types the file input should accept.\nE.g. for a MS Word file: `.doc, .docx,application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document`"
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "capture": {
                "type": "string",
                "attribute": "capture",
                "mutable": false,
                "complexType": {
                    "original": "'user' | 'environment'",
                    "resolved": "\"environment\" | \"user\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Specifies which camera to use for capture of image or video data. `user` for the user-facing camera and/or microphone.\n`environment` specifies the the outward-facing camera and/or microphone. If the requested facing mode isn't available,\nthe user agent may fall back to its preferred default mode."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "maxFileSize": {
                "type": "number",
                "attribute": "max-file-size",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The maximum file size allowed per file (Megabytes)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "1"
            },
            "maxFiles": {
                "type": "number",
                "attribute": "max-files",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The maximum number of files that can be selected. Defaults to 1"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "1"
            },
            "label": {
                "type": "string",
                "attribute": "label",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "String to place within a label element."
                },
                "getter": true,
                "setter": true,
                "reflect": false
            },
            "placeholder": {
                "type": "string",
                "attribute": "placeholder",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Placeholder only used within single file uploads."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'Choose a file'"
            },
            "hideLabel": {
                "type": "boolean",
                "attribute": "hide-label",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Visually hide the label - but make it accessible."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "required": {
                "type": "boolean",
                "attribute": "required",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the user must select a file to upload before submitting a form."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "disabled": {
                "type": "boolean",
                "attribute": "disabled",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the user cannot interact with the select."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "defaultValue": "false"
            },
            "clearable": {
                "type": "boolean",
                "attribute": "clearable",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, a clear icon will appear in the input when there is a value.\nClicking it clears the input. Only used within single file uploads."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "showInlineError": {
                "type": "boolean",
                "attribute": "show-inline-error",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Whether to show validation errors underneath input"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "defaultValue": "true"
            },
            "validateOn": {
                "type": "string",
                "attribute": "validate-on",
                "mutable": true,
                "complexType": {
                    "original": "'dirty' | 'submit' | 'submitThenDirty'",
                    "resolved": "\"dirty\" | \"submit\" | \"submitThenDirty\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "When should the field perform validation"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "'submitThenDirty'"
            },
            "form": {
                "type": "string",
                "attribute": "form",
                "mutable": false,
                "complexType": {
                    "original": "string | null",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The form element to associate with this input (its form owner). Must be the id of a form."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "invalid": {
                "type": "any",
                "attribute": "invalid",
                "mutable": false,
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "readonly",
                            "text": undefined
                        }],
                    "text": "This will be true when the control is in an invalid state.\nValidity is determined by the `required` prop. Or if custom validity message is set."
                },
                "getter": true,
                "setter": false,
                "reflect": true,
                "defaultValue": "null"
            },
            "validityMessage": {
                "type": "string",
                "attribute": "validity-message",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "readonly",
                            "text": undefined
                        }],
                    "text": "Current validation message - if any."
                },
                "getter": true,
                "setter": false,
                "reflect": false
            },
            "files": {
                "type": "unknown",
                "attribute": "files",
                "mutable": false,
                "complexType": {
                    "original": "FileWithUrl[]",
                    "resolved": "FileWithUrl[]",
                    "references": {
                        "FileWithUrl": {
                            "location": "import",
                            "path": "./file-upload-interface",
                            "id": "src/components/file-upload/file-upload-interface.d.ts::FileWithUrl"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A File array that lists every selected file.\nHas an added `objectURL` property returning a `DOMString`\ncontaining an object URL that can be used to reference the contents of the specified source\nThis list has no more than one member unless the multiple attribute is specified"
                },
                "getter": true,
                "setter": true
            },
            "value": {
                "type": "string",
                "attribute": "value",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A file input's value attribute contains a DOMString that represents the path to the selected file(s).\nIf the user selected multiple files, the value represents the first file in the list of files they selected.\nYou can reset the file-upload control by setting the value to an empty string e.g. `var input.value = ''`"
                },
                "getter": true,
                "setter": true,
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "hasHelperSlot": {},
            "hasLabelSlot": {},
            "errorMessage": {},
            "isDragging": {},
            "fileList": {},
            "hasFocus": {},
            "_invalid": {}
        };
    }
    static get events() {
        return [{
                "method": "nanoChange",
                "name": "nanoChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the value has changed."
                },
                "complexType": {
                    "original": "FileInputChangeEventDetail",
                    "resolved": "FileInputChangeEventDetail",
                    "references": {
                        "FileInputChangeEventDetail": {
                            "location": "import",
                            "path": "./file-upload-interface",
                            "id": "src/components/file-upload/file-upload-interface.d.ts::FileInputChangeEventDetail"
                        }
                    }
                }
            }, {
                "method": "nanoFocus",
                "name": "nanoFocus",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emited when the checkbox is focused"
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }, {
                "method": "nanoBlur",
                "name": "nanoBlur",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emited when the checkbox is blurred"
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }, {
                "method": "nanoValidate",
                "name": "nanoValidate",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "returns",
                            "text": "event.detail: `{ isValid: boolean, errorMessage: string, originalEvent: Event }`."
                        }],
                    "text": "Called when validation is performed (which depends on `validateOn`)."
                },
                "complexType": {
                    "original": "ControlValidityEventDetail",
                    "resolved": "ControlValidityEventDetail",
                    "references": {
                        "ControlValidityEventDetail": {
                            "location": "import",
                            "path": "../../types/shared",
                            "id": "src/types/shared.ts::ControlValidityEventDetail"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "reportValidity": {
                "complexType": {
                    "signature": "(validateFirst: boolean) => Promise<ControlValidity>",
                    "parameters": [{
                            "name": "validateFirst",
                            "type": "boolean",
                            "docs": "- perform validation first before reporting"
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "ControlValidity": {
                            "location": "import",
                            "path": "../../types/shared",
                            "id": "src/types/shared.ts::ControlValidity"
                        }
                    },
                    "return": "Promise<ControlValidity>"
                },
                "docs": {
                    "text": "Get the current state of the control.",
                    "tags": [{
                            "name": "param",
                            "text": "validateFirst - perform validation first before reporting"
                        }, {
                            "name": "returns",
                            "text": "`{ isValid: boolean, errorMessage: string }`"
                        }]
                }
            },
            "setFocus": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Sets focus on the specified `nano-input`. Use this method instead of the global\n`input.focus()`.",
                    "tags": []
                }
            },
            "getInputElement": {
                "complexType": {
                    "signature": "() => Promise<HTMLInputElement | HTMLTextAreaElement>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "HTMLTextAreaElement": {
                            "location": "global",
                            "id": "global::HTMLTextAreaElement"
                        },
                        "HTMLInputElement": {
                            "location": "global",
                            "id": "global::HTMLInputElement"
                        }
                    },
                    "return": "Promise<HTMLTextAreaElement | HTMLInputElement>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "returns",
                            "text": "the native `<input>` element used under the hood"
                        }]
                }
            },
            "showError": {
                "complexType": {
                    "signature": "(message: string) => Promise<void>",
                    "parameters": [{
                            "name": "message",
                            "type": "string",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Invalidate the field and show a custom error message. To clear the error you will need to re-call this method with an empty string.",
                    "tags": [{
                            "name": "param",
                            "text": "message"
                        }]
                }
            }
        };
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "fileList",
                "methodName": "fileListChange"
            }, {
                "propName": "maxFiles",
                "methodName": "shouldValidate"
            }, {
                "propName": "maxFileSize",
                "methodName": "shouldValidate"
            }, {
                "propName": "capture",
                "methodName": "shouldValidate"
            }, {
                "propName": "accept",
                "methodName": "shouldValidate"
            }, {
                "propName": "required",
                "methodName": "shouldValidate"
            }, {
                "propName": "disabled",
                "methodName": "shouldValidate"
            }, {
                "propName": "fileList",
                "methodName": "shouldValidate"
            }];
    }
    static get listeners() {
        return [{
                "name": "click",
                "method": "globalClickHandler",
                "target": "window",
                "capture": false,
                "passive": false
            }, {
                "name": "keydown",
                "method": "globalKeydownHandler",
                "target": "window",
                "capture": false,
                "passive": false
            }, {
                "name": "reset",
                "method": "onReset",
                "target": "body",
                "capture": false,
                "passive": false
            }];
    }
}
