@cbpds/web-components
Version:
Web components for the CBP Design System.
408 lines (407 loc) • 17.2 kB
JavaScript
/*!
* 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,
name: this.name,
value: this.files,
nativeEvent: e
});
}
async reset() {
this.formField.value = this.initialValue ? this.initialValue : '';
this.files = [];
}
async getData() {
const Data = {
host: this.host,
name: this.name,
files: this.files
};
return Data;
}
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,
name: this.name,
value: this.files,
nativeEvent: e
});
}
componentWillLoad() {
var _a;
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);
const Name = this.formField.getAttribute('name');
Name ? this.name = Name : (this.name ? this.formField.setAttribute('Name', this.name) : null);
if (this.multiple)
this.formField.setAttribute('multiple', '');
if (this.accept)
this.formField.setAttribute('accept', this.accept);
if (this.disabled)
this.formField.setAttribute('disabled', ``);
this.initialValue = (_a = this.formField) === null || _a === void 0 ? void 0 : _a.value;
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: '0945dbf3f6eb972cee225941bd1910f46404582d' }, h("div", { key: 'a938dc6769cff95c468d059161bb2d35dd8795ec', class: "cbp-file-input-wrapper" }, h("div", { key: '1dd01823ed4b0e3c894a5a1ee644f2d9eb8f3003', class: "cbp-file-input-visuals" }, h("cbp-icon", { key: '414d5fff8f25f53ff05bf59c15197c57a2d5f037', name: "file-lines", size: "2rem" }), h("div", { key: '3c7e40d1f2f4b849c5b9d45bfedb3610d528897a', class: "cbp-file-input-text" }, msg), h("cbp-button", { key: '875616422273c1cda4f4d1627802edabbbeef151', fill: "solid", color: "secondary" }, h("button", { key: '4db06ed1a150a86c21b38092adad3ade5bcafb45', slot: "cbp-button-custom", type: "button", tabindex: "-1", "aria-hidden": "true" }, h("cbp-icon", { key: '428e4cc506fedd29edce2b4fde54de518ec88712', name: "upload" }), "Browse"))), h("slot", { key: '474c77f164a5de590d59bfabd3181e4b1097c5fe' })), h("div", { key: '1b1d3631d093c6d1e50a3cd72f21abb14daabe53', 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": true,
"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": true
},
"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 methods() {
return {
"reset": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "A custom method to reset the file input component (for enhanced/multi-file inputs) to its initial state and value \nsince it does not update properly on a native form reset. This method may be called manually, but is automatically \ncalled on form reset when using the `cbp-form` component.",
"tags": []
}
},
"getData": {
"complexType": {
"signature": "() => Promise<{ host: HTMLElement; name: string; files: File[]; }>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
},
"HTMLElement": {
"location": "global",
"id": "global::HTMLElement"
},
"File": {
"location": "global",
"id": "global::File"
}
},
"return": "Promise<{ host: HTMLElement; name: string; files: File[]; }>"
},
"docs": {
"text": "",
"tags": []
}
}
};
}
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