UNPKG

tiny-essentials

Version:

Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.

332 lines (291 loc) 10.3 kB
'use strict'; var TinyHtmlTemplate = require('./TinyHtmlTemplate.cjs'); /** * TinyTextarea is a helper class for managing <textarea> elements. * It allows configuring all standard attributes such as rows, cols, placeholder, * autocomplete, spellcheck, and more, with validation. * * @example * const textarea = new TinyHtmlTextarea({ * rows: 5, * placeholder: 'Write here...', * required: true, * maxlength: 200 * }); * * @extends TinyHtmlTemplate<HTMLTextAreaElement> */ class TinyHtmlTextarea extends TinyHtmlTemplate { /** * Creates a new TinyTextarea instance. * @param {Object} config - Configuration object. * @param {string} [config.value=""] - Initial text inside the textarea. * @param {number} [config.rows] - Number of visible text lines. * @param {number} [config.cols] - Number of character columns. * @param {string} [config.placeholder] - Placeholder text. * @param {'none'|'sentences'|'words'|'characters'|'on'|'off'} [config.autocapitalize] - Controls automatic capitalization. * @param {string} [config.autocomplete] - Autocomplete behavior ("on", "off", or token list). * @param {'on'|'off'|boolean} [config.autocorrect] - Autocorrect behavior ("on" or "off"). * @param {boolean} [config.autofocus=false] - Whether the textarea should autofocus on load. * @param {string} [config.dirname] - Directionality of submitted text. * @param {boolean} [config.disabled=false] - Whether the textarea is disabled. * @param {string} [config.form] - The id of the associated form. * @param {number} [config.maxlength] - Maximum length in UTF-16 code units. * @param {number} [config.minlength] - Minimum length in UTF-16 code units. * @param {string} [config.name] - The name of the control. * @param {boolean} [config.readonly=false] - Whether the textarea is read-only. * @param {boolean} [config.required=false] - Whether the textarea is required. * @param {true|false|"true"|"false"|"default"} [config.spellcheck] - Spellcheck behavior. * @param {"hard"|"soft"|"off"} [config.wrap] - Wrapping behavior. * @param {string|string[]|Set<string>} [config.tags=[]] - Initial CSS classes. * @param {string} [config.mainClass=''] - Main CSS class. * @throws {TypeError} If any attribute is of the wrong type. */ constructor({ value = '', rows, cols, placeholder, autocapitalize, autocomplete, autocorrect, autofocus = false, dirname, disabled = false, form, maxlength, minlength, name, readonly = false, required = false, spellcheck, wrap, tags = [], mainClass = '', } = {}) { super(document.createElement('textarea'), tags, mainClass); // value this.value = value; // rows if (rows !== undefined) this.rows = rows; // cols if (cols !== undefined) this.cols = cols; // placeholder if (placeholder !== undefined) this.placeholder = placeholder; // autocapitalize if (autocapitalize !== undefined) this.autocapitalize = autocapitalize; // autocomplete if (autocomplete !== undefined) this.autocomplete = autocomplete; // autocorrect if (autocorrect !== undefined) this.autocorrect = autocorrect; // autofocus this.autofocus = autofocus; // dirname if (dirname !== undefined) this.dirname = dirname; // disabled this.disabled = disabled; // form if (form !== undefined) this.form = form; // maxlength if (maxlength !== undefined) this.maxlength = maxlength; // minlength if (minlength !== undefined) this.minlength = minlength; // name if (name !== undefined) this.name = name; // --- readonly --- this.readonly = readonly; // --- required --- this.required = required; // spellcheck if (spellcheck !== undefined) this.spellcheck = spellcheck; // wrap if (wrap !== undefined) this.wrap = wrap; } /** @param {string} value */ set value(value) { if (typeof value !== 'string') throw new TypeError('TinyTextarea: "value" must be a string.'); this.setVal(value); } /** @returns {string} */ get value() { return this.valTxt(); } /** @param {number} rows */ set rows(rows) { if (!Number.isInteger(rows) || rows < 1) throw new TypeError('TinyTextarea: "rows" must be a positive integer.'); this.setAttr('rows', rows); } /** @returns {number|null} */ get rows() { return this.attrNumber('rows'); } /** @param {number} cols */ set cols(cols) { if (!Number.isInteger(cols) || cols < 1) throw new TypeError('TinyTextarea: "cols" must be a positive integer.'); this.setAttr('cols', cols); } /** @returns {number|null} */ get cols() { return this.attrNumber('cols'); } /** @param {string} placeholder */ set placeholder(placeholder) { if (typeof placeholder !== 'string') throw new TypeError('TinyTextarea: "placeholder" must be a string.'); this.setAttr('placeholder', placeholder); } /** @returns {string|null} */ get placeholder() { return this.attrString('placeholder'); } /** @param {'none'|'sentences'|'words'|'characters'|'on'|'off'} autocapitalize */ set autocapitalize(autocapitalize) { const valid = ['none', 'sentences', 'words', 'characters', 'on', 'off']; if (!valid.includes(autocapitalize)) throw new TypeError(`TinyTextarea: "autocapitalize" must be one of ${valid.join(', ')}.`); this.setAttr('autocapitalize', autocapitalize); } /** @returns {string|null} */ get autocapitalize() { return this.attrString('autocapitalize'); } /** @param {string} autocomplete */ set autocomplete(autocomplete) { if (typeof autocomplete !== 'string') throw new TypeError('TinyTextarea: "autocomplete" must be a string.'); this.setAttr('autocomplete', autocomplete); } /** @returns {string|null} */ get autocomplete() { return this.attrString('autocomplete'); } /** @param {'on'|'off'|boolean} autocorrect */ set autocorrect(autocorrect) { if (typeof autocorrect === 'boolean') { this.setAttr('autocorrect', autocorrect ? 'on' : 'off'); return; } if (!['on', 'off'].includes(autocorrect)) throw new TypeError('TinyTextarea: "autocorrect" must be "on" or "off".'); this.setAttr('autocorrect', autocorrect); } /** @returns {boolean|null} */ get autocorrect() { const autocorrect = this.attrString('autocorrect'); if (autocorrect === 'on') return true; else if (autocorrect === 'off') return false; return null; } /** @param {boolean} autofocus */ set autofocus(autofocus) { if (typeof autofocus !== 'boolean') throw new TypeError('"autofocus" must be a boolean.'); if (autofocus) this.addProp('autofocus'); else this.removeProp('autofocus'); } /** @returns {boolean} */ get autofocus() { return this.hasProp('autofocus'); } /** @param {string} dirname */ set dirname(dirname) { if (typeof dirname !== 'string') throw new TypeError('TinyTextarea: "dirname" must be a string.'); this.setAttr('dirname', dirname); } /** @returns {string|null} */ get dirname() { return this.attrString('dirname'); } /** @param {boolean} disabled */ set disabled(disabled) { if (typeof disabled !== 'boolean') throw new TypeError('"disabled" must be a boolean.'); if (disabled) this.addProp('disabled'); else this.removeProp('disabled'); } /** @returns {boolean} */ get disabled() { return this.hasProp('disabled'); } /** @param {string} form */ set form(form) { if (typeof form !== 'string') throw new TypeError('TinyTextarea: "form" must be a string.'); this.setAttr('form', form); } /** @returns {string|null} */ get form() { return this.attrString('form'); } /** @param {number} maxlength */ set maxlength(maxlength) { if (!Number.isInteger(maxlength) || maxlength < 1) throw new TypeError('TinyTextarea: "maxlength" must be a positive integer.'); this.setAttr('maxlength', maxlength); } /** @returns {number|null} */ get maxlength() { return this.attrNumber('maxlength'); } /** @param {number} minlength */ set minlength(minlength) { if (!Number.isInteger(minlength) || minlength < 0) throw new TypeError('TinyTextarea: "minlength" must be a non-negative integer.'); this.setAttr('minlength', minlength); } /** @returns {number|null} */ get minlength() { return this.attrNumber('minlength'); } /** @param {string} name */ set name(name) { if (typeof name !== 'string') throw new TypeError('TinyTextarea: "name" must be a string.'); this.setAttr('name', name); } /** @returns {string|null} */ get name() { return this.attrString('name'); } /** @param {boolean} readonly */ set readonly(readonly) { if (typeof readonly !== 'boolean') throw new TypeError('"readonly" must be a boolean.'); if (readonly) this.addProp('readonly'); else this.removeProp('readonly'); } /** @returns {boolean} */ get readonly() { return this.hasProp('readonly'); } /** @param {boolean} required */ set required(required) { if (typeof required !== 'boolean') throw new TypeError('"required" must be a boolean.'); if (required) this.addProp('required'); else this.removeProp('required'); } /** @returns {boolean} */ get required() { return this.hasProp('required'); } /** @param {'true'|'false'|boolean|'default'} spellcheck */ set spellcheck(spellcheck) { if (![true, false, 'true', 'false', 'default'].includes(spellcheck)) throw new TypeError('TinyTextarea: "spellcheck" must be "true", "false" or "default".'); this.setAttr('spellcheck', spellcheck); } /** @returns {string|null} */ get spellcheck() { return this.attrString('spellcheck'); } /** @param {'hard'|'soft'|'off'} wrap */ set wrap(wrap) { const valid = ['hard', 'soft', 'off']; if (!valid.includes(wrap)) throw new TypeError(`TinyTextarea: "wrap" must be one of ${valid.join(', ')}.`); this.setAttr('wrap', wrap); } /** @returns {string|null} */ get wrap() { return this.attrString('wrap'); } } module.exports = TinyHtmlTextarea;