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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4,21 +4,19 @@
} }
.dbform .inputwrapper { .dbform .inputwrapper {
@apply rounded-xs border-2 border-transparent @apply rounded-xs transition-all duration-100 border-stone-300 border bg-white;
border-l-2 focus-within:border-l-slate-600
bg-stone-100 focus-within:bg-slate-100 transition-all duration-100;
} }
.dbform .inputwrapper .inputlabel { .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 { .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 { .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 { .dbform .inputwrapper textarea {

View File

@@ -258,6 +258,40 @@ document.addEventListener("htmx:afterSwap", (event) => {
setupCancelLinks(root); 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 // Simple textarea auto-resize function
function TextareaAutoResize(textarea) { function TextareaAutoResize(textarea) {
console.log("TextareaAutoResize called for:", textarea.name || textarea.id); console.log("TextareaAutoResize called for:", textarea.name || textarea.id);
@@ -284,7 +318,13 @@ function TextareaAutoResize(textarea) {
// Special case: annotation textarea has 2 rows minimum // Special case: annotation textarea has 2 rows minimum
const isAnnotation = textarea.name === "annotation"; 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 // For empty textareas, set minimum height
if (textarea.value.trim() === "") { if (textarea.value.trim() === "") {
@@ -298,7 +338,8 @@ function TextareaAutoResize(textarea) {
// Set to content height (scrollHeight is the actual content height) // Set to content height (scrollHeight is the actual content height)
const contentHeight = textarea.scrollHeight; 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); console.log("Setting height to:", newHeight);
textarea.style.height = newHeight; textarea.style.height = newHeight;
} }