fix: variable values take Enter as a new line; the box is one line until clicked, then shows all of it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-10-06 23:47:03 +03:00
co-authored by Claude Opus 5.5
parent 06ac0afb03
commit 429445126e
3 changed files with 13 additions and 5 deletions
+2
View File
@@ -31,6 +31,8 @@
resize: vertical; min-height: var(--ctl-h-xl);
}
.cx-autogrow { resize: none; overflow: hidden; }
.cx-fold { min-height: var(--ctl-h-md); height: var(--ctl-h-md); padding: var(--sp-2) var(--ctl-pad-x-sm); font-size: var(--fs-5); }
.cx-fold:not(:focus) { padding-block: 0; line-height: calc(var(--ctl-h-md) - 2px); } /* folded: the first line centred, the rest fully out of sight */
.cx-search { appearance: none; }
.cx-search::-webkit-search-cancel-button { filter: grayscale(1) opacity(.6); }
+10 -4
View File
@@ -138,21 +138,27 @@ define("stepper", "md", ({ value = 0, min, max, step = 1, onChange, label } = {}
return { node, get value() { return current; }, setValue: set, destroy: () => node.remove() };
});
define("textarea", "md", ({ value = "", rows = 4, autoGrow = false, placeholder, onInput, onCommit, label } = {}) => {
// `fold`: one line like an input until clicked, then as tall as its text (Enter is a new line); one line again on leaving.
define("textarea", "md", ({ value = "", rows = 4, autoGrow = false, fold = false, placeholder, onInput, onCommit, label } = {}) => {
const node = el("textarea", {
cls: ["cx-textarea", "cx-focusable", autoGrow ? "cx-autogrow" : null],
attrs: { rows, placeholder, "aria-label": label },
cls: ["cx-textarea", "cx-focusable", autoGrow || fold ? "cx-autogrow" : null, fold ? "cx-fold" : null],
attrs: { rows: fold ? 1 : rows, placeholder, "aria-label": label },
});
node.value = value;
const grow = () => { node.style.height = "auto"; node.style.height = `${node.scrollHeight}px`; };
if (autoGrow) { node.addEventListener("input", grow); queueMicrotask(grow); }
if (fold) {
node.addEventListener("focus", grow);
node.addEventListener("input", grow);
node.addEventListener("blur", () => { node.style.height = ""; node.scrollTop = 0; });
}
wire(node, { onInput, onCommit });
return {
node,
get value() { return node.value; },
setValue(v) { node.value = v ?? ""; if (autoGrow) grow(); },
setValue(v) { node.value = v ?? ""; if (autoGrow || (fold && document.activeElement === node)) grow(); },
destroy: () => node.remove(),
};
});
+1 -1
View File
@@ -71,7 +71,7 @@ export function variablesPanel(app, own) {
const draw = () => { shown = JSON.stringify([p.project && p.project.id, rows()]); page.set([
...rows().map((v, i) => c.toolbar.default({
items: [c.input.sm({ label: "Name", value: v.name, placeholder: "name", onCommit: (x) => { const l = clone(rows()); l[i].name = x; write(l); } }),
c.input.sm({ label: "Value", value: v.value, placeholder: "text", onCommit: (x) => { const l = clone(rows()); l[i].value = x; write(l); } })],
c.textarea.md({ fold: true, label: "Value", value: v.value, placeholder: "text", onCommit: (x) => { const l = clone(rows()); l[i].value = x; write(l); } })],
trailing: [c.button.sm({ label: "✕", tone: "ghost", title: "Remove", onClick: () => { write(rows().filter((_, k) => k !== i)); draw(); } })] })),
c.button.sm({ label: "+ Add variable", tone: "ghost", disabled: !p.project, onClick: () => { write([...rows(), { name: "name", value: "" }]); draw(); } }),
c.hint.default({ text: "Write $name in a prompt; it becomes the variable's text when you generate." }),