UNPKG

@cbpds/web-components

Version:
346 lines (345 loc) 14.8 kB
/*! * CPB Design System web components - built with Stencil */ import { Host, h } from "@stencil/core"; import { setCSSProps, createNamespaceKey } from "../../utils/utils"; export class CbpFileInput { constructor() { this.name = undefined; this.fieldId = createNamespaceKey('cbp-file-input'); this.multiple = undefined; this.accept = undefined; this.enhanced = undefined; this.status = {}; this.error = false; this.disabled = false; this.context = undefined; this.sx = {}; this.files = []; } handleChange(e) { if (this.enhanced && this.multiple) { let files = this.files; for (let i = 0; i < e.target.files.length; i++) { files = [...files, e.target.files[i]]; } this.files = files; this.formField.value = ''; } else { let files = []; for (let i = 0; i < e.target.files.length; i++) { files = [...files, e.target.files[i]]; } this.files = files; } this.formField.focus(); this.valueChange.emit({ host: this.host, nativeElement: this.formField, value: this.files, nativeEvent: e }); } watchDisabledHandler(newValue) { if (this.formField) { (newValue) ? this.formField.setAttribute('disabled', '') : this.formField.removeAttribute('disabled'); } } watchStatusHandler(newValue) { if (typeof newValue == 'string') { this.status = JSON.parse(newValue) || {}; } } handleDelete(e) { const { detail: { value } } = e; if (this.enhanced) { const filterIndex = value; this.files.splice(filterIndex, 1); this.files = [...this.files]; if (this.status.length > 0) { this.status.splice(filterIndex, 1); this.status = [...this.status]; } } else { this.formField.value = ''; this.files = []; this.status = {}; } this.formField.focus(); this.valueChange.emit({ host: this.host, nativeElement: this.formField, value: this.files, nativeEvent: e }); } componentWillLoad() { if (typeof this.sx == 'string') { this.sx = JSON.parse(this.sx) || {}; } setCSSProps(this.host, Object.assign({}, this.sx)); this.formField = this.host.querySelector('input[type=file]'); if (this.formField) { const Id = this.formField.getAttribute('id'); Id ? this.fieldId = Id : this.formField.setAttribute('id', this.fieldId); if (this.multiple) this.formField.setAttribute('multiple', ''); if (this.accept) this.formField.setAttribute('accept', this.accept); if (this.name) this.formField.setAttribute('name', this.name); if (this.disabled) this.formField.setAttribute('disabled', ``); this.formField.addEventListener('change', (e) => this.handleChange(e)); this.formField.addEventListener('dragenter', () => this.formField.classList.add('cbp-file-input-dragged')); this.formField.addEventListener('dragleave', () => this.formField.classList.remove('cbp-file-input-dragged')); this.formField.addEventListener('drop', () => this.formField.classList.remove('cbp-file-input-dragged')); } } render() { let msg = (this.files.length == 0 || (this.enhanced && this.multiple)) ? `Drag & Drop File${this.multiple ? 's' : ''} Here or Browse ${(this.files.length > 0 && this.enhanced && this.multiple) ? 'to Add More' : ''}` : `Drag & Drop File${this.multiple ? 's' : ''} Here or Browse to Replace`; return (h(Host, { key: 'de03c29905c9c1dc1d491f42aaae46ac31fdb469' }, h("div", { key: '462000cb5c81900123dc4188d0032be95bb01b24', class: "cbp-file-input-wrapper" }, h("div", { key: 'a5f8616b904309fb5b437cfcf2975f47389f00ba', class: "cbp-file-input-visuals" }, h("cbp-icon", { key: '47f7efaa585ac25ad60fcfd9abe44ee9335f977a', name: "file-lines", size: "2rem" }), h("div", { key: '7fc7785445e9df46205f312c9d1d90b16d80152b', class: "cbp-file-input-text" }, msg), h("cbp-button", { key: 'c0c95e14cf252434cec2ef494263909e7ba60db9', fill: "solid", color: "secondary" }, h("button", { key: '69400265faebd04d977dc816c0793ce3f7187996', slot: "cbp-button-custom", type: "button", tabindex: "-1", "aria-hidden": "true" }, h("cbp-icon", { key: 'e47b0fd44d54832ffb38e231ad77be9627ff7e22', name: "upload" }), "Browse"))), h("slot", { key: '3f36a5722efaadf812dbb1daffdd93b5132586ca' })), h("div", { key: '12625e1afdf7503705b84cb4a26e4a3103d23aa7', class: "cbp-file-input-filelist" }, this.files.map(({ name, size }, index) => { var _a, _b; return h("div", { key: `${name}-${size}`, class: this.status.length > 0 ? `cbp-file-input-file-${(_a = this.status[index]) === null || _a === void 0 ? void 0 : _a.status}` : '' }, h("div", null, h("div", { id: `${this.fieldId}-file-${index}` }, name), this.status.length > 0 && h("div", null, h("hr", null), h("div", null, (_b = this.status[index]) === null || _b === void 0 ? void 0 : _b.message))), h("cbp-button", { fill: "ghost", color: "secondary", value: `${index}`, accessibilityText: (this.files.length > 0 && this.multiple && !this.enhanced) ? 'Remove Files' : `Remove ${name}` }, h("cbp-icon", { name: "times" }))); })))); } static get is() { return "cbp-file-input"; } static get originalStyleUrls() { return { "$": ["cbp-file-input.scss"] }; } static get styleUrls() { return { "$": ["cbp-file-input.css"] }; } static get properties() { return { "name": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "The `name` attribute of the input, which is passed as part of formData (as a key)." }, "attribute": "name", "reflect": false }, "fieldId": { "type": "string", "mutable": true, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Optionally specify the ID of the input here, which is used to generate related pattern \nnode IDs and associate everything for accessibility." }, "attribute": "field-id", "reflect": false, "defaultValue": "createNamespaceKey('cbp-file-input')" }, "multiple": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Specifies whether the file input accepts multiple files rather than a single file (may also be set directly on the slotted input)." }, "attribute": "multiple", "reflect": false }, "accept": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Specifies the files types accepted by the file input (may also be set directly on the slotted input). \nThis property is merely a suggestion to the browser and any file type restrictions should still be \nenforced in form validation." }, "attribute": "accept", "reflect": false }, "enhanced": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Experimental: Specifies whether the functionality is enhanced over the native web platform file input. \nThis functionality requires integration with a framework or manual handling of the custom events\nand will not work with a native form post." }, "attribute": "enhanced", "reflect": false }, "status": { "type": "any", "mutable": false, "complexType": { "original": "any", "resolved": "any", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Supports passing back status and error messages as an array of objects or stringified JSON \nfrom the application. The array shall be the same length as the current file list.\nE.g., [ {\"status\": \"error|success|undefined\", \"message\": \"string\"}, ... ]\nOne could take the valueChange event's detail.value key, which contains an array of File objects, \nand add these keys to it before feeding it back to this component via the `status` property." }, "attribute": "status", "reflect": false, "defaultValue": "{}" }, "error": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Specifies that the field has an error (and sets aria-invalid accordingly). Primarily controlled by the \nparent `cbp-form-field` component." }, "attribute": "error", "reflect": true, "defaultValue": "false" }, "disabled": { "type": "boolean", "mutable": true, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Specifies that the field is disabled. Primarily controlled by the parent `cbp-form-field` component." }, "attribute": "disabled", "reflect": true, "defaultValue": "false" }, "context": { "type": "string", "mutable": false, "complexType": { "original": "'light-inverts' | 'light-always' | 'dark-inverts' | 'dark-always'", "resolved": "\"dark-always\" | \"dark-inverts\" | \"light-always\" | \"light-inverts\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Specifies the context of the component as it applies to the visual design and whether \nit inverts when light/dark mode is toggled. \nDefault behavior is \"light-inverts\" and does not have to be specified." }, "attribute": "context", "reflect": true }, "sx": { "type": "any", "mutable": false, "complexType": { "original": "any", "resolved": "any", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Supports adding inline styles as an object" }, "attribute": "sx", "reflect": false, "defaultValue": "{}" } }; } static get states() { return { "files": {} }; } static get events() { return [{ "method": "valueChange", "name": "valueChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "A custom event emitted when the click event occurs for either a rendered button or anchor/link." }, "complexType": { "original": "any", "resolved": "any", "references": {} } }]; } static get elementRef() { return "host"; } static get watchers() { return [{ "propName": "disabled", "methodName": "watchDisabledHandler" }, { "propName": "status", "methodName": "watchStatusHandler" }]; } static get listeners() { return [{ "name": "buttonClick", "method": "handleDelete", "target": undefined, "capture": false, "passive": false }]; } } //# sourceMappingURL=cbp-file-input.js.map