Size the action editor to its content; widen both composers on mobile

Editing a beat opened a fixed 110px box. Player actions are one line, but AI
beats are several paragraphs, so editing one meant working through a keyhole.
New AutoTextarea sizes to its content on mount and on every change; CSS keeps a
110px floor so a short player action doesn't collapse, and a 65vh ceiling that
scrolls internally so Save/Cancel can't be pushed off the screen.

On phones both composers are one flex row, which left almost nothing to type
into: measured at a 390px composer, the Play textarea got 138px (Do/Say/Story
eat ~180px, Send ~75px) and the chat textarea 310px. Both now wrap, with the
buttons on their own line and the textarea taking the full 390px — Play keeps
Do/Say/Story and Send together on the top row, chat drops Send beneath. Play
stays two rows, so nothing gets taller. Desktop is unchanged; every rule is
inside the existing max-width:720px block.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FGY1yvzSeKgTtRfeVtDmx
This commit is contained in:
parththakkar106
2026-07-26 20:54:52 +05:30
co-authored by Claude Opus 5
parent 49e2dde5cf
commit a170f5aed5
3 changed files with 55 additions and 6 deletions
+19
View File
@@ -281,6 +281,25 @@ export function AuthModal({ mode: initialMode, onClose, onAuthed }) {
)
}
/** A textarea that grows to fit its content instead of sitting at a fixed
height. Editing an AI beat means editing a few paragraphs, and a fixed box
made that a keyhole. CSS min/max-height still bound it (the cap scrolls),
so callers control the floor and ceiling from the stylesheet. */
export function AutoTextarea({ value, ...props }) {
const ref = useRef(null)
useEffect(() => {
const el = ref.current
if (!el) return
// Reset first: scrollHeight only ever grows while an explicit height is set,
// so without this the box could never shrink back down.
el.style.height = 'auto'
el.style.height = `${el.scrollHeight}px`
}, [value])
return <textarea ref={ref} value={value} {...props} />
}
export function Field({ label, value, onChange, textarea, rows, placeholder }) {
return (
<label className="field">