fix(entries): size the multiline field from its content instead of a fixed height

A manual resize was lost on reopen: the row is rebuilt on every open, and remembering the height would not survive a restart either since localStorage is wiped when the ephemeral port changes the origin. Deriving it from the content removes the state entirely - the field is always the right size.
This commit is contained in:
r-zakarya
2026-07-31 18:31:26 +01:00
parent 2cab20eb76
commit 9dc9f625d6
3 changed files with 18 additions and 3 deletions
+15 -1
View File
@@ -4161,6 +4161,12 @@ function soCustomFieldsField() {
return wrap;
}
// Grow a textarea to fit its content, up to a cap past which it scrolls.
function autoSizeTextarea(ta, maxPx = 320) {
ta.style.height = 'auto';
ta.style.height = Math.min(ta.scrollHeight, maxPx) + 'px';
}
function buildCustomFieldRow(field, idx, rerender) {
const row = el('div', { class: 'so-custom-row' });
const labelInput = el('input', {
@@ -4189,10 +4195,18 @@ function buildCustomFieldRow(field, idx, rerender) {
if (field.multiline) {
valueInput = el('textarea', {
class: 'so-input so-custom-value so-custom-multiline',
rows: 5, placeholder: 'Value',
rows: 3, placeholder: 'Value',
autocomplete: 'off', autocorrect: 'off', spellcheck: 'false',
});
valueInput.classList.toggle('is-masked', !!field.is_secret);
// Height follows the content instead of being remembered: a manual
// resize would be lost anyway (re-rendered on every open, and
// localStorage is wiped each launch when the port changes).
const grow = () => autoSizeTextarea(valueInput);
valueInput.addEventListener('input', grow);
// scrollHeight reads 0 until the element is in the DOM — same
// render-time vs DOM-attachment trap as renderSoChips (CLAUDE.md).
setTimeout(grow, 0);
} else {
valueInput = el('input', {
type: field.is_secret ? 'password' : 'text',