UNPKG

@postnord/web-components

Version:

PostNord Web Components

221 lines (214 loc) 15.6 kB
/*! * Built with Stencil * By PostNord. */ import { r as registerInstance, g as getElement, h, a as Host } from './index-5606614b.js'; import { u as uuidv4, k as awaitTopbar, e as en } from './helpers-9dac5241.js'; import { a as alert_exclamation_circle } from './alert_exclamation_circle-7e58e19d.js'; import { c as check } from './check-f615042e.js'; import { c as close } from './close-9e832820.js'; const icon$1 = '<svg class="pn-icon-svg" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M1.81 11.727a1 1 0 0 1 1.363.378c.29.513.835 1.343 1.7 2.174a9.5 9.5 0 0 0 3.457 2.128c1.03.361 2.244.593 3.67.593s2.64-.232 3.67-.593a9.5 9.5 0 0 0 3.458-2.128 9.7 9.7 0 0 0 1.698-2.174 1 1 0 0 1 1.742.984 11.5 11.5 0 0 1-1.445 2.001l1.686 2.322a1 1 0 1 1-1.618 1.175l-1.537-2.116a11.4 11.4 0 0 1-2.453 1.48l.763 2.785a1 1 0 1 1-1.928.528l-.73-2.661c-.993.251-2.093.397-3.306.397s-2.313-.146-3.306-.397l-.73 2.661a1 1 0 1 1-1.928-.528l.763-2.786a11.4 11.4 0 0 1-2.453-1.479L2.81 18.587a1 1 0 0 1-1.618-1.175l1.686-2.322a11.5 11.5 0 0 1-1.445-2 1 1 0 0 1 .379-1.363" clip-rule="evenodd"/></svg>'; const preview_off = icon$1; const icon = '<svg class="pn-icon-svg" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 7c-5.382 0-7.908 3.33-8.758 4.775a.43.43 0 0 0 0 .45C4.092 13.67 6.618 17 12 17s7.908-3.33 8.758-4.775a.43.43 0 0 0 0-.45C19.908 10.33 17.382 7 12 7M1.518 10.761C2.55 9.005 5.618 5 12 5s9.45 4.005 10.482 5.761a2.43 2.43 0 0 1 0 2.478C21.45 14.995 18.382 19 12 19s-9.45-4.005-10.482-5.761a2.43 2.43 0 0 1 0-2.478M8 12a4 4 0 1 1 8 0 4 4 0 0 1-8 0m4-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4" clip-rule="evenodd"/></svg>'; const preview_on = icon; const translations = { SHOW: { sv: 'Visa', en: 'Show', da: 'At vise', fi: 'Näytä', no: 'Vise', }, HIDE: { sv: 'Dölj', en: 'Hide', da: 'Skjule', fi: 'Piilottaa', no: 'Gjemme seg', }, CLEAR: { sv: 'Rensa', en: 'Clear', da: 'Klar', fi: 'Asia selvä', no: 'Klar', }, }; const pnInputCss = "pn-input{display:inline-flex;flex-direction:column}pn-input .pn-input-label{cursor:pointer;display:flex;justify-content:space-between;align-items:flex-end;font-weight:400;color:#2d2013;margin:0 0 0.25em 0;gap:0.5em;-webkit-tap-highlight-color:transparent;transition-property:color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}@media (prefers-reduced-motion: reduce){pn-input .pn-input-label{transition-duration:0s;transition-delay:0s}}pn-input .pn-input-label>span{font-size:0.875em}pn-input .pn-input-group{position:relative}pn-input .pn-input-element{--pn-input-offset-left:0em;--pn-input-offset-right:0em;color:#2d2013;background-color:#ffffff;border:0.0625em solid #969087;border-radius:0.5em;padding:0.75em;font-family:inherit;font-size:1em;font-weight:500;line-height:1.5em;-webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;outline:0.2rem solid transparent;outline-offset:0.2rem;transition-property:outline-color, background-color, border-color, color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1);width:100%;padding-left:calc(var(--pn-input-offset-left) + 0.75em);padding-right:calc(var(--pn-input-offset-right) + 0.75em)}pn-input .pn-input-element:-webkit-autofill,pn-input .pn-input-element:-webkit-autofill:hover,pn-input .pn-input-element:-webkit-autofill:focus,pn-input .pn-input-element:-webkit-autofill:active{-webkit-box-shadow:0 0 0 10em #e0f8ff inset;-webkit-text-fill-color:#2d2013}pn-input .pn-input-element:focus-visible{outline-color:#005d92;background-color:#ffffff;border-color:#005d92}@media (prefers-reduced-motion: reduce){pn-input .pn-input-element{transition-duration:0s;transition-delay:0s}}pn-input .pn-input-element::placeholder{color:#5e554a;font-weight:normal}pn-input .pn-input-element:hover{border-color:#005d92}pn-input .pn-input-element:disabled{color:#5e554a;background-color:#f3f2f2;border-color:#f3f2f2}pn-input .pn-input-element:read-only{border-color:#ffffff}pn-input .pn-input-element:disabled~.pn-input-eyecandy>pn-icon>.pn-icon-svg>path{fill:#969087}pn-input .pn-input-element::-webkit-calendar-picker-indicator{visibility:hidden;display:none}pn-input .pn-input-element::-webkit-textfield-decoration-container,pn-input .pn-input-element::-webkit-search-cancel-button,pn-input .pn-input-element::-webkit-inner-spin-button,pn-input .pn-input-element::-webkit-outer-spin-button,pn-input .pn-input-element::-webkit-search-decoration{-webkit-appearance:none;-moz-appearance:none;appearance:none}pn-input .pn-input-element[type=number]{appearance:textfield}pn-input .pn-input-eyecandy{position:absolute;top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;gap:0.5em;height:1.5em}pn-input .pn-input-eyecandy[data-prefix]{left:0.75em}pn-input .pn-input-eyecandy[data-suffix]{right:0.75em}pn-input .pn-input-text{color:#5e554a;font-weight:400;line-height:1.5em}pn-input .pn-input-message{color:#5e554a;font-size:0.875em;font-weight:400;margin:0.25em 0 0 0;display:flex;flex-direction:column;gap:0.25em}pn-input .pn-input-message[hidden],pn-input .pn-input-message>span[hidden]{display:none}pn-input .pn-input[data-error]>.pn-input-label{color:#a70707}pn-input .pn-input[data-error]>.pn-input-group>.pn-input-element{border-color:#a70707}pn-input .pn-input[data-error]>.pn-input-group>.pn-input-element:hover{border-color:#500715}pn-input .pn-input[data-error]>.pn-input-group>.pn-input-element:focus-visible{background-color:#ffffff;border-color:#a70707;outline-color:#a70707}pn-input .pn-input[data-error]>.pn-input-message[role=alert]{color:#a70707}pn-input .pn-input[data-valid]>.pn-input-label{color:#005e41}pn-input .pn-input[data-valid]>.pn-input-group>.pn-input-element{border-color:#005e41}pn-input .pn-input[data-valid]>.pn-input-group>.pn-input-element:hover{border-color:#002f24}pn-input .pn-input[data-valid]>.pn-input-group>.pn-input-element:focus-visible{background-color:#ffffff;border-color:#005e41;outline-color:#005e41}"; const PnInputStyle0 = pnInputCss; const PnInput = class { constructor(hostRef) { registerInstance(this, hostRef); this.offsetLeft = 0; this.offsetRight = 0; this.showHelperSlot = false; this.showErrorSlot = false; this.showPassword = false; this.label = undefined; this.helpertext = undefined; this.inputid = this.id; this.value = ''; this.language = null; this.icon = undefined; this.textPrefix = undefined; this.textSuffix = undefined; this.type = 'text'; this.name = undefined; this.placeholder = undefined; this.autocomplete = undefined; this.maxlength = undefined; this.inputmode = undefined; this.list = undefined; this.pattern = undefined; this.min = undefined; this.max = undefined; this.step = undefined; this.arialabel = undefined; this.ariacontrols = undefined; this.required = false; this.disabled = false; this.readonly = false; this.valid = false; this.invalid = false; this.error = undefined; } id = `pn-input-${uuidv4()}`; idMessage = `${this.id}-message`; prefix; suffix; mo; get hostElement() { return getElement(this); } togglePassword() { this.showPassword = !this.showPassword; } handleOffset() { requestAnimationFrame(() => requestAnimationFrame(() => { const left = this.prefix?.clientWidth ? this.prefix.clientWidth + 8 : 0; const right = this.suffix?.clientWidth ? this.suffix.clientWidth + 8 : 0; this.offsetLeft = left; this.offsetRight = right; })); } handleMessage() { this.checkSlottedHelper(); this.checkSlottedError(); } async componentWillLoad() { this.handleMessage(); if (this.inputid !== this.id) this.idMessage = `${this.inputid}-message`; if (this.language === null) await awaitTopbar(this.hostElement); } componentDidLoad() { this.handleOffset(); if (this.mo) this.mo.disconnect(); this.mo = new MutationObserver(() => { this.handleOffset(); this.handleMessage(); }); this.mo.observe(this.hostElement, { subtree: true, childList: true, }); } setVal(event) { const target = event.composedPath?.()[0]; this.value = target.value; } clearVal() { const inputClear = new InputEvent('input', { bubbles: true, data: '' }); const input = this.hostElement.querySelector('input'); this.value = ''; input.focus(); input.value = this.value; input.dispatchEvent(inputClear); } translate(prop) { return translations?.[prop]?.[this.language || en]; } hasHelperText() { return this.helpertext?.length > 0 || this.showHelperSlot; } hasErrorMessage() { return this.error?.length > 0 || this.showErrorSlot; } /** If any error is active, either via the prop `invalid` or `error` prop/slot. */ hasError() { return this.hasErrorMessage() || this.invalid || this.showErrorSlot; } /** If any helpertext or error message is active. Checks both props and slots. */ hasMessage() { return this.hasHelperText() || this.hasErrorMessage(); } checkSlottedHelper() { const slottedHelper = this.hostElement.querySelector('[slot=helpertext]')?.textContent; this.showHelperSlot = !!slottedHelper?.length; } checkSlottedError() { const slottedError = this.hostElement.querySelector('[slot=error]')?.textContent; this.showErrorSlot = !!slottedError?.length; } getInputType() { const types = ['text', 'password', 'url', 'tel', 'search', 'number', 'email']; return types.includes(this.type) && !this.showPassword ? this.type : 'text'; } isPassword() { if (this.disabled) return false; return this.type === 'password' || (this.type === 'text' && this.showPassword); } isSearch() { if (this.disabled) return false; return this.type === 'search' && !!this.value?.length; } passwordText() { return this.translate(this.showPassword ? 'HIDE' : 'SHOW'); } /** Check if there is a valid or error state active. Returns false if neither is true. */ stateDisplay() { return this.valid || this.hasError(); } /** * Returns the correct icon for the current state (valid or error). * Defaults to error icon. * @see {@link stateDisplay} */ stateIcon() { if (this.valid) return check; return alert_exclamation_circle; } /** * Returns the correct color for the validation icon. Defaults to red. * @see {@link stateDisplay} */ stateColor() { if (this.valid) return 'green700'; return 'warning'; } showPrefix() { return this.textPrefix && !this.icon; } showSuffix() { return !this.showPrefix() && !!this.textSuffix?.length && !this.isPassword() && this.type !== 'search'; } render() { return (h(Host, { key: '6b2db20d9aa3c3d300814a71022a6fe314fa6d03' }, h("div", { key: '419fa861a5748d0c95e9e69b9defd48f50975683', class: "pn-input", "data-valid": this.valid, "data-error": this.hasError() }, (this.label || this.maxlength >= 1) && (h("label", { key: '06576cf8fe7613382cb7aa64d00ece94556a1304', htmlFor: this.inputid, class: "pn-input-label" }, this.label && h("span", { key: '2c534cf97da3005b773e57ea6623240afea8186d' }, this.label), this.maxlength >= 0 && h("span", { key: 'ab2626d9046b75f372a4e01a7234969017837f2f' }, `${this.value.length}/${this.maxlength}`))), h("div", { key: 'e236d0a4dc4c7c719ea2f4be51cd81def68ca53b', class: "pn-input-group" }, h("input", { key: '8aeb20eaa6fe21732c813bb5f9a8028cc0dcbc76', type: this.getInputType(), id: this.inputid, class: "pn-input-element", name: this.name, placeholder: this.placeholder, autocomplete: this.autocomplete, maxlength: this.maxlength, list: this.list, pattern: this.pattern, min: this.min, max: this.max, step: this.step, value: this.value, inputmode: this.inputmode, disabled: this.disabled, required: this.required, readonly: this.readonly, "aria-label": this.arialabel, "aria-describedby": this.hasMessage() ? this.idMessage : null, "aria-controls": this.ariacontrols, "aria-invalid": this.hasError()?.toString(), style: { '--pn-input-offset-left': `${this.offsetLeft}px`, '--pn-input-offset-right': `${this.offsetRight}px`, }, onInput: e => this.setVal(e) }), h("div", { key: '409947a09fe6960778458060590c47ee204ea534', class: "pn-input-eyecandy", "data-prefix": true, ref: el => (this.prefix = el) }, !!this.icon && h("pn-icon", { key: '0e914746aecea9a37c4f66304e89a82197defd7a', icon: this.icon, "aria-hidden": "true" }), this.showPrefix() && h("span", { key: 'e6a7eb7f10ac9d5cf5de4f2064e3922038dfc9e0', class: "pn-input-text" }, this.textPrefix)), h("div", { key: 'f97005264aca3330f9b7c4eb0489c36f7bd31842', class: "pn-input-eyecandy", "data-suffix": true, ref: el => (this.suffix = el) }, this.showSuffix() && h("span", { key: '769efb326ce6d4058ee4d8d6c5d2f3b781c65c11', class: "pn-input-text" }, this.textSuffix), this.stateDisplay() && h("pn-icon", { key: 'fe18921f222fd14d91edc799da3f50c6d1c7dff8', "aria-hidden": "true", icon: this.stateIcon(), color: this.stateColor() }), this.isPassword() && (h("pn-button", { key: '7e10d1c4502d9abc9fd8156652718e04cdfa9955', icon: this.showPassword ? preview_on : preview_off, iconOnly: true, arialabel: this.passwordText(), small: true, appearance: "light", variant: "borderless", onClick: () => this.togglePassword() })), this.isSearch() && (h("pn-button", { key: '841edb1592c21de8315a0b1c4a8a7c9815c61e01', icon: close, iconOnly: true, arialabel: this.translate('CLEAR'), small: true, appearance: "light", variant: "borderless", onClick: () => this.clearVal() })))), h("p", { key: 'fb41bb4f2559b05cae5b80d214c218429493b5ba', class: "pn-input-message", id: this.idMessage, role: this.hasErrorMessage() ? 'alert' : null, hidden: !this.hasMessage() }, this.hasHelperText() && !this.hasError() && h("span", { key: 'a4b226408274dc3fc6788af3932edd5b05f398f3', class: "pn-input-helper" }, this.helpertext), h("span", { key: '488b39c606ca027df73153a9e6e83b4d59360814', class: "pn-input-helper-slot", hidden: !this.showHelperSlot || this.hasError() }, h("slot", { key: '3cf5c96a8ee99d1d1954a3075862119512ef589c', name: "helpertext" })), this.hasErrorMessage() && h("span", { key: 'b6907bee94961eeb0f4c8c3c59d4f8cc30080754', class: "pn-input-error" }, this.error), h("span", { key: '0193a2c21c1d248f762207351b7bba336368cd6c', class: "pn-input-error-slot", hidden: !this.showErrorSlot }, h("slot", { key: '9e7b771c38bbdd7b3fd75bdc0587c21dcfef2857', name: "error" })))))); } static get watchers() { return { "textPrefix": ["handleOffset"], "textSuffix": ["handleOffset"], "helpertext": ["handleMessage"], "error": ["handleMessage"] }; } }; PnInput.style = PnInputStyle0; export { PnInput as pn_input }; //# sourceMappingURL=pn-input.entry.js.map