UNPKG

@digital-blueprint/lunchlottery-app

Version:

[GitHub Repository](https://github.com/digital-blueprint/lunchlottery-app) | [npmjs package](https://www.npmjs.com/package/@digital-blueprint/lunchlottery-app) | [Unpkg CDN](https://unpkg.com/browse/@digital-blueprint/lunchlottery-app/)

128 lines (116 loc) 4.64 kB
import {css, html} from 'lit'; import {ScopedElementsMixin} from '@dbp-toolkit/common'; import {ref, createRef} from 'lit/directives/ref.js'; import {DbpBaseElement} from '../base-element.js'; export class DbpStringElement extends ScopedElementsMixin(DbpBaseElement) { constructor() { super(); this.label = 'A string field'; this.rows = 1; this.placeholder = ''; this.maxLength = null; this.wordCountLimit = null; /** @type {import('lit/directives/ref.js').Ref<HTMLTextAreaElement>} */ this.textareaRef = createRef(); this.inputRef = createRef(); this._userProvidedValidator = null; } static get properties() { return { ...super.properties, rows: {type: Number}, placeholder: {type: String}, maxLength: {type: Number, attribute: 'maxlength'}, wordCountLimit: {type: Number, attribute: 'word-count-limit'}, }; } firstUpdated() { super.firstUpdated(); // Store the user-provided validator if it exists if (this.customValidator) { this._userProvidedValidator = this.customValidator; } const formElement = this.rows > 1 ? this.textareaRef.value : this.inputRef.value; if (this.wordCountLimit && formElement) { formElement.addEventListener('input', (event) => { const words = formElement.value.trim().split(/\s+/); this.customValidator = () => { // First call the user-provided validator if it exists if (this._userProvidedValidator) { const userError = this._userProvidedValidator(this.value); if (userError) { return userError; } } // Then, check word count limit if (words.length > this.wordCountLimit) { return this._i18n.t('render-form.string.word-count-exceeded', { wordLimit: this.wordCountLimit, wordCount: words.length, }); } return null; // No errors }; this.handleErrors(); }); } } static get styles() { return [ ...super.styles, // language=css css` :host([layout-type='inline']) fieldset { display: flex; gap: var(--dbp-enum-label-gap, 1em); align-items: center; } :host([layout-type='inline'][rows]) fieldset { display: flex; gap: var(--dbp-enum-label-gap, 1em); align-items: flex-start; } :host([layout-type='inline']) label { margin-bottom: 0; white-space: nowrap; } textarea { resize: vertical; } `, ]; } renderInput() { // With the textarea tag, it's advised to use `.value` to set the value! // https://lit.dev/docs/templates/expressions/#binding-properties return html` ${this.rows > 1 ? html` <textarea id="${this.formElementId}" ${ref(this.textareaRef)} name="${this.name}" rows="${this.rows}" .value="${this.value}" placeholder="${this.placeholder}" @input="${this.handleInputValue}" maxlength="${this.maxLength}" ?disabled=${this.disabled} ?required=${this.required}></textarea> ` : html` <input type="text" id="${this.formElementId}" ${ref(this.inputRef)} name="${this.name}" .value="${this.value}" placeholder="${this.placeholder}" @input="${this.handleInputValue}" maxlength="${this.maxLength}" ?disabled=${this.disabled} ?required=${this.required} /> `} `; } }