semantic-forms 5.1.5 → 5.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-forms.min.mjs","mappings":"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","sources":["webpack://semantic-forms/./semanticForms.js","webpack://semantic-forms/webpack/bootstrap","webpack://semantic-forms/webpack/startup"],"sourcesContent":["const semanticForms = () => {\n // do some feature detection so none of the JS executes if the browser is too old\n if (typeof document.getElementsByClassName !== 'function' || typeof document.querySelector !== 'function' || !document.body.classList || !window.MutationObserver) {\n console.warn('semantic-forms was loaded into an unsupported browser and will not execute.')\n return\n }\n\n const passwordShow = '<svg fill=\"none\" height=\"256\" viewBox=\"0 0 24 24\" width=\"256\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m1 12s4-8 11-8 11 8 11 8\"/><path d=\"m1 12s4 8 11 8 11-8 11-8\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></g></svg>'\n const passwordHide = '<svg fill=\"none\" height=\"256\" viewBox=\"0 0 24 24\" width=\"256\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m2 2 20 20\"/><path d=\"m6.71277 6.7226c-3.04798 2.07267-4.71277 5.2774-4.71277 5.2774s3.63636 7 10 7c2.0503 0 3.8174-.7266 5.2711-1.7116m-6.2711-12.23018c.3254-.03809.6588-.05822 1-.05822 6.3636 0 10 7 10 7s-.6918 1.3317-2 2.8335\"/><path d=\"m14 14.2362c-.5308.475-1.2316.7639-2 .7639-1.6569 0-3-1.3431-3-3 0-.8237.33193-1.5698.86932-2.11192\"/></g></svg>'\n const helpTextIcon = '<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" style=\"overflow:visible;margin-top:1px;\"><rect width=\"16\" height=\"16\" fill=\"none\"/><path fill=\"currentColor\" d=\"M8,10.5c-0.552,0-1,0.448-1,1c0,0.552,0.448,1,1,1c0.552,0,1-0.448,1-1C9,10.948,8.552,10.5,8,10.5z M8,0 C3.582,0,0,3.582,0,8c0,4.418,3.582,8,8,8s8-3.582,8-8C16,3.582,12.418,0,8,0z M12.243,12.243C11.109,13.376,9.603,14,8,14 s-3.109-0.624-4.243-1.757C2.624,11.109,2,9.603,2,8s0.624-3.109,1.757-4.243C4.891,2.624,6.397,2,8,2s3.109,0.624,4.243,1.757 C13.376,4.891,14,6.397,14,8C14,9.603,13.376,11.109,12.243,12.243z M7.927,3.755c-2.248,0-2.76,1.695-2.802,2.906h1.571 c0.028-0.256,0.101-1.418,1.221-1.418c0.672,0,1.206,0.406,1.206,1.175c0,0.695-0.724,1.155-1.303,1.711 C7.241,8.685,7.168,9.325,7.168,9.824V10c0.146,0,1.615,0,1.615,0V9.824c0-1.256,1.967-1.594,1.967-3.541 C10.75,5.059,9.874,3.755,7.927,3.755z\"/></svg>'\n\n const nodeNameLookup = ['TEXTAREA', 'SELECT']\n const inputTypeLookup = ['checkbox', 'color', 'date', 'datetime-local', 'email', 'file', 'image', 'month', 'number', 'password', 'radio', 'range', 'search', 'tel', 'text', 'time', 'url', 'week']\n\n // progressively enhance form elements that have the semanticForms class\n const forms = document.querySelectorAll('form.semanticForms:not(.semanticFormsActive)')\n\n for (const form of forms) {\n form.classList.add('semanticFormsActive')\n if (form.classList.contains('lowFlow')) continue\n\n // update each input in the semantic form\n const inputs = Array.from(form.querySelectorAll('input, textarea, select'))\n for (const input of inputs) {\n // ignore input if it has previously been formatted\n if (input.classList.contains('semanticform') || !input.id) continue\n\n const type = input.getAttribute('type')\n if (nodeNameLookup.includes(input.nodeName) || inputTypeLookup.includes(type)) {\n // recursively find <dl> element\n let dl = input.parentNode\n while (dl && dl.nodeName !== 'DL') dl = dl.parentNode\n\n if (!dl) continue\n if (!dl.classList.contains('floatLabelForm')) dl.classList.add('floatLabelForm')\n\n const label = input.parentNode.parentNode.id && (type === 'checkbox' || type === 'radio')\n ? document.querySelector('label[data-for=' + input.parentNode.parentNode.id.replace(/\\./g, '\\\\.') + ']')\n : document.querySelector('label[for=' + input.id.replace(/\\./g, '\\\\.') + ']')\n\n if (!label) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) without a properly associated label. Make sure there is a label for it and the label has a matching \"for\" attribute.`)\n }\n\n input.classList.add('semanticform')\n\n // #region create labels\n\n if (type === 'checkbox' || type === 'radio') {\n // recursively find <dd> element\n let dd = input.parentNode\n while (dd && dd.nodeName !== 'DD') dd = dd.parentNode\n\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that is not inside a <dd> element.`)\n continue\n }\n\n if (dd.firstChild.nodeName !== 'LABEL') {\n const newLabel = document.createElement('label')\n newLabel.className = 'floatLabelFormAnimatedLabel'\n\n if (type === 'checkbox' && input.parentNode.nodeName === 'DD') {\n newLabel.setAttribute('for', input.id)\n input.parentNode.classList.add('singleCheckbox')\n newLabel.className = ''\n label.setAttribute('hidden', 'hidden')\n insertAfter(newLabel, input)\n }\n\n if (type === 'radio' && input.parentNode.nodeName === 'DD') {\n newLabel.setAttribute('for', input.id)\n input.parentNode.classList.add('singleRadio')\n newLabel.className = ''\n label.setAttribute('hidden', 'hidden')\n insertAfter(newLabel, input)\n }\n\n newLabel.innerHTML = label.innerHTML\n\n if (label.hasAttribute('title') && label.getAttribute('data-show-help-icon') !== null && !label.querySelector('span.help')) {\n const text = label.getAttribute('title')\n label.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n }\n\n if (dd.querySelector(':required') && label.getAttribute('data-no-asterisk') === null && !label.querySelector('span.required')) {\n const text = label.getAttribute('data-asterisk-text') || 'This field is required.'\n label.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n }\n\n if (!dd.querySelector('label')) dd.append(newLabel)\n }\n\n // removes old div that a radio or checkbox may have been added to\n if (dd.parentElement.nodeName === 'DIV') dd.parentElement.remove()\n\n const div = document.createElement('div')\n div.append(label.closest('dt'), dd)\n dl.append(div)\n } else {\n const newLabel = document.createElement('label')\n newLabel.setAttribute('for', input.id)\n newLabel.className = 'floatLabelFormAnimatedLabel'\n\n newLabel.innerHTML = label.innerHTML\n\n if (input.hasAttribute('title') && label.getAttribute('data-show-help-icon') !== null && !label.querySelector('span.help')) {\n const text = input.getAttribute('title')\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n }\n\n if (input.hasAttribute('required') && label.getAttribute('data-no-asterisk') === null && !label.querySelector('span.required')) {\n const text = label.getAttribute('data-asterisk-text') || 'This field is required.'\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n }\n\n label.setAttribute('hidden', 'hidden')\n\n insertAfter(newLabel, input)\n }\n // #endregion\n\n // standard inputs\n if (type !== 'checkbox' && type !== 'radio') {\n if (!input.getAttribute('placeholder')) input.setAttribute('placeholder', ' ')\n\n const div = document.createElement('div')\n const dt = label.closest('dt')\n const dd = input.closest('dd')\n\n if (!dt) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that does not have a corresponding <dt> element.`)\n continue\n }\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that does not have a corresponding <dd> element.`)\n continue\n }\n\n // #region clear button\n if (input.nodeName !== 'SELECT' && type !== 'range') {\n const clearBtn = document.createElement('button')\n clearBtn.type = 'button'\n clearBtn.title = input.getAttribute('data-clear-field-text') || 'Clear field'\n clearBtn.ariaLabel = input.getAttribute('data-clear-field-text') || 'Clear field'\n clearBtn.tabIndex = -1\n clearBtn.innerHTML = '<svg viewBox=\"0 0 16 16\" width=\"18\" height=\"18\"><path d=\"M 1 1 L 15 15 M 1 15 L 15 1\" fill=\"none\" stroke-width=\"2\" stroke=\"currentColor\" />'\n clearBtn.classList.add('clear')\n clearBtn.id = `semanticFormsClearButton_${input.id}`\n clearBtn.addEventListener('click', () => {\n input.previousValue = input.value\n input.value = ''\n input.focus()\n lastClearFieldPressed = input.id\n })\n insertAfter(clearBtn, dd.querySelector('label'))\n }\n input.addEventListener('focus', event => {\n if (event.target.nodeName === 'INPUT') lastFocusedInput = event.target\n })\n // #endregion\n\n // check for colspan- utility class\n if (/colspan-/.test(dd.className)) {\n const match = dd.className.match(/colspan-([0-9]|full)/)[0]\n dd.classList.remove(match)\n div.classList.add(match)\n }\n\n div.append(dt, dd)\n dl.append(div)\n\n // determine visibility of newly created <div>\n if (dt.style.display === 'none' && dd.style.display === 'none') div.style.display = 'none'\n }\n\n // handle file input clear btn, cannot be handled with CSS\n if (type === 'file') {\n const clearBtn = input.parentElement.querySelector('.clear')\n input.addEventListener('input', event => {\n clearBtn.style.display = event.target.files.length ? 'flex' : 'none'\n })\n clearBtn.addEventListener('click', () => {\n clearBtn.style.display = 'none'\n })\n }\n\n // handle range inputs with a class to display the value\n if (type === 'range' && input.classList.contains('displayValue')) {\n const label = input.parentNode.parentNode.querySelector('dd label')\n label.innerHTML += `<span class=\"seperator\">: </span><output>${input.value}</output>`\n input.addEventListener('input', event => {\n const output = event.target.parentNode.parentNode.querySelector('output')\n output.innerHTML = event.target.value\n })\n }\n\n // #region show password button\n if (type === 'password' && input.getAttribute('data-no-reveal') === null) {\n const showBtn = document.createElement('button')\n showBtn.type = 'button'\n showBtn.title = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.ariaLabel = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.tabIndex = -1\n showBtn.innerHTML = passwordShow\n showBtn.classList.add('show')\n showBtn.id = `semanticFormsShowButton_${input.id}`\n const dd = input.closest('dd')\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that is not inside a <dd> element.`)\n continue\n }\n showBtn.addEventListener('click', () => {\n if (input.type === 'password') {\n showBtn.innerHTML = passwordHide\n showBtn.title = input.getAttribute('data-hide-password-text') || 'Hide password'\n showBtn.ariaLabel = input.getAttribute('data-hide-password-text') || 'Hide password'\n input.type = 'text'\n } else {\n showBtn.innerHTML = passwordShow\n showBtn.title = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.ariaLabel = input.getAttribute('data-show-password-text') || 'Show password'\n input.type = 'password'\n }\n input.focus()\n })\n insertAfter(showBtn, dd.querySelector('label'))\n }\n // #endregion\n\n // add listener to shift clear button when scrollbar present\n for (const textarea of document.querySelectorAll('textarea')) {\n // shifts the close button to the right if a scrollbar is present\n const shiftCloseBtn = () => {\n const clearBtn = textarea.parentElement?.querySelector('button.clear')\n if (clearBtn) clearBtn.style.marginRight = textarea.clientHeight < textarea.scrollHeight ? '15px' : ''\n }\n\n textarea.addEventListener('input', shiftCloseBtn)\n textarea.addEventListener('mouseup', shiftCloseBtn)\n }\n }\n }\n }\n\n /**\n * Places an element immediately after another element\n * @param {Object} newNode element being placed after the reference node\n * @param {*} referenceNode element to be used as reference for new node\n */\n function insertAfter (newNode, referenceNode) {\n if (referenceNode.nextSibling) referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling)\n else referenceNode.parentNode.appendChild(newNode)\n }\n\n // handle undo/redo\n let lastFocusedInput\n let lastClearFieldPressed\n document.addEventListener('keydown', event => {\n if ((event.ctrlKey || event.metaKey) && event.key === 'z' && !event.shiftKey) {\n // undo clearing a field\n if (lastFocusedInput) {\n if (lastFocusedInput?.parentNode?.querySelector('button.clear').id === `semanticFormsClearButton_${lastClearFieldPressed}` || lastFocusedInput?.parentNode?.querySelector('button.clear').name === `semanticFormsClearButton_${lastClearFieldPressed}`) {\n if (lastFocusedInput.previousValue) {\n lastFocusedInput.redoValue = lastFocusedInput.value\n lastFocusedInput.value = lastFocusedInput.previousValue\n }\n }\n }\n } else if ((event.ctrlKey && event.key === 'y') || (event.metaKey && event.shiftKey && event.key === 'z')) {\n // redo clearing a field\n if (lastFocusedInput) {\n if (lastFocusedInput?.parentNode?.querySelector('button.clear').id === `semanticFormsClearButton_${lastClearFieldPressed}` || lastFocusedInput?.parentNode?.querySelector('button.clear').name === `semanticFormsClearButton_${lastClearFieldPressed}`) {\n if (lastFocusedInput.redoValue) {\n lastFocusedInput.previousValue = lastFocusedInput.value\n lastFocusedInput.value = lastFocusedInput.redoValue\n }\n }\n }\n }\n })\n\n // monitor changes to the DOM and enhance new semanticForms forms that get added\n if (!window.semanticFormsObserver) {\n window.semanticFormsObserver = new window.MutationObserver(mutations => {\n let stop = false\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (node.nodeName === 'FORM' || node?.querySelector?.('form')) {\n semanticForms()\n stop = true\n }\n }\n if (stop) break\n }\n })\n window.semanticFormsObserver.observe(document.body, { attributes: false, childList: true, characterData: false, subtree: true })\n }\n\n semanticForms.reinitialize = form => {\n form.classList.remove('semanticFormsActive')\n semanticForms()\n }\n}\n\nmodule.exports = semanticForms\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(90);\n"],"names":["semanticForms","document","getElementsByClassName","querySelector","body","classList","window","MutationObserver","console","warn","passwordShow","helpTextIcon","nodeNameLookup","inputTypeLookup","forms","querySelectorAll","form","add","contains","inputs","Array","from","input","id","type","getAttribute","includes","nodeName","dl","parentNode","label","replace","error","dd","firstChild","newLabel","createElement","className","setAttribute","insertAfter","innerHTML","hasAttribute","text","append","parentElement","remove","div","closest","dt","clearBtn","title","ariaLabel","tabIndex","addEventListener","previousValue","value","focus","lastClearFieldPressed","event","target","lastFocusedInput","test","match","style","display","files","length","showBtn","textarea","shiftCloseBtn","marginRight","clientHeight","scrollHeight","newNode","referenceNode","nextSibling","insertBefore","appendChild","ctrlKey","metaKey","key","shiftKey","name","redoValue","semanticFormsObserver","mutations","stop","mutation","node","addedNodes","observe","attributes","childList","characterData","subtree","reinitialize","module","exports","__webpack_module_cache__","__webpack_exports__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__"],"sourceRoot":""}
1
+ {"version":3,"file":"semantic-forms.min.mjs","mappings":"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","sources":["webpack://semantic-forms/./semanticForms.js","webpack://semantic-forms/webpack/bootstrap","webpack://semantic-forms/webpack/startup"],"sourcesContent":["const semanticForms = () => {\n // do some feature detection so none of the JS executes if the browser is too old\n if (typeof document.getElementsByClassName !== 'function' || typeof document.querySelector !== 'function' || !document.body.classList || !window.MutationObserver) {\n console.warn('semantic-forms was loaded into an unsupported browser and will not execute.')\n return\n }\n\n const passwordShow = '<svg fill=\"none\" height=\"256\" viewBox=\"0 0 24 24\" width=\"256\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m1 12s4-8 11-8 11 8 11 8\"/><path d=\"m1 12s4 8 11 8 11-8 11-8\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></g></svg>'\n const passwordHide = '<svg fill=\"none\" height=\"256\" viewBox=\"0 0 24 24\" width=\"256\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m2 2 20 20\"/><path d=\"m6.71277 6.7226c-3.04798 2.07267-4.71277 5.2774-4.71277 5.2774s3.63636 7 10 7c2.0503 0 3.8174-.7266 5.2711-1.7116m-6.2711-12.23018c.3254-.03809.6588-.05822 1-.05822 6.3636 0 10 7 10 7s-.6918 1.3317-2 2.8335\"/><path d=\"m14 14.2362c-.5308.475-1.2316.7639-2 .7639-1.6569 0-3-1.3431-3-3 0-.8237.33193-1.5698.86932-2.11192\"/></g></svg>'\n const helpTextIcon = '<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" style=\"overflow:visible;margin-top:1px;\"><rect width=\"16\" height=\"16\" fill=\"none\"/><path fill=\"currentColor\" d=\"M8,10.5c-0.552,0-1,0.448-1,1c0,0.552,0.448,1,1,1c0.552,0,1-0.448,1-1C9,10.948,8.552,10.5,8,10.5z M8,0 C3.582,0,0,3.582,0,8c0,4.418,3.582,8,8,8s8-3.582,8-8C16,3.582,12.418,0,8,0z M12.243,12.243C11.109,13.376,9.603,14,8,14 s-3.109-0.624-4.243-1.757C2.624,11.109,2,9.603,2,8s0.624-3.109,1.757-4.243C4.891,2.624,6.397,2,8,2s3.109,0.624,4.243,1.757 C13.376,4.891,14,6.397,14,8C14,9.603,13.376,11.109,12.243,12.243z M7.927,3.755c-2.248,0-2.76,1.695-2.802,2.906h1.571 c0.028-0.256,0.101-1.418,1.221-1.418c0.672,0,1.206,0.406,1.206,1.175c0,0.695-0.724,1.155-1.303,1.711 C7.241,8.685,7.168,9.325,7.168,9.824V10c0.146,0,1.615,0,1.615,0V9.824c0-1.256,1.967-1.594,1.967-3.541 C10.75,5.059,9.874,3.755,7.927,3.755z\"/></svg>'\n\n const nodeNameLookup = ['TEXTAREA', 'SELECT']\n const inputTypeLookup = ['checkbox', 'color', 'date', 'datetime-local', 'email', 'file', 'image', 'month', 'number', 'password', 'radio', 'range', 'search', 'tel', 'text', 'time', 'url', 'week']\n\n // progressively enhance form elements that have the semanticForms class\n const forms = document.querySelectorAll('form.semanticForms:not(.semanticFormsActive)')\n\n for (const form of forms) {\n form.classList.add('semanticFormsActive')\n if (form.classList.contains('lowFlow')) continue\n\n // update each input in the semantic form\n const inputs = Array.from(form.querySelectorAll('input, textarea, select'))\n for (const input of inputs) {\n // ignore input if it has previously been formatted\n if (input.classList.contains('semanticform') || !input.id) continue\n\n const type = input.getAttribute('type')\n if (nodeNameLookup.includes(input.nodeName) || inputTypeLookup.includes(type)) {\n // recursively find <dl> element\n let dl = input.parentNode\n while (dl && dl.nodeName !== 'DL') dl = dl.parentNode\n\n if (!dl) continue\n if (!dl.classList.contains('floatLabelForm')) dl.classList.add('floatLabelForm')\n\n const label = input.parentNode.parentNode.id && (type === 'checkbox' || type === 'radio')\n ? document.querySelector('label[data-for=' + input.parentNode.parentNode.id.replace(/\\./g, '\\\\.') + ']')\n : document.querySelector('label[for=' + input.id.replace(/\\./g, '\\\\.') + ']')\n\n if (!label) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) without a properly associated label. Make sure there is a label for it and the label has a matching \"for\" attribute.`)\n }\n\n input.classList.add('semanticform')\n\n // #region create labels\n\n if (type === 'checkbox' || type === 'radio') {\n // recursively find <dd> element\n let dd = input.parentNode\n while (dd && dd.nodeName !== 'DD') dd = dd.parentNode\n\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that is not inside a <dd> element.`)\n continue\n }\n\n if (dd.firstChild.nodeName !== 'LABEL') {\n const newLabel = document.createElement('label')\n newLabel.className = 'floatLabelFormAnimatedLabel'\n\n if (type === 'checkbox' && input.parentNode.nodeName === 'DD') {\n newLabel.setAttribute('for', input.id)\n input.parentNode.classList.add('singleCheckbox')\n newLabel.className = ''\n label.setAttribute('hidden', 'hidden')\n insertAfter(newLabel, input)\n }\n\n if (type === 'radio' && input.parentNode.nodeName === 'DD') {\n newLabel.setAttribute('for', input.id)\n input.parentNode.classList.add('singleRadio')\n newLabel.className = ''\n label.setAttribute('hidden', 'hidden')\n insertAfter(newLabel, input)\n }\n\n newLabel.innerHTML = label.innerHTML\n\n if (label.hasAttribute('title') && label.getAttribute('data-show-help-icon') !== null && !label.querySelector('span.help')) {\n const text = label.getAttribute('title')\n label.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n }\n\n if (dd.querySelector(':required') && label.getAttribute('data-no-asterisk') === null && !label.querySelector('span.required')) {\n const text = label.getAttribute('data-asterisk-text') || 'This field is required.'\n label.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n }\n\n if (!dd.querySelector('label')) dd.append(newLabel)\n }\n\n // removes old div that a radio or checkbox may have been added to\n if (dd.parentElement.nodeName === 'DIV') dd.parentElement.remove()\n\n const div = document.createElement('div')\n div.append(label.closest('dt'), dd)\n dl.append(div)\n } else {\n const newLabel = document.createElement('label')\n newLabel.setAttribute('for', input.id)\n newLabel.className = 'floatLabelFormAnimatedLabel'\n\n newLabel.innerHTML = label.innerHTML\n\n if (input.hasAttribute('title') && label.getAttribute('data-show-help-icon') !== null && !label.querySelector('span.help')) {\n const text = input.getAttribute('title')\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n }\n\n if (input.hasAttribute('required') && label.getAttribute('data-no-asterisk') === null && !label.querySelector('span.required')) {\n const text = label.getAttribute('data-asterisk-text') || 'This field is required.'\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n }\n\n label.setAttribute('hidden', 'hidden')\n\n insertAfter(newLabel, input)\n }\n // #endregion\n\n // standard inputs\n if (type !== 'checkbox' && type !== 'radio') {\n if (!input.getAttribute('placeholder')) input.setAttribute('placeholder', ' ')\n\n const div = document.createElement('div')\n const dt = label.closest('dt')\n const dd = input.closest('dd')\n\n if (!dt) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that does not have a corresponding <dt> element.`)\n continue\n }\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that does not have a corresponding <dd> element.`)\n continue\n }\n\n // #region clear button\n if (input.nodeName !== 'SELECT' && type !== 'range') {\n const clearBtn = document.createElement('button')\n clearBtn.type = 'button'\n clearBtn.title = input.getAttribute('data-clear-field-text') || 'Clear field'\n clearBtn.ariaLabel = input.getAttribute('data-clear-field-text') || 'Clear field'\n clearBtn.tabIndex = -1\n clearBtn.innerHTML = '<svg viewBox=\"0 0 16 16\" width=\"18\" height=\"18\"><path d=\"M 1 1 L 15 15 M 1 15 L 15 1\" fill=\"none\" stroke-width=\"2\" stroke=\"currentColor\" />'\n clearBtn.classList.add('clear')\n clearBtn.id = `semanticFormsClearButton_${input.id}`\n clearBtn.addEventListener('click', () => {\n input.previousValue = input.value\n input.value = ''\n input.focus()\n lastClearFieldPressed = input.id\n\n // used for any other updates required by various inputs\n input.dispatchEvent(new Event('input', { bubbles: true }))\n })\n insertAfter(clearBtn, dd.querySelector('label'))\n }\n input.addEventListener('focus', event => {\n if (event.target.nodeName === 'INPUT') lastFocusedInput = event.target\n })\n // #endregion\n\n // check for colspan- utility class\n if (/colspan-/.test(dd.className)) {\n const match = dd.className.match(/colspan-([0-9]|full)/)[0]\n dd.classList.remove(match)\n div.classList.add(match)\n }\n\n div.append(dt, dd)\n dl.append(div)\n\n // determine visibility of newly created <div>\n if (dt.style.display === 'none' && dd.style.display === 'none') div.style.display = 'none'\n }\n\n // handle file input clear btn, cannot be handled with CSS\n if (type === 'file') {\n const clearBtn = input.parentElement.querySelector('.clear')\n input.addEventListener('input', event => {\n clearBtn.style.display = event.target.files.length ? 'flex' : 'none'\n })\n clearBtn.addEventListener('click', () => {\n clearBtn.style.display = 'none'\n })\n }\n\n // handle range inputs with a class to display the value\n if (type === 'range' && input.classList.contains('displayValue')) {\n const label = input.parentNode.parentNode.querySelector('dd label')\n label.innerHTML += `<span class=\"seperator\">: </span><output>${input.value}</output>`\n input.addEventListener('input', event => {\n const output = event.target.parentNode.parentNode.querySelector('output')\n output.innerHTML = event.target.value\n })\n }\n\n // #region show password button\n if (type === 'password' && input.getAttribute('data-no-reveal') === null) {\n const showBtn = document.createElement('button')\n showBtn.type = 'button'\n showBtn.title = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.ariaLabel = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.tabIndex = -1\n showBtn.innerHTML = passwordShow\n showBtn.classList.add('show')\n showBtn.id = `semanticFormsShowButton_${input.id}`\n const dd = input.closest('dd')\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that is not inside a <dd> element.`)\n continue\n }\n showBtn.addEventListener('click', () => {\n if (input.type === 'password') {\n showBtn.innerHTML = passwordHide\n showBtn.title = input.getAttribute('data-hide-password-text') || 'Hide password'\n showBtn.ariaLabel = input.getAttribute('data-hide-password-text') || 'Hide password'\n input.type = 'text'\n } else {\n showBtn.innerHTML = passwordShow\n showBtn.title = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.ariaLabel = input.getAttribute('data-show-password-text') || 'Show password'\n input.type = 'password'\n }\n input.focus()\n })\n insertAfter(showBtn, dd.querySelector('label'))\n }\n // #endregion\n\n // add listener to shift clear button when scrollbar present\n if (input.nodeName === 'TEXTAREA') {\n if (input.getAttribute('data-disable-autosize') === null) {\n // add auto-sizing\n input.style.setProperty('resize', 'none')\n input.style.setProperty('min-height', '0')\n input.style.setProperty('max-height', 'none')\n input.style.setProperty('height', 'auto')\n \n const handleInput = () => {\n // reset rows attribute to get accurate scrollHeight\n let maxRows = input.getAttribute('data-max-rows')\n\n if (maxRows) {\n if (isNaN(maxRows) || Number(maxRows) <= 0) {\n console.warn(`An invalid value was passed to the \"data-max-rows\" attribute. This value will be ignored.\\n\\nProvided value: ${input.getAttribute('data-max-rows')}`, )\n maxRows = null\n }\n }\n\n const minRows = input.getAttribute('data-max-rows') && Number(input.getAttribute('data-max-rows')) < 5 ? input.getAttribute('data-max-rows') : '5'\n input.setAttribute('rows', minRows)\n \n // get the computed values object reference\n const style = window.getComputedStyle(input)\n \n // force content-box for size accurate line-height calculation, remove scrollbars, lock width (subtract inline padding and inline border widths), and remove inline padding and borders to keep width consistent (for text wrapping accuracy)\n const inlinePadding = parseFloat(style['padding-left']) + parseFloat(style['padding-right'])\n const inlineBorderWidth = parseFloat(style['border-left-width']) + parseFloat(style['border-right-width'])\n input.style.setProperty('overflow', 'hidden', 'important')\n input.style.setProperty('width', (parseFloat(style['width']) - inlinePadding - inlineBorderWidth) + 'px')\n input.style.setProperty('box-sizing', 'content-box')\n input.style.setProperty('padding-inline', '0')\n input.style.setProperty('border-width', '0')\n \n // get the base line height, and top / bottom padding\n const blockPadding = parseFloat(style['padding-top']) + parseFloat(style['padding-bottom'])\n const lineHeight = style['line-height'] === 'normal' \n ? parseFloat(style['height']) // if line-height is not explicitly set, use the computed height value (ignore padding due to content-box)\n : parseFloat(style['line-height']) // otherwise (line-height is explicitly set), use the computed line-height value\n \n // get the scroll height (rounding to be safe to ensure cross browser consistency)\n const scrollHeight = Math.round(input.scrollHeight)\n \n // undo overflow, width, border-width, box-sizing & inline padding overrides\n input.style.removeProperty('width')\n input.style.removeProperty('box-sizing')\n input.style.removeProperty('padding-inline')\n input.style.removeProperty('border-width')\n input.style.removeProperty('overflow')\n \n // subtract blockPadding from scrollHeight and divide that by our lineHeight to get the row count, round to nearest integer as it will always be within ~.1 of the correct whole number\n const rows = Math.round((scrollHeight - blockPadding) / lineHeight)\n \n // set the calculated rows attribute (limited by rowLimit)\n if (maxRows) {\n input.setAttribute(\"rows\", \"\" + Math.min(rows, Number(maxRows)))\n } else {\n input.setAttribute(\"rows\", \"\" + rows)\n }\n }\n \n input.addEventListener('input', handleInput)\n \n // trigger the event to set the initial rows value\n input.dispatchEvent(new Event('input', { bubbles: true }))\n }\n\n // shifts the clear button to the right if a scrollbar is present\n const shiftClearBtn = () => {\n const clearBtn = input.parentElement?.querySelector('button.clear')\n if (clearBtn) clearBtn.style.marginRight = input.clientHeight < input.scrollHeight ? '15px' : ''\n }\n input.addEventListener('input', shiftClearBtn)\n input.addEventListener('mouseup', shiftClearBtn)\n shiftClearBtn()\n }\n }\n }\n }\n\n /**\n * Places an element immediately after another element\n * @param {Object} newNode element being placed after the reference node\n * @param {*} referenceNode element to be used as reference for new node\n */\n function insertAfter (newNode, referenceNode) {\n if (referenceNode.nextSibling) referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling)\n else referenceNode.parentNode.appendChild(newNode)\n }\n\n // handle undo/redo\n let lastFocusedInput\n let lastClearFieldPressed\n document.addEventListener('keydown', event => {\n if ((event.ctrlKey || event.metaKey) && event.key === 'z' && !event.shiftKey) {\n // undo clearing a field\n if (lastFocusedInput) {\n if (lastFocusedInput?.parentNode?.querySelector('button.clear').id === `semanticFormsClearButton_${lastClearFieldPressed}` || lastFocusedInput?.parentNode?.querySelector('button.clear').name === `semanticFormsClearButton_${lastClearFieldPressed}`) {\n if (lastFocusedInput.previousValue) {\n lastFocusedInput.redoValue = lastFocusedInput.value\n lastFocusedInput.value = lastFocusedInput.previousValue\n }\n }\n }\n } else if ((event.ctrlKey && event.key === 'y') || (event.metaKey && event.shiftKey && event.key === 'z')) {\n // redo clearing a field\n if (lastFocusedInput) {\n if (lastFocusedInput?.parentNode?.querySelector('button.clear').id === `semanticFormsClearButton_${lastClearFieldPressed}` || lastFocusedInput?.parentNode?.querySelector('button.clear').name === `semanticFormsClearButton_${lastClearFieldPressed}`) {\n if (lastFocusedInput.redoValue) {\n lastFocusedInput.previousValue = lastFocusedInput.value\n lastFocusedInput.value = lastFocusedInput.redoValue\n }\n }\n }\n }\n })\n\n // monitor changes to the DOM and enhance new semanticForms forms that get added\n if (!window.semanticFormsObserver) {\n window.semanticFormsObserver = new window.MutationObserver(mutations => {\n let stop = false\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (node.nodeName === 'FORM' || node?.querySelector?.('form')) {\n semanticForms()\n stop = true\n }\n }\n if (stop) break\n }\n })\n window.semanticFormsObserver.observe(document.body, { attributes: false, childList: true, characterData: false, subtree: true })\n }\n\n semanticForms.reinitialize = form => {\n form.classList.remove('semanticFormsActive')\n semanticForms()\n }\n}\n\nmodule.exports = semanticForms\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(90);\n"],"names":["semanticForms","document","getElementsByClassName","querySelector","body","classList","window","MutationObserver","console","warn","passwordShow","helpTextIcon","nodeNameLookup","inputTypeLookup","forms","querySelectorAll","form","add","contains","inputs","Array","from","input","id","type","getAttribute","includes","nodeName","dl","parentNode","label","replace","error","dd","firstChild","newLabel","createElement","className","setAttribute","insertAfter","innerHTML","hasAttribute","text","append","parentElement","remove","div","closest","dt","clearBtn","title","ariaLabel","tabIndex","addEventListener","previousValue","value","focus","lastClearFieldPressed","dispatchEvent","Event","bubbles","event","target","lastFocusedInput","test","match","style","display","files","length","showBtn","setProperty","handleInput","maxRows","isNaN","Number","minRows","getComputedStyle","inlinePadding","parseFloat","inlineBorderWidth","blockPadding","lineHeight","scrollHeight","Math","round","removeProperty","rows","min","shiftClearBtn","marginRight","clientHeight","newNode","referenceNode","nextSibling","insertBefore","appendChild","ctrlKey","metaKey","key","shiftKey","name","redoValue","semanticFormsObserver","mutations","stop","mutation","node","addedNodes","observe","attributes","childList","characterData","subtree","reinitialize","module","exports","__webpack_module_cache__","__webpack_exports__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__"],"sourceRoot":""}
@@ -24,7 +24,9 @@ if(dd.parentElement.nodeName==="DIV")dd.parentElement.remove();const div=documen
24
24
  // standard inputs
25
25
  if(type!=="checkbox"&&type!=="radio"){if(!input.getAttribute("placeholder"))input.setAttribute("placeholder"," ");const div=document.createElement("div");const dt=label.closest("dt");const dd=input.closest("dd");if(!dt){console.error(`semantic-forms: Found an input (${input.id||input.getAttribute("name")}) that does not have a corresponding <dt> element.`);continue}if(!dd){console.error(`semantic-forms: Found an input (${input.id||input.getAttribute("name")}) that does not have a corresponding <dd> element.`);continue}
26
26
  // #region clear button
27
- if(input.nodeName!=="SELECT"&&type!=="range"){const clearBtn=document.createElement("button");clearBtn.type="button";clearBtn.title=input.getAttribute("data-clear-field-text")||"Clear field";clearBtn.ariaLabel=input.getAttribute("data-clear-field-text")||"Clear field";clearBtn.tabIndex=-1;clearBtn.innerHTML='<svg viewBox="0 0 16 16" width="18" height="18"><path d="M 1 1 L 15 15 M 1 15 L 15 1" fill="none" stroke-width="2" stroke="currentColor" />';clearBtn.classList.add("clear");clearBtn.id=`semanticFormsClearButton_${input.id}`;clearBtn.addEventListener("click",()=>{input.previousValue=input.value;input.value="";input.focus();lastClearFieldPressed=input.id});insertAfter(clearBtn,dd.querySelector("label"))}input.addEventListener("focus",event=>{if(event.target.nodeName==="INPUT")lastFocusedInput=event.target});
27
+ if(input.nodeName!=="SELECT"&&type!=="range"){const clearBtn=document.createElement("button");clearBtn.type="button";clearBtn.title=input.getAttribute("data-clear-field-text")||"Clear field";clearBtn.ariaLabel=input.getAttribute("data-clear-field-text")||"Clear field";clearBtn.tabIndex=-1;clearBtn.innerHTML='<svg viewBox="0 0 16 16" width="18" height="18"><path d="M 1 1 L 15 15 M 1 15 L 15 1" fill="none" stroke-width="2" stroke="currentColor" />';clearBtn.classList.add("clear");clearBtn.id=`semanticFormsClearButton_${input.id}`;clearBtn.addEventListener("click",()=>{input.previousValue=input.value;input.value="";input.focus();lastClearFieldPressed=input.id;
28
+ // used for any other updates required by various inputs
29
+ input.dispatchEvent(new Event("input",{bubbles:true}))});insertAfter(clearBtn,dd.querySelector("label"))}input.addEventListener("focus",event=>{if(event.target.nodeName==="INPUT")lastFocusedInput=event.target});
28
30
  // #endregion
29
31
  // check for colspan- utility class
30
32
  if(/colspan-/.test(dd.className)){const match=dd.className.match(/colspan-([0-9]|full)/)[0];dd.classList.remove(match);div.classList.add(match)}div.append(dt,dd);dl.append(div);
@@ -38,9 +40,29 @@ if(type==="range"&&input.classList.contains("displayValue")){const label=input.p
38
40
  if(type==="password"&&input.getAttribute("data-no-reveal")===null){const showBtn=document.createElement("button");showBtn.type="button";showBtn.title=input.getAttribute("data-show-password-text")||"Show password";showBtn.ariaLabel=input.getAttribute("data-show-password-text")||"Show password";showBtn.tabIndex=-1;showBtn.innerHTML=passwordShow;showBtn.classList.add("show");showBtn.id=`semanticFormsShowButton_${input.id}`;const dd=input.closest("dd");if(!dd){console.error(`semantic-forms: Found an input (${input.id||input.getAttribute("name")}) that is not inside a <dd> element.`);continue}showBtn.addEventListener("click",()=>{if(input.type==="password"){showBtn.innerHTML=passwordHide;showBtn.title=input.getAttribute("data-hide-password-text")||"Hide password";showBtn.ariaLabel=input.getAttribute("data-hide-password-text")||"Hide password";input.type="text"}else{showBtn.innerHTML=passwordShow;showBtn.title=input.getAttribute("data-show-password-text")||"Show password";showBtn.ariaLabel=input.getAttribute("data-show-password-text")||"Show password";input.type="password"}input.focus()});insertAfter(showBtn,dd.querySelector("label"))}
39
41
  // #endregion
40
42
  // add listener to shift clear button when scrollbar present
41
- for(const textarea of document.querySelectorAll("textarea")){
42
- // shifts the close button to the right if a scrollbar is present
43
- const shiftCloseBtn=()=>{const clearBtn=textarea.parentElement?.querySelector("button.clear");if(clearBtn)clearBtn.style.marginRight=textarea.clientHeight<textarea.scrollHeight?"15px":""};textarea.addEventListener("input",shiftCloseBtn);textarea.addEventListener("mouseup",shiftCloseBtn)}}}}
43
+ if(input.nodeName==="TEXTAREA"){if(input.getAttribute("data-disable-autosize")===null){
44
+ // add auto-sizing
45
+ input.style.setProperty("resize","none");input.style.setProperty("min-height","0");input.style.setProperty("max-height","none");input.style.setProperty("height","auto");const handleInput=()=>{
46
+ // reset rows attribute to get accurate scrollHeight
47
+ let maxRows=input.getAttribute("data-max-rows");if(maxRows)if(isNaN(maxRows)||Number(maxRows)<=0){console.warn(`An invalid value was passed to the "data-max-rows" attribute. This value will be ignored.\n\nProvided value: ${input.getAttribute("data-max-rows")}`);maxRows=null}const minRows=input.getAttribute("data-max-rows")&&Number(input.getAttribute("data-max-rows"))<5?input.getAttribute("data-max-rows"):"5";input.setAttribute("rows",minRows);
48
+ // get the computed values object reference
49
+ const style=window.getComputedStyle(input);
50
+ // force content-box for size accurate line-height calculation, remove scrollbars, lock width (subtract inline padding and inline border widths), and remove inline padding and borders to keep width consistent (for text wrapping accuracy)
51
+ const inlinePadding=parseFloat(style["padding-left"])+parseFloat(style["padding-right"]);const inlineBorderWidth=parseFloat(style["border-left-width"])+parseFloat(style["border-right-width"]);input.style.setProperty("overflow","hidden","important");input.style.setProperty("width",parseFloat(style["width"])-inlinePadding-inlineBorderWidth+"px");input.style.setProperty("box-sizing","content-box");input.style.setProperty("padding-inline","0");input.style.setProperty("border-width","0");
52
+ // get the base line height, and top / bottom padding
53
+ const blockPadding=parseFloat(style["padding-top"])+parseFloat(style["padding-bottom"]);const lineHeight=style["line-height"]==="normal"?parseFloat(style["height"]):parseFloat(style["line-height"]);// otherwise (line-height is explicitly set), use the computed line-height value
54
+ // get the scroll height (rounding to be safe to ensure cross browser consistency)
55
+ const scrollHeight=Math.round(input.scrollHeight);
56
+ // undo overflow, width, border-width, box-sizing & inline padding overrides
57
+ input.style.removeProperty("width");input.style.removeProperty("box-sizing");input.style.removeProperty("padding-inline");input.style.removeProperty("border-width");input.style.removeProperty("overflow");
58
+ // subtract blockPadding from scrollHeight and divide that by our lineHeight to get the row count, round to nearest integer as it will always be within ~.1 of the correct whole number
59
+ const rows=Math.round((scrollHeight-blockPadding)/lineHeight);
60
+ // set the calculated rows attribute (limited by rowLimit)
61
+ if(maxRows)input.setAttribute("rows",""+Math.min(rows,Number(maxRows)));else input.setAttribute("rows",""+rows)};input.addEventListener("input",handleInput);
62
+ // trigger the event to set the initial rows value
63
+ input.dispatchEvent(new Event("input",{bubbles:true}))}
64
+ // shifts the clear button to the right if a scrollbar is present
65
+ const shiftClearBtn=()=>{const clearBtn=input.parentElement?.querySelector("button.clear");if(clearBtn)clearBtn.style.marginRight=input.clientHeight<input.scrollHeight?"15px":""};input.addEventListener("input",shiftClearBtn);input.addEventListener("mouseup",shiftClearBtn);shiftClearBtn()}}}}
44
66
  /**
45
67
  * Places an element immediately after another element
46
68
  * @param {Object} newNode element being placed after the reference node
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-forms.mjs","mappings":"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","sources":["webpack://semantic-forms/./semanticForms.js","webpack://semantic-forms/webpack/bootstrap","webpack://semantic-forms/webpack/startup"],"sourcesContent":["const semanticForms = () => {\n // do some feature detection so none of the JS executes if the browser is too old\n if (typeof document.getElementsByClassName !== 'function' || typeof document.querySelector !== 'function' || !document.body.classList || !window.MutationObserver) {\n console.warn('semantic-forms was loaded into an unsupported browser and will not execute.')\n return\n }\n\n const passwordShow = '<svg fill=\"none\" height=\"256\" viewBox=\"0 0 24 24\" width=\"256\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m1 12s4-8 11-8 11 8 11 8\"/><path d=\"m1 12s4 8 11 8 11-8 11-8\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></g></svg>'\n const passwordHide = '<svg fill=\"none\" height=\"256\" viewBox=\"0 0 24 24\" width=\"256\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m2 2 20 20\"/><path d=\"m6.71277 6.7226c-3.04798 2.07267-4.71277 5.2774-4.71277 5.2774s3.63636 7 10 7c2.0503 0 3.8174-.7266 5.2711-1.7116m-6.2711-12.23018c.3254-.03809.6588-.05822 1-.05822 6.3636 0 10 7 10 7s-.6918 1.3317-2 2.8335\"/><path d=\"m14 14.2362c-.5308.475-1.2316.7639-2 .7639-1.6569 0-3-1.3431-3-3 0-.8237.33193-1.5698.86932-2.11192\"/></g></svg>'\n const helpTextIcon = '<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" style=\"overflow:visible;margin-top:1px;\"><rect width=\"16\" height=\"16\" fill=\"none\"/><path fill=\"currentColor\" d=\"M8,10.5c-0.552,0-1,0.448-1,1c0,0.552,0.448,1,1,1c0.552,0,1-0.448,1-1C9,10.948,8.552,10.5,8,10.5z M8,0 C3.582,0,0,3.582,0,8c0,4.418,3.582,8,8,8s8-3.582,8-8C16,3.582,12.418,0,8,0z M12.243,12.243C11.109,13.376,9.603,14,8,14 s-3.109-0.624-4.243-1.757C2.624,11.109,2,9.603,2,8s0.624-3.109,1.757-4.243C4.891,2.624,6.397,2,8,2s3.109,0.624,4.243,1.757 C13.376,4.891,14,6.397,14,8C14,9.603,13.376,11.109,12.243,12.243z M7.927,3.755c-2.248,0-2.76,1.695-2.802,2.906h1.571 c0.028-0.256,0.101-1.418,1.221-1.418c0.672,0,1.206,0.406,1.206,1.175c0,0.695-0.724,1.155-1.303,1.711 C7.241,8.685,7.168,9.325,7.168,9.824V10c0.146,0,1.615,0,1.615,0V9.824c0-1.256,1.967-1.594,1.967-3.541 C10.75,5.059,9.874,3.755,7.927,3.755z\"/></svg>'\n\n const nodeNameLookup = ['TEXTAREA', 'SELECT']\n const inputTypeLookup = ['checkbox', 'color', 'date', 'datetime-local', 'email', 'file', 'image', 'month', 'number', 'password', 'radio', 'range', 'search', 'tel', 'text', 'time', 'url', 'week']\n\n // progressively enhance form elements that have the semanticForms class\n const forms = document.querySelectorAll('form.semanticForms:not(.semanticFormsActive)')\n\n for (const form of forms) {\n form.classList.add('semanticFormsActive')\n if (form.classList.contains('lowFlow')) continue\n\n // update each input in the semantic form\n const inputs = Array.from(form.querySelectorAll('input, textarea, select'))\n for (const input of inputs) {\n // ignore input if it has previously been formatted\n if (input.classList.contains('semanticform') || !input.id) continue\n\n const type = input.getAttribute('type')\n if (nodeNameLookup.includes(input.nodeName) || inputTypeLookup.includes(type)) {\n // recursively find <dl> element\n let dl = input.parentNode\n while (dl && dl.nodeName !== 'DL') dl = dl.parentNode\n\n if (!dl) continue\n if (!dl.classList.contains('floatLabelForm')) dl.classList.add('floatLabelForm')\n\n const label = input.parentNode.parentNode.id && (type === 'checkbox' || type === 'radio')\n ? document.querySelector('label[data-for=' + input.parentNode.parentNode.id.replace(/\\./g, '\\\\.') + ']')\n : document.querySelector('label[for=' + input.id.replace(/\\./g, '\\\\.') + ']')\n\n if (!label) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) without a properly associated label. Make sure there is a label for it and the label has a matching \"for\" attribute.`)\n }\n\n input.classList.add('semanticform')\n\n // #region create labels\n\n if (type === 'checkbox' || type === 'radio') {\n // recursively find <dd> element\n let dd = input.parentNode\n while (dd && dd.nodeName !== 'DD') dd = dd.parentNode\n\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that is not inside a <dd> element.`)\n continue\n }\n\n if (dd.firstChild.nodeName !== 'LABEL') {\n const newLabel = document.createElement('label')\n newLabel.className = 'floatLabelFormAnimatedLabel'\n\n if (type === 'checkbox' && input.parentNode.nodeName === 'DD') {\n newLabel.setAttribute('for', input.id)\n input.parentNode.classList.add('singleCheckbox')\n newLabel.className = ''\n label.setAttribute('hidden', 'hidden')\n insertAfter(newLabel, input)\n }\n\n if (type === 'radio' && input.parentNode.nodeName === 'DD') {\n newLabel.setAttribute('for', input.id)\n input.parentNode.classList.add('singleRadio')\n newLabel.className = ''\n label.setAttribute('hidden', 'hidden')\n insertAfter(newLabel, input)\n }\n\n newLabel.innerHTML = label.innerHTML\n\n if (label.hasAttribute('title') && label.getAttribute('data-show-help-icon') !== null && !label.querySelector('span.help')) {\n const text = label.getAttribute('title')\n label.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n }\n\n if (dd.querySelector(':required') && label.getAttribute('data-no-asterisk') === null && !label.querySelector('span.required')) {\n const text = label.getAttribute('data-asterisk-text') || 'This field is required.'\n label.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n }\n\n if (!dd.querySelector('label')) dd.append(newLabel)\n }\n\n // removes old div that a radio or checkbox may have been added to\n if (dd.parentElement.nodeName === 'DIV') dd.parentElement.remove()\n\n const div = document.createElement('div')\n div.append(label.closest('dt'), dd)\n dl.append(div)\n } else {\n const newLabel = document.createElement('label')\n newLabel.setAttribute('for', input.id)\n newLabel.className = 'floatLabelFormAnimatedLabel'\n\n newLabel.innerHTML = label.innerHTML\n\n if (input.hasAttribute('title') && label.getAttribute('data-show-help-icon') !== null && !label.querySelector('span.help')) {\n const text = input.getAttribute('title')\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n }\n\n if (input.hasAttribute('required') && label.getAttribute('data-no-asterisk') === null && !label.querySelector('span.required')) {\n const text = label.getAttribute('data-asterisk-text') || 'This field is required.'\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n }\n\n label.setAttribute('hidden', 'hidden')\n\n insertAfter(newLabel, input)\n }\n // #endregion\n\n // standard inputs\n if (type !== 'checkbox' && type !== 'radio') {\n if (!input.getAttribute('placeholder')) input.setAttribute('placeholder', ' ')\n\n const div = document.createElement('div')\n const dt = label.closest('dt')\n const dd = input.closest('dd')\n\n if (!dt) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that does not have a corresponding <dt> element.`)\n continue\n }\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that does not have a corresponding <dd> element.`)\n continue\n }\n\n // #region clear button\n if (input.nodeName !== 'SELECT' && type !== 'range') {\n const clearBtn = document.createElement('button')\n clearBtn.type = 'button'\n clearBtn.title = input.getAttribute('data-clear-field-text') || 'Clear field'\n clearBtn.ariaLabel = input.getAttribute('data-clear-field-text') || 'Clear field'\n clearBtn.tabIndex = -1\n clearBtn.innerHTML = '<svg viewBox=\"0 0 16 16\" width=\"18\" height=\"18\"><path d=\"M 1 1 L 15 15 M 1 15 L 15 1\" fill=\"none\" stroke-width=\"2\" stroke=\"currentColor\" />'\n clearBtn.classList.add('clear')\n clearBtn.id = `semanticFormsClearButton_${input.id}`\n clearBtn.addEventListener('click', () => {\n input.previousValue = input.value\n input.value = ''\n input.focus()\n lastClearFieldPressed = input.id\n })\n insertAfter(clearBtn, dd.querySelector('label'))\n }\n input.addEventListener('focus', event => {\n if (event.target.nodeName === 'INPUT') lastFocusedInput = event.target\n })\n // #endregion\n\n // check for colspan- utility class\n if (/colspan-/.test(dd.className)) {\n const match = dd.className.match(/colspan-([0-9]|full)/)[0]\n dd.classList.remove(match)\n div.classList.add(match)\n }\n\n div.append(dt, dd)\n dl.append(div)\n\n // determine visibility of newly created <div>\n if (dt.style.display === 'none' && dd.style.display === 'none') div.style.display = 'none'\n }\n\n // handle file input clear btn, cannot be handled with CSS\n if (type === 'file') {\n const clearBtn = input.parentElement.querySelector('.clear')\n input.addEventListener('input', event => {\n clearBtn.style.display = event.target.files.length ? 'flex' : 'none'\n })\n clearBtn.addEventListener('click', () => {\n clearBtn.style.display = 'none'\n })\n }\n\n // handle range inputs with a class to display the value\n if (type === 'range' && input.classList.contains('displayValue')) {\n const label = input.parentNode.parentNode.querySelector('dd label')\n label.innerHTML += `<span class=\"seperator\">: </span><output>${input.value}</output>`\n input.addEventListener('input', event => {\n const output = event.target.parentNode.parentNode.querySelector('output')\n output.innerHTML = event.target.value\n })\n }\n\n // #region show password button\n if (type === 'password' && input.getAttribute('data-no-reveal') === null) {\n const showBtn = document.createElement('button')\n showBtn.type = 'button'\n showBtn.title = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.ariaLabel = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.tabIndex = -1\n showBtn.innerHTML = passwordShow\n showBtn.classList.add('show')\n showBtn.id = `semanticFormsShowButton_${input.id}`\n const dd = input.closest('dd')\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that is not inside a <dd> element.`)\n continue\n }\n showBtn.addEventListener('click', () => {\n if (input.type === 'password') {\n showBtn.innerHTML = passwordHide\n showBtn.title = input.getAttribute('data-hide-password-text') || 'Hide password'\n showBtn.ariaLabel = input.getAttribute('data-hide-password-text') || 'Hide password'\n input.type = 'text'\n } else {\n showBtn.innerHTML = passwordShow\n showBtn.title = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.ariaLabel = input.getAttribute('data-show-password-text') || 'Show password'\n input.type = 'password'\n }\n input.focus()\n })\n insertAfter(showBtn, dd.querySelector('label'))\n }\n // #endregion\n\n // add listener to shift clear button when scrollbar present\n for (const textarea of document.querySelectorAll('textarea')) {\n // shifts the close button to the right if a scrollbar is present\n const shiftCloseBtn = () => {\n const clearBtn = textarea.parentElement?.querySelector('button.clear')\n if (clearBtn) clearBtn.style.marginRight = textarea.clientHeight < textarea.scrollHeight ? '15px' : ''\n }\n\n textarea.addEventListener('input', shiftCloseBtn)\n textarea.addEventListener('mouseup', shiftCloseBtn)\n }\n }\n }\n }\n\n /**\n * Places an element immediately after another element\n * @param {Object} newNode element being placed after the reference node\n * @param {*} referenceNode element to be used as reference for new node\n */\n function insertAfter (newNode, referenceNode) {\n if (referenceNode.nextSibling) referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling)\n else referenceNode.parentNode.appendChild(newNode)\n }\n\n // handle undo/redo\n let lastFocusedInput\n let lastClearFieldPressed\n document.addEventListener('keydown', event => {\n if ((event.ctrlKey || event.metaKey) && event.key === 'z' && !event.shiftKey) {\n // undo clearing a field\n if (lastFocusedInput) {\n if (lastFocusedInput?.parentNode?.querySelector('button.clear').id === `semanticFormsClearButton_${lastClearFieldPressed}` || lastFocusedInput?.parentNode?.querySelector('button.clear').name === `semanticFormsClearButton_${lastClearFieldPressed}`) {\n if (lastFocusedInput.previousValue) {\n lastFocusedInput.redoValue = lastFocusedInput.value\n lastFocusedInput.value = lastFocusedInput.previousValue\n }\n }\n }\n } else if ((event.ctrlKey && event.key === 'y') || (event.metaKey && event.shiftKey && event.key === 'z')) {\n // redo clearing a field\n if (lastFocusedInput) {\n if (lastFocusedInput?.parentNode?.querySelector('button.clear').id === `semanticFormsClearButton_${lastClearFieldPressed}` || lastFocusedInput?.parentNode?.querySelector('button.clear').name === `semanticFormsClearButton_${lastClearFieldPressed}`) {\n if (lastFocusedInput.redoValue) {\n lastFocusedInput.previousValue = lastFocusedInput.value\n lastFocusedInput.value = lastFocusedInput.redoValue\n }\n }\n }\n }\n })\n\n // monitor changes to the DOM and enhance new semanticForms forms that get added\n if (!window.semanticFormsObserver) {\n window.semanticFormsObserver = new window.MutationObserver(mutations => {\n let stop = false\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (node.nodeName === 'FORM' || node?.querySelector?.('form')) {\n semanticForms()\n stop = true\n }\n }\n if (stop) break\n }\n })\n window.semanticFormsObserver.observe(document.body, { attributes: false, childList: true, characterData: false, subtree: true })\n }\n\n semanticForms.reinitialize = form => {\n form.classList.remove('semanticFormsActive')\n semanticForms()\n }\n}\n\nmodule.exports = semanticForms\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./semanticForms.js\");\n"],"names":["semanticForms","document","getElementsByClassName","querySelector","body","classList","window","MutationObserver","console","warn","passwordShow","passwordHide","helpTextIcon","nodeNameLookup","inputTypeLookup","forms","querySelectorAll","form","add","contains","inputs","Array","from","input","id","type","getAttribute","includes","nodeName","dl","parentNode","label","replace","error","dd","firstChild","newLabel","createElement","className","setAttribute","insertAfter","innerHTML","hasAttribute","text","append","parentElement","remove","div","closest","dt","clearBtn","title","ariaLabel","tabIndex","addEventListener","previousValue","value","focus","lastClearFieldPressed","event","target","lastFocusedInput","test","match","style","display","files","length","output","showBtn","textarea","shiftCloseBtn","marginRight","clientHeight","scrollHeight","newNode","referenceNode","nextSibling","insertBefore","appendChild","ctrlKey","metaKey","key","shiftKey","name","redoValue","semanticFormsObserver","mutations","stop","mutation","node","addedNodes","observe","attributes","childList","characterData","subtree","reinitialize","module","exports","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","__webpack_exports__"],"sourceRoot":""}
1
+ {"version":3,"file":"semantic-forms.mjs","mappings":"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","sources":["webpack://semantic-forms/./semanticForms.js","webpack://semantic-forms/webpack/bootstrap","webpack://semantic-forms/webpack/startup"],"sourcesContent":["const semanticForms = () => {\n // do some feature detection so none of the JS executes if the browser is too old\n if (typeof document.getElementsByClassName !== 'function' || typeof document.querySelector !== 'function' || !document.body.classList || !window.MutationObserver) {\n console.warn('semantic-forms was loaded into an unsupported browser and will not execute.')\n return\n }\n\n const passwordShow = '<svg fill=\"none\" height=\"256\" viewBox=\"0 0 24 24\" width=\"256\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m1 12s4-8 11-8 11 8 11 8\"/><path d=\"m1 12s4 8 11 8 11-8 11-8\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></g></svg>'\n const passwordHide = '<svg fill=\"none\" height=\"256\" viewBox=\"0 0 24 24\" width=\"256\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m2 2 20 20\"/><path d=\"m6.71277 6.7226c-3.04798 2.07267-4.71277 5.2774-4.71277 5.2774s3.63636 7 10 7c2.0503 0 3.8174-.7266 5.2711-1.7116m-6.2711-12.23018c.3254-.03809.6588-.05822 1-.05822 6.3636 0 10 7 10 7s-.6918 1.3317-2 2.8335\"/><path d=\"m14 14.2362c-.5308.475-1.2316.7639-2 .7639-1.6569 0-3-1.3431-3-3 0-.8237.33193-1.5698.86932-2.11192\"/></g></svg>'\n const helpTextIcon = '<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" style=\"overflow:visible;margin-top:1px;\"><rect width=\"16\" height=\"16\" fill=\"none\"/><path fill=\"currentColor\" d=\"M8,10.5c-0.552,0-1,0.448-1,1c0,0.552,0.448,1,1,1c0.552,0,1-0.448,1-1C9,10.948,8.552,10.5,8,10.5z M8,0 C3.582,0,0,3.582,0,8c0,4.418,3.582,8,8,8s8-3.582,8-8C16,3.582,12.418,0,8,0z M12.243,12.243C11.109,13.376,9.603,14,8,14 s-3.109-0.624-4.243-1.757C2.624,11.109,2,9.603,2,8s0.624-3.109,1.757-4.243C4.891,2.624,6.397,2,8,2s3.109,0.624,4.243,1.757 C13.376,4.891,14,6.397,14,8C14,9.603,13.376,11.109,12.243,12.243z M7.927,3.755c-2.248,0-2.76,1.695-2.802,2.906h1.571 c0.028-0.256,0.101-1.418,1.221-1.418c0.672,0,1.206,0.406,1.206,1.175c0,0.695-0.724,1.155-1.303,1.711 C7.241,8.685,7.168,9.325,7.168,9.824V10c0.146,0,1.615,0,1.615,0V9.824c0-1.256,1.967-1.594,1.967-3.541 C10.75,5.059,9.874,3.755,7.927,3.755z\"/></svg>'\n\n const nodeNameLookup = ['TEXTAREA', 'SELECT']\n const inputTypeLookup = ['checkbox', 'color', 'date', 'datetime-local', 'email', 'file', 'image', 'month', 'number', 'password', 'radio', 'range', 'search', 'tel', 'text', 'time', 'url', 'week']\n\n // progressively enhance form elements that have the semanticForms class\n const forms = document.querySelectorAll('form.semanticForms:not(.semanticFormsActive)')\n\n for (const form of forms) {\n form.classList.add('semanticFormsActive')\n if (form.classList.contains('lowFlow')) continue\n\n // update each input in the semantic form\n const inputs = Array.from(form.querySelectorAll('input, textarea, select'))\n for (const input of inputs) {\n // ignore input if it has previously been formatted\n if (input.classList.contains('semanticform') || !input.id) continue\n\n const type = input.getAttribute('type')\n if (nodeNameLookup.includes(input.nodeName) || inputTypeLookup.includes(type)) {\n // recursively find <dl> element\n let dl = input.parentNode\n while (dl && dl.nodeName !== 'DL') dl = dl.parentNode\n\n if (!dl) continue\n if (!dl.classList.contains('floatLabelForm')) dl.classList.add('floatLabelForm')\n\n const label = input.parentNode.parentNode.id && (type === 'checkbox' || type === 'radio')\n ? document.querySelector('label[data-for=' + input.parentNode.parentNode.id.replace(/\\./g, '\\\\.') + ']')\n : document.querySelector('label[for=' + input.id.replace(/\\./g, '\\\\.') + ']')\n\n if (!label) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) without a properly associated label. Make sure there is a label for it and the label has a matching \"for\" attribute.`)\n }\n\n input.classList.add('semanticform')\n\n // #region create labels\n\n if (type === 'checkbox' || type === 'radio') {\n // recursively find <dd> element\n let dd = input.parentNode\n while (dd && dd.nodeName !== 'DD') dd = dd.parentNode\n\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that is not inside a <dd> element.`)\n continue\n }\n\n if (dd.firstChild.nodeName !== 'LABEL') {\n const newLabel = document.createElement('label')\n newLabel.className = 'floatLabelFormAnimatedLabel'\n\n if (type === 'checkbox' && input.parentNode.nodeName === 'DD') {\n newLabel.setAttribute('for', input.id)\n input.parentNode.classList.add('singleCheckbox')\n newLabel.className = ''\n label.setAttribute('hidden', 'hidden')\n insertAfter(newLabel, input)\n }\n\n if (type === 'radio' && input.parentNode.nodeName === 'DD') {\n newLabel.setAttribute('for', input.id)\n input.parentNode.classList.add('singleRadio')\n newLabel.className = ''\n label.setAttribute('hidden', 'hidden')\n insertAfter(newLabel, input)\n }\n\n newLabel.innerHTML = label.innerHTML\n\n if (label.hasAttribute('title') && label.getAttribute('data-show-help-icon') !== null && !label.querySelector('span.help')) {\n const text = label.getAttribute('title')\n label.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n }\n\n if (dd.querySelector(':required') && label.getAttribute('data-no-asterisk') === null && !label.querySelector('span.required')) {\n const text = label.getAttribute('data-asterisk-text') || 'This field is required.'\n label.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n }\n\n if (!dd.querySelector('label')) dd.append(newLabel)\n }\n\n // removes old div that a radio or checkbox may have been added to\n if (dd.parentElement.nodeName === 'DIV') dd.parentElement.remove()\n\n const div = document.createElement('div')\n div.append(label.closest('dt'), dd)\n dl.append(div)\n } else {\n const newLabel = document.createElement('label')\n newLabel.setAttribute('for', input.id)\n newLabel.className = 'floatLabelFormAnimatedLabel'\n\n newLabel.innerHTML = label.innerHTML\n\n if (input.hasAttribute('title') && label.getAttribute('data-show-help-icon') !== null && !label.querySelector('span.help')) {\n const text = input.getAttribute('title')\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"help\">${helpTextIcon}</span>`\n }\n\n if (input.hasAttribute('required') && label.getAttribute('data-no-asterisk') === null && !label.querySelector('span.required')) {\n const text = label.getAttribute('data-asterisk-text') || 'This field is required.'\n newLabel.innerHTML += ` <span title=\"${text}\" class=\"required\">*</span>`\n }\n\n label.setAttribute('hidden', 'hidden')\n\n insertAfter(newLabel, input)\n }\n // #endregion\n\n // standard inputs\n if (type !== 'checkbox' && type !== 'radio') {\n if (!input.getAttribute('placeholder')) input.setAttribute('placeholder', ' ')\n\n const div = document.createElement('div')\n const dt = label.closest('dt')\n const dd = input.closest('dd')\n\n if (!dt) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that does not have a corresponding <dt> element.`)\n continue\n }\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that does not have a corresponding <dd> element.`)\n continue\n }\n\n // #region clear button\n if (input.nodeName !== 'SELECT' && type !== 'range') {\n const clearBtn = document.createElement('button')\n clearBtn.type = 'button'\n clearBtn.title = input.getAttribute('data-clear-field-text') || 'Clear field'\n clearBtn.ariaLabel = input.getAttribute('data-clear-field-text') || 'Clear field'\n clearBtn.tabIndex = -1\n clearBtn.innerHTML = '<svg viewBox=\"0 0 16 16\" width=\"18\" height=\"18\"><path d=\"M 1 1 L 15 15 M 1 15 L 15 1\" fill=\"none\" stroke-width=\"2\" stroke=\"currentColor\" />'\n clearBtn.classList.add('clear')\n clearBtn.id = `semanticFormsClearButton_${input.id}`\n clearBtn.addEventListener('click', () => {\n input.previousValue = input.value\n input.value = ''\n input.focus()\n lastClearFieldPressed = input.id\n\n // used for any other updates required by various inputs\n input.dispatchEvent(new Event('input', { bubbles: true }))\n })\n insertAfter(clearBtn, dd.querySelector('label'))\n }\n input.addEventListener('focus', event => {\n if (event.target.nodeName === 'INPUT') lastFocusedInput = event.target\n })\n // #endregion\n\n // check for colspan- utility class\n if (/colspan-/.test(dd.className)) {\n const match = dd.className.match(/colspan-([0-9]|full)/)[0]\n dd.classList.remove(match)\n div.classList.add(match)\n }\n\n div.append(dt, dd)\n dl.append(div)\n\n // determine visibility of newly created <div>\n if (dt.style.display === 'none' && dd.style.display === 'none') div.style.display = 'none'\n }\n\n // handle file input clear btn, cannot be handled with CSS\n if (type === 'file') {\n const clearBtn = input.parentElement.querySelector('.clear')\n input.addEventListener('input', event => {\n clearBtn.style.display = event.target.files.length ? 'flex' : 'none'\n })\n clearBtn.addEventListener('click', () => {\n clearBtn.style.display = 'none'\n })\n }\n\n // handle range inputs with a class to display the value\n if (type === 'range' && input.classList.contains('displayValue')) {\n const label = input.parentNode.parentNode.querySelector('dd label')\n label.innerHTML += `<span class=\"seperator\">: </span><output>${input.value}</output>`\n input.addEventListener('input', event => {\n const output = event.target.parentNode.parentNode.querySelector('output')\n output.innerHTML = event.target.value\n })\n }\n\n // #region show password button\n if (type === 'password' && input.getAttribute('data-no-reveal') === null) {\n const showBtn = document.createElement('button')\n showBtn.type = 'button'\n showBtn.title = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.ariaLabel = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.tabIndex = -1\n showBtn.innerHTML = passwordShow\n showBtn.classList.add('show')\n showBtn.id = `semanticFormsShowButton_${input.id}`\n const dd = input.closest('dd')\n if (!dd) {\n console.error(`semantic-forms: Found an input (${input.id || input.getAttribute('name')}) that is not inside a <dd> element.`)\n continue\n }\n showBtn.addEventListener('click', () => {\n if (input.type === 'password') {\n showBtn.innerHTML = passwordHide\n showBtn.title = input.getAttribute('data-hide-password-text') || 'Hide password'\n showBtn.ariaLabel = input.getAttribute('data-hide-password-text') || 'Hide password'\n input.type = 'text'\n } else {\n showBtn.innerHTML = passwordShow\n showBtn.title = input.getAttribute('data-show-password-text') || 'Show password'\n showBtn.ariaLabel = input.getAttribute('data-show-password-text') || 'Show password'\n input.type = 'password'\n }\n input.focus()\n })\n insertAfter(showBtn, dd.querySelector('label'))\n }\n // #endregion\n\n // add listener to shift clear button when scrollbar present\n if (input.nodeName === 'TEXTAREA') {\n if (input.getAttribute('data-disable-autosize') === null) {\n // add auto-sizing\n input.style.setProperty('resize', 'none')\n input.style.setProperty('min-height', '0')\n input.style.setProperty('max-height', 'none')\n input.style.setProperty('height', 'auto')\n \n const handleInput = () => {\n // reset rows attribute to get accurate scrollHeight\n let maxRows = input.getAttribute('data-max-rows')\n\n if (maxRows) {\n if (isNaN(maxRows) || Number(maxRows) <= 0) {\n console.warn(`An invalid value was passed to the \"data-max-rows\" attribute. This value will be ignored.\\n\\nProvided value: ${input.getAttribute('data-max-rows')}`, )\n maxRows = null\n }\n }\n\n const minRows = input.getAttribute('data-max-rows') && Number(input.getAttribute('data-max-rows')) < 5 ? input.getAttribute('data-max-rows') : '5'\n input.setAttribute('rows', minRows)\n \n // get the computed values object reference\n const style = window.getComputedStyle(input)\n \n // force content-box for size accurate line-height calculation, remove scrollbars, lock width (subtract inline padding and inline border widths), and remove inline padding and borders to keep width consistent (for text wrapping accuracy)\n const inlinePadding = parseFloat(style['padding-left']) + parseFloat(style['padding-right'])\n const inlineBorderWidth = parseFloat(style['border-left-width']) + parseFloat(style['border-right-width'])\n input.style.setProperty('overflow', 'hidden', 'important')\n input.style.setProperty('width', (parseFloat(style['width']) - inlinePadding - inlineBorderWidth) + 'px')\n input.style.setProperty('box-sizing', 'content-box')\n input.style.setProperty('padding-inline', '0')\n input.style.setProperty('border-width', '0')\n \n // get the base line height, and top / bottom padding\n const blockPadding = parseFloat(style['padding-top']) + parseFloat(style['padding-bottom'])\n const lineHeight = style['line-height'] === 'normal' \n ? parseFloat(style['height']) // if line-height is not explicitly set, use the computed height value (ignore padding due to content-box)\n : parseFloat(style['line-height']) // otherwise (line-height is explicitly set), use the computed line-height value\n \n // get the scroll height (rounding to be safe to ensure cross browser consistency)\n const scrollHeight = Math.round(input.scrollHeight)\n \n // undo overflow, width, border-width, box-sizing & inline padding overrides\n input.style.removeProperty('width')\n input.style.removeProperty('box-sizing')\n input.style.removeProperty('padding-inline')\n input.style.removeProperty('border-width')\n input.style.removeProperty('overflow')\n \n // subtract blockPadding from scrollHeight and divide that by our lineHeight to get the row count, round to nearest integer as it will always be within ~.1 of the correct whole number\n const rows = Math.round((scrollHeight - blockPadding) / lineHeight)\n \n // set the calculated rows attribute (limited by rowLimit)\n if (maxRows) {\n input.setAttribute(\"rows\", \"\" + Math.min(rows, Number(maxRows)))\n } else {\n input.setAttribute(\"rows\", \"\" + rows)\n }\n }\n \n input.addEventListener('input', handleInput)\n \n // trigger the event to set the initial rows value\n input.dispatchEvent(new Event('input', { bubbles: true }))\n }\n\n // shifts the clear button to the right if a scrollbar is present\n const shiftClearBtn = () => {\n const clearBtn = input.parentElement?.querySelector('button.clear')\n if (clearBtn) clearBtn.style.marginRight = input.clientHeight < input.scrollHeight ? '15px' : ''\n }\n input.addEventListener('input', shiftClearBtn)\n input.addEventListener('mouseup', shiftClearBtn)\n shiftClearBtn()\n }\n }\n }\n }\n\n /**\n * Places an element immediately after another element\n * @param {Object} newNode element being placed after the reference node\n * @param {*} referenceNode element to be used as reference for new node\n */\n function insertAfter (newNode, referenceNode) {\n if (referenceNode.nextSibling) referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling)\n else referenceNode.parentNode.appendChild(newNode)\n }\n\n // handle undo/redo\n let lastFocusedInput\n let lastClearFieldPressed\n document.addEventListener('keydown', event => {\n if ((event.ctrlKey || event.metaKey) && event.key === 'z' && !event.shiftKey) {\n // undo clearing a field\n if (lastFocusedInput) {\n if (lastFocusedInput?.parentNode?.querySelector('button.clear').id === `semanticFormsClearButton_${lastClearFieldPressed}` || lastFocusedInput?.parentNode?.querySelector('button.clear').name === `semanticFormsClearButton_${lastClearFieldPressed}`) {\n if (lastFocusedInput.previousValue) {\n lastFocusedInput.redoValue = lastFocusedInput.value\n lastFocusedInput.value = lastFocusedInput.previousValue\n }\n }\n }\n } else if ((event.ctrlKey && event.key === 'y') || (event.metaKey && event.shiftKey && event.key === 'z')) {\n // redo clearing a field\n if (lastFocusedInput) {\n if (lastFocusedInput?.parentNode?.querySelector('button.clear').id === `semanticFormsClearButton_${lastClearFieldPressed}` || lastFocusedInput?.parentNode?.querySelector('button.clear').name === `semanticFormsClearButton_${lastClearFieldPressed}`) {\n if (lastFocusedInput.redoValue) {\n lastFocusedInput.previousValue = lastFocusedInput.value\n lastFocusedInput.value = lastFocusedInput.redoValue\n }\n }\n }\n }\n })\n\n // monitor changes to the DOM and enhance new semanticForms forms that get added\n if (!window.semanticFormsObserver) {\n window.semanticFormsObserver = new window.MutationObserver(mutations => {\n let stop = false\n for (const mutation of mutations) {\n for (const node of mutation.addedNodes) {\n if (node.nodeName === 'FORM' || node?.querySelector?.('form')) {\n semanticForms()\n stop = true\n }\n }\n if (stop) break\n }\n })\n window.semanticFormsObserver.observe(document.body, { attributes: false, childList: true, characterData: false, subtree: true })\n }\n\n semanticForms.reinitialize = form => {\n form.classList.remove('semanticFormsActive')\n semanticForms()\n }\n}\n\nmodule.exports = semanticForms\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./semanticForms.js\");\n"],"names":["semanticForms","document","getElementsByClassName","querySelector","body","classList","window","MutationObserver","console","warn","passwordShow","passwordHide","helpTextIcon","nodeNameLookup","inputTypeLookup","forms","querySelectorAll","form","add","contains","inputs","Array","from","input","id","type","getAttribute","includes","nodeName","dl","parentNode","label","replace","error","dd","firstChild","newLabel","createElement","className","setAttribute","insertAfter","innerHTML","hasAttribute","text","append","parentElement","remove","div","closest","dt","clearBtn","title","ariaLabel","tabIndex","addEventListener","previousValue","value","focus","lastClearFieldPressed","dispatchEvent","Event","bubbles","event","target","lastFocusedInput","test","match","style","display","files","length","output","showBtn","setProperty","handleInput","maxRows","isNaN","Number","minRows","getComputedStyle","inlinePadding","parseFloat","inlineBorderWidth","blockPadding","lineHeight","scrollHeight","Math","round","removeProperty","rows","min","shiftClearBtn","marginRight","clientHeight","newNode","referenceNode","nextSibling","insertBefore","appendChild","ctrlKey","metaKey","key","shiftKey","name","redoValue","semanticFormsObserver","mutations","stop","mutation","node","addedNodes","observe","attributes","childList","characterData","subtree","reinitialize","module","exports","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","__webpack_exports__"],"sourceRoot":""}
@@ -23,7 +23,7 @@ function toggleDarkMode (mode) {
23
23
  document.querySelector('link[href="/css/highlight.js.light.css"]')?.remove()
24
24
  document.querySelector('head').insertAdjacentHTML('beforeend', '<link rel="stylesheet" href="/css/highlight.js.light.css">')
25
25
  document.querySelector('#mode button').innerHTML = 'Switch to dark mode'
26
- const forms = document.querySelectorAll('form')
26
+ const forms = document.querySelectorAll('.semanticForms')
27
27
  for (const form of forms) {
28
28
  form.classList.add('light')
29
29
  form.classList.remove('dark')
@@ -35,7 +35,7 @@ function toggleDarkMode (mode) {
35
35
  document.querySelector('link[href="/css/highlight.js.light.css"]')?.remove()
36
36
  document.querySelector('head').insertAdjacentHTML('beforeend', '<link rel="stylesheet" href="/css/highlight.js.dark.css">')
37
37
  document.querySelector('#mode button').innerHTML = 'Switch to light mode'
38
- const forms = document.querySelectorAll('form')
38
+ const forms = document.querySelectorAll('.semanticForms')
39
39
  for (const form of forms) {
40
40
  form.classList.add('dark')
41
41
  form.classList.remove('light')
@@ -82,8 +82,8 @@
82
82
  <dt><label for="url">URL field</label></dt>
83
83
  <dd><input id="url" name="url" type="url" placeholder="e.g. https://github.com"></dd>
84
84
 
85
- <dt><label for="search">Search field</label></dt>
86
- <dd><input id="search" name="search" type="search" placeholder="e.g. cats"></dd>
85
+ <dt><label for="search-field">Search field</label></dt>
86
+ <dd><input id="search-field" name="search-field" type="search" placeholder="e.g. cats"></dd>
87
87
 
88
88
  <dt><label for="search-no-float">No float label</label></dt>
89
89
  <dd><input id="search-no-float" name="search-no-float" type="search" placeholder="e.g. cats" class="no-float-label"></dd>
@@ -347,13 +347,25 @@
347
347
  <h3>Other</h3>
348
348
  <dl>
349
349
  <dt><label for="textarea">Textarea</label></dt>
350
- <dd><textarea id="textarea" name="textarea" rows="5" cols="50" placeholder="e.g. He just kept talking in one incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt it was really quite hypnotic."></textarea></dd>
350
+ <dd><textarea id="textarea" name="textarea" placeholder="e.g. He just kept talking in one incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt it was really quite hypnotic."></textarea></dd>
351
351
 
352
352
  <dt><label for="prefilledtextarea">Textarea (prefilled)</label></dt>
353
353
  <dd>
354
- <textarea id="prefilledtextarea" name="prefilledtextarea" rows="5" cols="50" placeholder="e.g. He just kept talking in one incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt it was really quite hypnotic.">Some prefilled content...</textarea>
354
+ <textarea id="prefilledtextarea" name="prefilledtextarea" placeholder="e.g. He just kept talking in one incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt it was really quite hypnotic.">Some prefilled content...</textarea>
355
355
  <label for="prefilledtextarea">Some help text regarding the textarea with some really long text that should overflow and wrap</label>
356
356
  </dd>
357
+
358
+ <dt><label for="textarea-max-rows">Textarea</label></dt>
359
+ <dd>
360
+ <textarea id="textarea-max-rows" name="textarea-max-rows" placeholder="e.g. He just kept talking in one incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt it was really quite hypnotic." data-max-rows="3">Row 1&#10;Row 2&#10;Row 3&#10;Row 4</textarea>
361
+ <label for="textarea-max-rows">This <code>textarea</code> has the <code>data-max-rows</code> set to 3, so the textarea will not expand past 3 rows.</label>
362
+ </dd>
363
+
364
+ <dt><label for="disable-autosize-textarea">Disabled autosize textarea</label></dt>
365
+ <dd>
366
+ <textarea name="disable-autosize-textarea" id="disable-autosize-textarea" rows="5" placeholder="e.g. He just kept talking in one incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt it was really quite hypnotic." data-disable-autosize>Row 1&#10;Row 2&#10;Row 3&#10;Row 4&#10;Row 5&#10;Row 6</textarea>
367
+ <label for="disable-autosize-textarea">This <code>textarea</code> element has the <code>data-disable-autosize</code> attribute applied, and has <code>rows</code> set to 5.</label>
368
+ </dd>
357
369
  </dl>
358
370
 
359
371
  <h3>Tables</h3>
@@ -411,7 +423,7 @@
411
423
  </table>
412
424
 
413
425
  <h4>Table using <code>colgroups</code> to define column width</h4>
414
- <table class="semanticForms">
426
+ <table>
415
427
  <colgroup>
416
428
  <col span="1" style="width: 20%">
417
429
  <col span="1" style="width: 50%">
@@ -1235,7 +1247,7 @@
1235
1247
  </main>
1236
1248
  <script>
1237
1249
  document.addEventListener('DOMContentLoaded', () => {
1238
- const forms = document.querySelectorAll('form')
1250
+ const forms = document.querySelectorAll('.semanticForms')
1239
1251
  for (const form of forms) {
1240
1252
  form.addEventListener('submit', e => e.preventDefault())
1241
1253
  }
@@ -78,6 +78,8 @@
78
78
  </dl>
79
79
  </form>
80
80
 
81
+ <p>Note: <code><!--#<textarea>--></code> elements autosize when you type in them. This can be disabled with <code>data-no-autosize</code> attribute. The row count can also be limited with the <code>data-max-rows</code> attribute.</p>
82
+
81
83
  <h5 id="addhelptext">Add help text</h5>
82
84
 
83
85
  <p>Include a label in the <code><!--#<dd>--></code> element with a matching <code>for</code> attribute to place help text beneath the input:</p>
@@ -126,16 +128,16 @@
126
128
  <pre><code class='language-html' lang='html'><escape>
127
129
  <form class="semanticForms">
128
130
  <dl>
129
- <dt><label for="search">Search</label></dt>
130
- <dd><input id="search" name="search" type="search" placeholder="e.g. cool stuff" class="no-float-label"></dd>
131
+ <dt><label for="search-field">Search</label></dt>
132
+ <dd><input id="search-field" name="search-field" type="search" placeholder="e.g. cool stuff" class="no-float-label"></dd>
131
133
  </dl>
132
134
  </form>
133
135
  </escape></code></pre>
134
136
 
135
137
  <form class="semanticForms">
136
138
  <dl>
137
- <dt><label for="search">Search</label></dt>
138
- <dd><input id="search" name="search" type="search" placeholder="e.g. cool stuff" class="no-float-label"></dd>
139
+ <dt><label for="search-field">Search</label></dt>
140
+ <dd><input id="search-field" name="search-field" type="search" placeholder="e.g. cool stuff" class="no-float-label"></dd>
139
141
  </dl>
140
142
  </form>
141
143
 
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "url": "https://github.com/rooseveltframework/semantic-forms/graphs/contributors"
9
9
  }
10
10
  ],
11
- "version": "5.1.5",
11
+ "version": "5.1.7",
12
12
  "files": [
13
13
  "dist",
14
14
  "semanticForms.scss",
package/semanticForms.js CHANGED
@@ -154,6 +154,9 @@ const semanticForms = () => {
154
154
  input.value = ''
155
155
  input.focus()
156
156
  lastClearFieldPressed = input.id
157
+
158
+ // used for any other updates required by various inputs
159
+ input.dispatchEvent(new Event('input', { bubbles: true }))
157
160
  })
158
161
  insertAfter(clearBtn, dd.querySelector('label'))
159
162
  }
@@ -231,15 +234,81 @@ const semanticForms = () => {
231
234
  // #endregion
232
235
 
233
236
  // add listener to shift clear button when scrollbar present
234
- for (const textarea of document.querySelectorAll('textarea')) {
235
- // shifts the close button to the right if a scrollbar is present
236
- const shiftCloseBtn = () => {
237
- const clearBtn = textarea.parentElement?.querySelector('button.clear')
238
- if (clearBtn) clearBtn.style.marginRight = textarea.clientHeight < textarea.scrollHeight ? '15px' : ''
237
+ if (input.nodeName === 'TEXTAREA') {
238
+ if (input.getAttribute('data-disable-autosize') === null) {
239
+ // add auto-sizing
240
+ input.style.setProperty('resize', 'none')
241
+ input.style.setProperty('min-height', '0')
242
+ input.style.setProperty('max-height', 'none')
243
+ input.style.setProperty('height', 'auto')
244
+
245
+ const handleInput = () => {
246
+ // reset rows attribute to get accurate scrollHeight
247
+ let maxRows = input.getAttribute('data-max-rows')
248
+
249
+ if (maxRows) {
250
+ if (isNaN(maxRows) || Number(maxRows) <= 0) {
251
+ console.warn(`An invalid value was passed to the "data-max-rows" attribute. This value will be ignored.\n\nProvided value: ${input.getAttribute('data-max-rows')}`, )
252
+ maxRows = null
253
+ }
254
+ }
255
+
256
+ const minRows = input.getAttribute('data-max-rows') && Number(input.getAttribute('data-max-rows')) < 5 ? input.getAttribute('data-max-rows') : '5'
257
+ input.setAttribute('rows', minRows)
258
+
259
+ // get the computed values object reference
260
+ const style = window.getComputedStyle(input)
261
+
262
+ // force content-box for size accurate line-height calculation, remove scrollbars, lock width (subtract inline padding and inline border widths), and remove inline padding and borders to keep width consistent (for text wrapping accuracy)
263
+ const inlinePadding = parseFloat(style['padding-left']) + parseFloat(style['padding-right'])
264
+ const inlineBorderWidth = parseFloat(style['border-left-width']) + parseFloat(style['border-right-width'])
265
+ input.style.setProperty('overflow', 'hidden', 'important')
266
+ input.style.setProperty('width', (parseFloat(style['width']) - inlinePadding - inlineBorderWidth) + 'px')
267
+ input.style.setProperty('box-sizing', 'content-box')
268
+ input.style.setProperty('padding-inline', '0')
269
+ input.style.setProperty('border-width', '0')
270
+
271
+ // get the base line height, and top / bottom padding
272
+ const blockPadding = parseFloat(style['padding-top']) + parseFloat(style['padding-bottom'])
273
+ const lineHeight = style['line-height'] === 'normal'
274
+ ? parseFloat(style['height']) // if line-height is not explicitly set, use the computed height value (ignore padding due to content-box)
275
+ : parseFloat(style['line-height']) // otherwise (line-height is explicitly set), use the computed line-height value
276
+
277
+ // get the scroll height (rounding to be safe to ensure cross browser consistency)
278
+ const scrollHeight = Math.round(input.scrollHeight)
279
+
280
+ // undo overflow, width, border-width, box-sizing & inline padding overrides
281
+ input.style.removeProperty('width')
282
+ input.style.removeProperty('box-sizing')
283
+ input.style.removeProperty('padding-inline')
284
+ input.style.removeProperty('border-width')
285
+ input.style.removeProperty('overflow')
286
+
287
+ // subtract blockPadding from scrollHeight and divide that by our lineHeight to get the row count, round to nearest integer as it will always be within ~.1 of the correct whole number
288
+ const rows = Math.round((scrollHeight - blockPadding) / lineHeight)
289
+
290
+ // set the calculated rows attribute (limited by rowLimit)
291
+ if (maxRows) {
292
+ input.setAttribute("rows", "" + Math.min(rows, Number(maxRows)))
293
+ } else {
294
+ input.setAttribute("rows", "" + rows)
295
+ }
296
+ }
297
+
298
+ input.addEventListener('input', handleInput)
299
+
300
+ // trigger the event to set the initial rows value
301
+ input.dispatchEvent(new Event('input', { bubbles: true }))
239
302
  }
240
303
 
241
- textarea.addEventListener('input', shiftCloseBtn)
242
- textarea.addEventListener('mouseup', shiftCloseBtn)
304
+ // shifts the clear button to the right if a scrollbar is present
305
+ const shiftClearBtn = () => {
306
+ const clearBtn = input.parentElement?.querySelector('button.clear')
307
+ if (clearBtn) clearBtn.style.marginRight = input.clientHeight < input.scrollHeight ? '15px' : ''
308
+ }
309
+ input.addEventListener('input', shiftClearBtn)
310
+ input.addEventListener('mouseup', shiftClearBtn)
311
+ shiftClearBtn()
243
312
  }
244
313
  }
245
314
  }