FN-5706: hide chat input overflow until max-height
Prevent the chat composer from showing a right-edge scrollbar line before it reaches the autosize cap. - set chat textarea default overflow to hidden in ChatView CSS - add resolveChatInputOverflowY to switch overflow to auto only past the 640px cap - apply overflow mode during composer autosize updates - extend chat input autosize tests and docs to cover overflow behavior Files changed: docs/dashboard-guide.md | 2 +- packages/dashboard/app/components/ChatView.css | 1 + packages/dashboard/app/components/ChatView.tsx | 5 +++++ packages/dashboard/app/components/__tests__/ChatView.chat-input-autosize.test.tsx | 9 ++++++++- 4 files changed, 15 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-5706 Fusion-Task-Lineage: 4619aa30-c02f-453b-bdf2-f60f360e9372
This commit is contained in:
@@ -1078,7 +1078,7 @@ const baseOnly = await loadAllAppCssBaseOnly(); // strips @media/@supports
|
||||
### File browser editor & autosize textarea
|
||||
|
||||
- `FileEditor.tsx` is CodeMirror 6-only (no `<textarea>` fallback). Language resolution: `packages/dashboard/app/utils/codemirror-language.ts`.
|
||||
- For chat-style composer fields use `packages/dashboard/app/hooks/useAutosizeTextarea.ts`. Pattern: `height = "auto"` then clamp `scrollHeight` to min/max in `useLayoutEffect`. Pair with `resize: none` and `overflow-y: auto`.
|
||||
- For chat-style composer fields use `packages/dashboard/app/hooks/useAutosizeTextarea.ts`. Pattern: `height = "auto"` then clamp `scrollHeight` to min/max in `useLayoutEffect`. Pair with `resize: none`; keep `overflow-y: hidden` while under the max-height cap and switch to `overflow-y: auto` only after content exceeds the cap.
|
||||
|
||||
### File-path links
|
||||
|
||||
|
||||
@@ -1422,6 +1422,7 @@
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
resize: none;
|
||||
overflow-y: hidden;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 10px 14px;
|
||||
|
||||
@@ -59,6 +59,10 @@ export interface ChatViewProps {
|
||||
const CHAT_INPUT_MAX_HEIGHT_PX = 640;
|
||||
let chatViewWasPreviouslyInactive = false;
|
||||
|
||||
export function resolveChatInputOverflowY(scrollHeight: number): "auto" | "hidden" {
|
||||
return scrollHeight > CHAT_INPUT_MAX_HEIGHT_PX ? "auto" : "hidden";
|
||||
}
|
||||
|
||||
export function clampChatInputHeight(scrollHeight: number): number {
|
||||
// Floor matches QuickChat (clampQuickChatInputHeight) and the CSS min-height,
|
||||
// so a 0-scrollHeight measurement (e.g. before layout) still yields a
|
||||
@@ -1770,6 +1774,7 @@ export function ChatView({ projectId, addToast, experimentalFeatures }: ChatView
|
||||
|
||||
composer.style.height = "auto";
|
||||
composer.style.height = `${clampChatInputHeight(composer.scrollHeight)}px`;
|
||||
composer.style.overflowY = resolveChatInputOverflowY(composer.scrollHeight);
|
||||
}, []);
|
||||
|
||||
const handleComposerRef = useCallback((textarea: HTMLTextAreaElement | null) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { clampChatInputHeight } from "../ChatView";
|
||||
import { clampChatInputHeight, resolveChatInputOverflowY } from "../ChatView";
|
||||
|
||||
const chatViewCss = readFileSync(resolve(__dirname, "../ChatView.css"), "utf8");
|
||||
|
||||
@@ -12,6 +12,7 @@ describe("ChatView chat input autosize", () => {
|
||||
expect(textareaRule).not.toBeNull();
|
||||
expect(textareaRule?.[0]).toContain("max-height: 640px");
|
||||
expect(textareaRule?.[0]).toContain("flex: 0 0 auto");
|
||||
expect(textareaRule?.[0]).toContain("overflow-y: hidden");
|
||||
});
|
||||
|
||||
it("clamps oversized textarea growth to the new max height", () => {
|
||||
@@ -23,4 +24,10 @@ describe("ChatView chat input autosize", () => {
|
||||
it("preserves smaller textarea heights below the cap", () => {
|
||||
expect(clampChatInputHeight(80)).toBe(80);
|
||||
});
|
||||
|
||||
it("keeps overflow hidden until content exceeds the max height cap", () => {
|
||||
expect(resolveChatInputOverflowY(80)).toBe("hidden");
|
||||
expect(resolveChatInputOverflowY(640)).toBe("hidden");
|
||||
expect(resolveChatInputOverflowY(641)).toBe("auto");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user