Make the action input auto-grow up to ~4 lines
Swap the single-line action <input> for a <textarea> that grows with its content (capped at ~4 lines, then scrolls) and shrinks back after send. Enter still sends; Shift+Enter inserts a newline. Buttons stay bottom-aligned as it grows. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TEpWMjnfPqzZ13nPMoGhs5
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8a1650c0d4
commit
92044a53c4
+10
-1
@@ -392,8 +392,17 @@ button:disabled { opacity: 0.45; cursor: default; transform: none; box-shadow: n
|
||||
.turn-buttons button { font-size: 0.78rem; padding: 4px 12px; color: var(--text-dim); }
|
||||
.turn-buttons button:hover:not(:disabled) { color: var(--text); }
|
||||
|
||||
.input-bar { display: flex; gap: 8px; align-items: stretch; }
|
||||
.input-bar { display: flex; gap: 8px; align-items: flex-end; }
|
||||
.input-bar input { flex: 1; }
|
||||
/* Auto-growing action box: starts at one line, grows to ~4, then scrolls. */
|
||||
.input-bar textarea {
|
||||
flex: 1;
|
||||
resize: none;
|
||||
min-height: 0;
|
||||
max-height: calc(6em + 20px); /* ~4 lines (1.5em each) + padding/border */
|
||||
overflow-y: auto;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.mode-select { display: flex; }
|
||||
.mode-select button {
|
||||
|
||||
@@ -612,6 +612,16 @@ export default function Play() {
|
||||
const storyEndRef = useRef(null)
|
||||
const abortRef = useRef(null)
|
||||
const pinnedRef = useRef(true) // autoscroll only while the reader is at the bottom
|
||||
const inputRef = useRef(null)
|
||||
|
||||
// Grow the action box with its content (CSS caps it at ~4 lines, then
|
||||
// scrolls); shrinks back after send() clears the text.
|
||||
useEffect(() => {
|
||||
const el = inputRef.current
|
||||
if (!el) return
|
||||
el.style.height = 'auto'
|
||||
el.style.height = `${el.scrollHeight}px`
|
||||
}, [input])
|
||||
|
||||
useEffect(() => {
|
||||
api.getAdventure(id)
|
||||
@@ -863,8 +873,9 @@ export default function Play() {
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
<textarea
|
||||
ref={inputRef}
|
||||
rows={1}
|
||||
value={input}
|
||||
disabled={busy}
|
||||
placeholder={
|
||||
@@ -873,7 +884,10 @@ export default function Play() {
|
||||
: 'What happens next?'
|
||||
}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter' && !busy) send() }}
|
||||
// Enter sends; Shift+Enter inserts a newline.
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey && !busy) { e.preventDefault(); send() }
|
||||
}}
|
||||
/>
|
||||
{busy ? (
|
||||
<button className="danger" onClick={stopGeneration}>■ Stop</button>
|
||||
|
||||
Reference in New Issue
Block a user