FIX: better calc of min height of textarea

This commit is contained in:
Simon Martens
2026-02-04 12:34:03 +01:00
parent a70cdd6488
commit 822441e8ce
4 changed files with 2032 additions and 2031 deletions

View File

@@ -4,21 +4,19 @@
}
.dbform .inputwrapper {
@apply rounded-xs border-2 border-transparent
border-l-2 focus-within:border-l-slate-600
bg-stone-100 focus-within:bg-slate-100 transition-all duration-100;
@apply rounded-xs transition-all duration-100 border-stone-300 border bg-white;
}
.dbform .inputwrapper .inputlabel {
@apply pl-3 pr-0 text-gray-800 font-bold py-1;
@apply pl-2 pr-0 text-gray-800 font-bold py-0.5;
}
.dbform .inputwrapper .inputinput {
@apply block w-full focus:border-none focus:outline-none px-3 py-1;
@apply block w-full focus:border-none focus:outline-none px-2 py-0.5;
}
.dbform .inputwrapper .inputtextarea {
@apply block w-full focus:border-none focus:outline-none resize-y px-3 py-1;
@apply block w-full focus:border-none focus:outline-none resize-y px-2 py-0.5;
}
.dbform .inputwrapper textarea {

View File

@@ -258,6 +258,40 @@ document.addEventListener("htmx:afterSwap", (event) => {
setupCancelLinks(root);
});
function resolveLineHeightPx(textarea, computed) {
const lineHeight = computed.lineHeight;
if (lineHeight && lineHeight !== "normal") {
const parsed = parseFloat(lineHeight);
if (!Number.isNaN(parsed)) {
return parsed;
}
}
const fontSize = parseFloat(computed.fontSize) || 16;
if (!document.body) {
return fontSize * 1.2;
}
const probe = document.createElement("span");
probe.textContent = "M";
probe.style.position = "absolute";
probe.style.visibility = "hidden";
probe.style.whiteSpace = "pre";
probe.style.padding = "0";
probe.style.margin = "0";
probe.style.border = "0";
probe.style.fontFamily = computed.fontFamily;
probe.style.fontSize = computed.fontSize;
probe.style.fontWeight = computed.fontWeight;
probe.style.fontStyle = computed.fontStyle;
probe.style.letterSpacing = computed.letterSpacing;
probe.style.lineHeight = "normal";
document.body.appendChild(probe);
const height = probe.getBoundingClientRect().height;
probe.remove();
return height || fontSize * 1.2;
}
// Simple textarea auto-resize function
function TextareaAutoResize(textarea) {
console.log("TextareaAutoResize called for:", textarea.name || textarea.id);
@@ -284,7 +318,13 @@ function TextareaAutoResize(textarea) {
// Special case: annotation textarea has 2 rows minimum
const isAnnotation = textarea.name === "annotation";
const minHeight = isAnnotation ? 76 : 38; // 2 rows vs 1 row
const computed = getComputedStyle(textarea);
const rows = isAnnotation ? 2 : 1;
const lineHeight = resolveLineHeightPx(textarea, computed);
const paddingY = parseFloat(computed.paddingTop) + parseFloat(computed.paddingBottom);
const borderY = parseFloat(computed.borderTopWidth) + parseFloat(computed.borderBottomWidth);
const minContentHeight = lineHeight * rows + paddingY;
const minHeight = computed.boxSizing === "border-box" ? minContentHeight + borderY : minContentHeight;
// For empty textareas, set minimum height
if (textarea.value.trim() === "") {
@@ -298,7 +338,8 @@ function TextareaAutoResize(textarea) {
// Set to content height (scrollHeight is the actual content height)
const contentHeight = textarea.scrollHeight;
const newHeight = Math.max(contentHeight, minHeight) + "px";
const contentHeightWithBox = computed.boxSizing === "border-box" ? contentHeight + borderY : contentHeight;
const newHeight = Math.max(contentHeightWithBox, minHeight) + "px";
console.log("Setting height to:", newHeight);
textarea.style.height = newHeight;
}