UNPKG

@postnord/web-components

Version:

PostNord Web Components

444 lines (443 loc) 17.3 kB
/*! * Built with Stencil * By PostNord. */ import { uuidv4, awaitTopbar, en } from "../../../globals/helpers"; import { h, Host } from "@stencil/core"; import { close_small, search } from "pn-design-assets/pn-assets/icons.js"; import { translations } from "./translations"; export class PnSearchField { id = `pn-search-field-${uuidv4()}`; searchElement; hostElement; /** Provide an aria-label for the search field. */ label; /** Set the value of the search field. */ value = ''; /** Set a search field placeholder. */ placeholder; /** Set a unique ID for the search input */ searchid = this.id; /** Set HTML name of the search input. */ name; /** Allow the browser to autocomplete the search field. */ autocomplete; /** Point to a datalist element with this id. */ list; /** Override the pntopbar language. */ language = null; /** Disable the search field. @category State */ disabled = false; /** Set the search field as required. @category State */ required = false; /** Display loading animation. @category State */ loading = false; /** Button type, options are `none` for no button, `icon` for a labelless button with just a search icon and `icon-inline` for a search button inside of the search field (this last option disables the clear field button). @category Button */ button = ''; /** Label for the button element. @category Button */ buttonLabel; /** Light instead of dark search button. @category Button */ buttonLight = false; /** This is emitted on search submission both with keyboard and mouse. */ search; /** Custom event that handles both clearing and input to have the option of just binding listeners to one event instead of two. */ update; inputHandler() { this.update.emit(this.value); } async componentWillLoad() { if (this.language) return; await awaitTopbar(this.hostElement); } translate(prop) { return translations?.[prop]?.[this.language || en]; } emitSearch({ click, button }) { if (click?.type === 'click' || (button?.type === 'keydown' && button?.key === 'Enter')) { // We prevent the native search event since it's not supported in IE and FF, then we emit our own instead const event = click || button; event.preventDefault(); this.search.emit(this.value); } } setVal(e) { this.value = e.target.value; } clearInput() { this.value = ''; this.update.emit(this.value); this.hostElement.querySelector('input').focus(); } getClassNames() { let classNames = ''; const buttonTypes = ['none', 'icon', 'icon-inline']; if (this.value) classNames += 'searching '; if (this.loading) classNames += 'loading '; if (buttonTypes.includes(this.button)) classNames += `button-${this.button} `; return classNames; } render() { return (h(Host, { key: '832efc417d5cdac506bd633c278850c6632b37f4', class: this.getClassNames() }, h("div", { key: '4216bce9ecec34c4f9d8c638da80b2c44c8615be', class: "input-container" }, h("input", { key: '817f49b544f9ef97d8f281cc6c8bcee65edb231a', type: "search", value: this.value, id: this.searchid, name: this.name, "aria-label": this.label, placeholder: this.placeholder, disabled: this.disabled, required: this.required, autocomplete: this.autocomplete, list: this.list, ref: el => (this.searchElement = el), onKeyDown: e => this.emitSearch({ button: e }), onInput: e => this.setVal(e) }), h("div", { key: '2f5c2f864712551c7928ceb57733837720a1bc2e', class: "button-container" }, (this.button === 'none' || this.button === 'icon-inline') && (h("pn-button", { key: '69f28fbd1dc19c68d2125a8f689ac067e77c68bf', small: true, class: "search", type: "button", appearance: "light", icon: search, iconOnly: true, noTab: this.button !== 'icon-inline', arialabel: this.translate('SEARCH'), onPnClick: e => this.emitSearch({ click: e.detail }) })), this.button !== 'icon-inline' && (h("pn-button", { key: '82f9599ab84356609cce0a03f2c9be24f28d950f', small: true, class: "clear", type: "button", appearance: "light", icon: close_small, iconOnly: true, arialabel: this.translate('CLEAR'), noTab: this.value && (!this.loading || this.button !== 'none'), onPnClick: () => this.clearInput() })), this.button === 'none' || (this.button === 'icon-inline' && h("pn-spinner", { key: '42c3319f161dd199695d2b460311d43abfc31e30' })))), this.button !== 'none' && this.button !== 'icon-inline' && (h("pn-button", { key: '9fc3a87ad30f92688b65762d98787319bba06df0', label: this.buttonLabel, appearance: this.buttonLight ? 'light' : null, icon: search, iconOnly: true, arialabel: this.button === 'icon' ? this.buttonLabel : null, loading: this.loading, onPnClick: e => this.emitSearch({ click: e.detail }) })))); } static get is() { return "pn-search-field"; } static get originalStyleUrls() { return { "$": ["pn-search-field.scss"] }; } static get styleUrls() { return { "$": ["pn-search-field.css"] }; } static get properties() { return { "label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": true, "optional": false, "docs": { "tags": [], "text": "Provide an aria-label for the search field." }, "getter": false, "setter": false, "attribute": "label", "reflect": false }, "value": { "type": "string", "mutable": true, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set the value of the search field." }, "getter": false, "setter": false, "attribute": "value", "reflect": false, "defaultValue": "''" }, "placeholder": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Set a search field placeholder." }, "getter": false, "setter": false, "attribute": "placeholder", "reflect": false }, "searchid": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set a unique ID for the search input" }, "getter": false, "setter": false, "attribute": "searchid", "reflect": false, "defaultValue": "this.id" }, "name": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Set HTML name of the search input." }, "getter": false, "setter": false, "attribute": "name", "reflect": false }, "autocomplete": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Allow the browser to autocomplete the search field." }, "getter": false, "setter": false, "attribute": "autocomplete", "reflect": false }, "list": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Point to a datalist element with this id." }, "getter": false, "setter": false, "attribute": "list", "reflect": false }, "language": { "type": "string", "mutable": false, "complexType": { "original": "PnLanguages", "resolved": "\"\" | \"da\" | \"en\" | \"fi\" | \"no\" | \"sv\"", "references": { "PnLanguages": { "location": "import", "path": "@/globals/types", "id": "src/globals/types.ts::PnLanguages" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Override the pntopbar language." }, "getter": false, "setter": false, "attribute": "language", "reflect": false, "defaultValue": "null" }, "disabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "State" }], "text": "Disable the search field." }, "getter": false, "setter": false, "attribute": "disabled", "reflect": false, "defaultValue": "false" }, "required": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "State" }], "text": "Set the search field as required." }, "getter": false, "setter": false, "attribute": "required", "reflect": false, "defaultValue": "false" }, "loading": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "State" }], "text": "Display loading animation." }, "getter": false, "setter": false, "attribute": "loading", "reflect": false, "defaultValue": "false" }, "button": { "type": "string", "mutable": false, "complexType": { "original": "'' | 'none' | 'icon' | 'icon-inline'", "resolved": "\"\" | \"icon\" | \"icon-inline\" | \"none\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "Button" }], "text": "Button type, options are `none` for no button, `icon` for a labelless button with just a search icon and `icon-inline` for a search button inside of the search field (this last option disables the clear field button)." }, "getter": false, "setter": false, "attribute": "button", "reflect": false, "defaultValue": "''" }, "buttonLabel": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Button" }], "text": "Label for the button element." }, "getter": false, "setter": false, "attribute": "button-label", "reflect": false }, "buttonLight": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "Button" }], "text": "Light instead of dark search button." }, "getter": false, "setter": false, "attribute": "button-light", "reflect": false, "defaultValue": "false" } }; } static get events() { return [{ "method": "search", "name": "search", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "This is emitted on search submission both with keyboard and mouse." }, "complexType": { "original": "string", "resolved": "string", "references": {} } }, { "method": "update", "name": "update", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Custom event that handles both clearing and input to have the option of just binding listeners to one event instead of two." }, "complexType": { "original": "string", "resolved": "string", "references": {} } }]; } static get elementRef() { return "hostElement"; } static get listeners() { return [{ "name": "input", "method": "inputHandler", "target": undefined, "capture": false, "passive": false }]; } } //# sourceMappingURL=pn-search-field.js.map