Profile bio textarea: auto-grow to fit content (caret in view, bounded max height) #419
Labels
No labels
actions
bug
cli
duplicate
enhancement
fork
forum
git storage
help wanted
insights
invalid
issues
moderation
oidc
ownership transfer
packages
pr/merge protection rules
projects
pull requests
question
releases
sponsorships
tags
webhooks
wiki
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
crueber/walhub#419
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Profile bio textarea: auto-grow to fit content
What's requested
The markdown bio textarea on the owner profile edit form is a fixed
rows="6"box: typing or pasting more than ~6 lines forces an inner scrollbar instead of the field growing to show the content, and the caret can scroll out of view exactly when the user is typing. Requested behavior:rows="6"height.max-heightaround 50vh withoverflow-y: autobeyond it); exact cap is implementer's choice, but it must be stated in the implementation.Evidence
web/src/pages/Repos.jsx,ProfileForm—<textarea id="profile-bio" class="input w-full font-mono text-sm" rows="6" …>(around line 172). Fixed rows, no grow logic.web/src/pages/Org.jsx:216(rows="5").Architecture notes
grep -rn 'auto-resize\|autogrow\|field-sizing' web/is empty).web/src/lib/(seesettingsNav,attachUpload) — a smallweb/src/lib/autogrow.js(e.g.grow(textarea, { minRows, maxRows })usingscrollHeight, exported for unit tests) fits; a pure-CSSfield-sizing: contentroute is acceptable only if the fallback story for non-supporting browsers is noted. Implementer's call; one shared helper consumed by both textareas, not per-page copies.Scope
Repos.jsx) and the org profile bio textarea (Org.jsx) — same component shape, same fix. No other textareas change in this ticket.repos.owners.updateProfile,profileSaveBody) is untouched.Acceptance criteria
rows="6".Fixed by PR #425 (#425) — shared web/src/lib/autogrow.js consumed by both bio textareas, cap exactly 50vh, 18 new headless tests green, vite build clean, no backend change.
REVIEW PR #425 (fix/issue-419, bio autogrow) — verified in scratch worktree, all 8 checks pass. No browser per task scope (node tests + reasoning; no browser-facing serving change — static textarea wiring only).
(1) Shared helper, both textareas: PASS. web/src/lib/autogrow.js (new, 136 lines) imported by both web/src/pages/Repos.jsx:35 and web/src/pages/Org.jsx:16; wiring identical (ref→initAutogrow, onInput→setBio+growTextarea, createEffect→getBio+growTextarea). No per-page copies. Each page has exactly one <textarea (the bio one) — no other textareas touched.
(2) Grow+shrink: PASS. growTextarea sets height:auto BEFORE reading scrollHeight (autogrow.js:112) — the classic no-shrink bug avoided; floor recorded from mounted rows height via initAutogrow offsetHeight/clientHeight (autogrow.js:74-88); rows=6/5 stay as no-JS fallback.
(3) Caret in view: PASS, sound. While fitted the box IS the content (overflow hidden, no inner scroll — caret necessarily visible); past the cap only the trailing-caret case is pinned (scrollTop=scrollHeight, autogrow.js:123-129), mid-text carets correctly left to native scroll.
(4) Cap exact 50vh + overflow auto: PASS, stated. AUTOGROW_MAX_VH=50 (autogrow.js:30), stated in header comment + PR body; overflowY auto iff overflowing, hidden while fitted (no flicker).
(5) Seeded/programmatic refit: PASS. Both pages have createEffect tracking getBio + bioRef guard (covers mount + async Org seedAll); onInput covers keystrokes/paste; refit idempotent so double-fire harmless. Org ProfileTab mounts only under Show when={getTab()==="Profile"} (Org.jsx:785), so the floor is measured while visible, not against a hidden tab.
(6) DOM/pure separation: PASS. Pure autogrowMaxPx/clampAutogrowHeight headless-tested; DOM initAutogrow/growTextarea run against stub elements in node --test — matches attachUpload/settingsNav convention.
(7) Scope/hygiene: PASS. 4 files only (autogrow.js, Repos.jsx, Org.jsx, autogrow.test.js); no backend change; no package/manifest change — law 1 (dependency budget) holds.
(8) Law-12 no-doc call: REASONABLE. No doc pins textarea sizing, so code/docs do not disagree; bio_markdown write path untouched.
VERIFY (scratch worktree /tmp/pr425 @
0d7200b, since removed): autogrow.test.js 18/18 pass; full suite 867 tests → 865 pass / 2 fail, and the 2 fails are smoke.test.js live-server probes which fail identically on clean main (re-ran smoke.test.js on main: 1 pass / 2 fail) — pre-existing, unrelated. vite build clean in 2.46s (only pre-existing >500kB chunk-size warning). Org.jsx already imports createEffect (line 6) — no missing-import bug. No fixes needed; nothing pushed.MERGE RECOMMENDATION: ready to merge.
Fixed by PR #425 (review clean — all 8 checks pass, shared helper, 50vh cap, both textareas), merged. Closing.