Skip to content

I’ve fixed a text overflow issue in the AI-generated messages.#313

Merged
ngoiyaeric merged 2 commits intomainfrom
fix-text-overflow
Oct 3, 2025
Merged

I’ve fixed a text overflow issue in the AI-generated messages.#313
ngoiyaeric merged 2 commits intomainfrom
fix-text-overflow

Conversation

@ngoiyaeric
Copy link
Collaborator

@ngoiyaeric ngoiyaeric commented Oct 3, 2025

User description

The component that renders my responses was missing the necessary styling to handle long, unbroken strings of text. This caused text to overflow its container, negatively impacting the user interface.

I’ve resolved the issue by adding the break-words CSS class to the MemoizedReactMarkdown component in components/message.tsx. This ensures that long strings of text will wrap correctly, preventing overflow and improving the overall user experience.

Additionally, I added an aria-label to the submit button in components/chat-panel.tsx to improve accessibility.


PR Type

Bug fix, Enhancement


Description

  • Fix text overflow in AI messages with break-words CSS

  • Add accessibility label to submit button


Diagram Walkthrough

flowchart LR
  A["Text Overflow Issue"] --> B["Add break-words CSS"]
  C["Submit Button"] --> D["Add aria-label"]
  B --> E["Fixed UI Layout"]
  D --> F["Better Accessibility"]
Loading

File Walkthrough

Relevant files
Bug fix
message.tsx
Fix text overflow with break-words styling                             

components/message.tsx

  • Added break-words CSS class to MemoizedReactMarkdown component
  • Prevents text overflow in AI-generated messages
+1/-1     
Enhancement
chat-panel.tsx
Add accessibility label to submit button                                 

components/chat-panel.tsx

  • Added aria-label="Send message" to submit button
  • Improves accessibility for screen readers
+1/-0     

Summary by CodeRabbit

  • New Features

    • Added an accessible aria-label “Send message” to the chat input’s submit button, improving screen reader support.
    • Form submissions now treat a related query field as an alternative input source, allowing alternate/related inputs to be submitted when present.
  • Style

    • Enabled word wrapping in message content to prevent overflow and improve readability for long words and URLs.

The component that renders my responses was missing the necessary styling to handle long, unbroken strings of text. This caused text to overflow its container, negatively impacting the user interface.

I’ve resolved the issue by adding the `break-words` CSS class to the `MemoizedReactMarkdown` component in `components/message.tsx`. This ensures that long strings of text will wrap correctly, preventing overflow and improving the overall user experience.

Additionally, I added an `aria-label` to the submit button in `components/chat-panel.tsx` to improve accessibility.
@charliecreates charliecreates bot requested a review from CharlieHelps October 3, 2025 06:33
@vercel
Copy link
Contributor

vercel bot commented Oct 3, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
qcx Ready Ready Preview Comment Oct 3, 2025 7:11am

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

Walkthrough

Prefer related_query over input when skip is false during form submissions; add an accessibility aria-label to the chat send button and enable word-breaking for rendered message content. No exported API signature changes.

Changes

Cohort / File(s) Summary of Changes
Form submission / input sourcing
app/actions.tsx
When skip is false, source user input from formData.get('related_query') first, falling back to formData.get('input'); previously only input was used.
Chat UI accessibility
components/chat-panel.tsx
Added aria-label="Send message" to the chat input submit Button.
Message rendering / styling
components/message.tsx
Added break-words to the Markdown container className to enable word wrapping for long content.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Browser
  participant Actions as app/actions.tsx
  Note right of Actions #E6F0FF: New input-sourcing branch
  User->>Browser: Submit form (may include related_query)
  Browser->>Actions: POST formData
  alt skip == true
    Actions->>Actions: use fallback behavior (existing)
  else skip == false
    Actions->>Actions: userInput = formData.get('related_query') or formData.get('input')
  end
  Actions->>Server: continue processing with resolved userInput
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

I nibble keys and tidy threads,
Prefer the query where it treads.
A button named to send with grace,
Long words now wrap in cozy space.
Hop—code shipped, I bound away. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit's high-level summary is enabled.
Title Check ✅ Passed The title clearly describes the primary change—fixing text overflow in AI-generated messages—without extraneous detail or noise, making it concise and relevant.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-text-overflow

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Oct 3, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Oct 3, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Prevent text overflow more robustly

To handle text overflow, replace the break-words class with overflow-x-hidden on
the MemoizedReactMarkdown component.

components/message.tsx [21-27]

 <MemoizedReactMarkdown
   rehypePlugins={[[rehypeExternalLinks, { target: '_blank' }], rehypeKatex]}
   remarkPlugins={[remarkGfm, remarkMath]}
-  className="prose-sm prose-neutral prose-a:text-accent-foreground/50 break-words"
+  className="prose-sm prose-neutral prose-a:text-accent-foreground/50 overflow-x-hidden"
 >
   {processedData}
 </MemoizedReactMarkdown>
  • Apply / Chat
Suggestion importance[1-10]: 4

__

Why: The suggestion offers a valid alternative for handling text overflow, but it's not objectively better. The proposed overflow-x-hidden hides overflowing content, which can be a worse user experience than the PR's break-words approach that wraps it to keep it visible.

Low
  • Update

Copy link

@charliecreates charliecreates bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes address the stated issues effectively: text overflow is mitigated with break-words, and the icon-only submit button now has an accessible name. For added resilience, consider handling long tokens inside code/pre elements within markdown content. No blocking issues identified.

Additional notes (1)
  • Readability | components/message.tsx:24-24
    Good fix for the overflow. One potential edge case: very long tokens inside inline code or fenced code blocks (e.g., hashes, base64, long URLs) may still overflow or require awkward horizontal scrolling, since pre elements preserve whitespace and overflow-wrap doesn’t apply inside them. You can make this more robust by also handling code and pre descendants of .prose.

Consider adding overflow handling for pre and a more aggressive break strategy for code to ensure no content breaks layout while keeping code blocks readable.

Summary of changes
  • In components/message.tsx, added the Tailwind utility break-words to the MemoizedReactMarkdown component’s className to prevent long, unbroken strings from overflowing their container.
  • In components/chat-panel.tsx, added an aria-label="Send message" to the submit Button to improve accessibility of the icon-only control.

@charliecreates charliecreates bot removed the request for review from CharlieHelps October 3, 2025 06:35
@ngoiyaeric
Copy link
Collaborator Author

@coderabbitai run unit tests the recommended prompts section is not parsing the prompts into the system when they are clicked like they used to before

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for files related to recommended prompts or prompt suggestions
echo "=== Searching for recommended prompts related files ==="
fd -e tsx -e ts -e jsx -e js | xargs rg -l "recommended.*prompt|prompt.*suggestion|example.*prompt" -i

echo -e "\n=== Searching for prompt click handlers ==="
rg -n -C5 "onClick.*prompt|handlePrompt|onPromptClick" --type=tsx --type=ts --type=jsx --type=js

echo -e "\n=== Searching for prompt parsing logic ==="
rg -n -C5 "parsePrompt|parse.*prompt|setInput|setValue.*prompt" --type=tsx --type=ts --type=jsx --type=js | head -100

echo -e "\n=== Looking for components with 'prompt' in filename ==="
fd prompt -e tsx -e ts -e jsx -e js

Length of output: 312


🏁 Script executed:

#!/bin/bash
# Search for prompt suggestions and example prompts
echo "=== Searching for example/suggestion prompts ==="
rg -n "example|suggestion|recommended" -i -g "*.tsx" -g "*.ts" -C3 | grep -i prompt | head -50

echo -e "\n=== Looking at system-prompt-form.tsx ==="
cat components/settings/components/system-prompt-form.tsx

echo -e "\n=== Searching for prompt click handlers broadly ==="
rg -n "onClick.*=.*\{" -g "*.tsx" -C2 | grep -i "prompt\|example\|suggestion" | head -50

echo -e "\n=== Find all component files ==="
fd . components -e tsx | head -20

echo -e "\n=== Search for exampleMessages or similar patterns ==="
rg -n "exampleMessage|example.*message|suggested.*prompt|prompt.*example" -i -g "*.tsx" -g "*.ts"

Length of output: 2503


🏁 Script executed:

#!/bin/bash
# Read the empty-screen.tsx file to see the example messages and click handlers
echo "=== Reading empty-screen.tsx ==="
cat components/empty-screen.tsx

echo -e "\n=== Check if this file was modified in the PR ==="
git diff origin/main...HEAD -- components/empty-screen.tsx

echo -e "\n=== Look at chat-panel.tsx to see if it handles the prompts ==="
cat components/chat-panel.tsx

Length of output: 9787


🏁 Script executed:

#!/bin/bash
# Find where EmptyScreen is imported and used
echo "=== Finding EmptyScreen usage ==="
rg -n "EmptyScreen" -g "*.tsx" -g "*.ts" -C5

echo -e "\n=== Looking at chat.tsx ==="
cat components/chat.tsx

echo -e "\n=== Check git diff for all changes in this PR ==="
git diff main...HEAD --stat

echo -e "\n=== Check detailed diff for the modified files ==="
git diff main...HEAD

Length of output: 8624


🏁 Script executed:

#!/bin/bash
# Check the actions available and how submit works
echo "=== Looking at app/actions.ts or similar files ==="
fd "actions" -e ts -e tsx | head -10

echo -e "\n=== Search for submit function definition ==="
rg -n "export.*submit" -g "*.ts" -g "*.tsx" -C5

echo -e "\n=== Check if there's a way to programmatically submit ==="
rg -n "formRef.*submit|requestSubmit" -g "*.tsx" -C3

echo -e "\n=== Look for any recent changes or patterns around EmptyScreen ==="
rg -n "setInput.*submit|submitMessage" -g "*.tsx" -C5

Length of output: 3607


@ngoiyaeric, I've identified the issue with the recommended prompts. This is actually unrelated to the current PR (which only fixes text overflow with break-words).

The Problem

The recommended prompts in components/empty-screen.tsx are not auto-submitting messages when clicked. Looking at components/chat.tsx lines 96-98 and 118-120, the submitMessage callback only sets the input value but doesn't trigger form submission:

submitMessage={message => {
  setInput(message)
}}

The Solution

You need to modify components/chat.tsx to expose a way to programmatically submit the form. Here are two possible approaches:

Option 1: Add a submit callback to ChatPanel (Recommended)

Step 1: Modify ChatPanel to expose a submit method via ref:

// In components/chat-panel.tsx
export interface ChatPanelRef {
  handleAttachmentClick: () => void;
  submitForm: () => void; // Add this
}

export const ChatPanel = forwardRef<ChatPanelRef, ChatPanelProps>(({ messages, input, setInput }, ref) => {
  // ... existing code ...

  useImperativeHandle(ref, () => ({
    handleAttachmentClick() {
      fileInputRef.current?.click()
    },
    submitForm() {
      formRef.current?.requestSubmit()
    }
  }));

  // ... rest of the code ...

Step 2: Update chat.tsx to call both setInput and submitForm:

// In components/chat.tsx, replace both occurrences (lines 96-98 and 118-120):
submitMessage={message => {
  setInput(message)
  // Use setTimeout to ensure input is set before submitting
  setTimeout(() => {
    chatPanelRef.current?.submitForm()
  }, 0)
}}

Option 2: Simpler approach using useEffect

Alternatively, you could add a state flag to trigger submission:

// In components/chat.tsx
const [shouldSubmit, setShouldSubmit] = useState(false)

useEffect(() => {
  if (shouldSubmit && input) {
    chatPanelRef.current?.submitForm()
    setShouldSubmit(false)
  }
}, [shouldSubmit, input])

// Then in submitMessage:
submitMessage={message => {
  setInput(message)
  setShouldSubmit(true)
}}

Note on Unit Tests

I cannot run unit tests in the sandbox environment as test frameworks and execution environments are not available. However, you can test this functionality manually by:

  1. Opening a new chat session
  2. Clicking on any of the recommended prompts (e.g., "What is a planet computer?")
  3. Verifying that the message is both populated in the input AND automatically submitted

Would you like me to create a GitHub issue to track this bug separately from the current PR?

The `submit` action in `app/actions.tsx` was not correctly processing related queries. It only checked for an `input` field in the form data, ignoring the `related_query` field. This caused clicks on related prompts to fail, as their values were never extracted and processed.

This commit resolves the issue by updating the `submit` action to prioritize the `related_query` field when it is available. If the `related_query` field exists in the form data, its value is used as the user input. Otherwise, the action falls back to the `input` field. This ensures that related queries are correctly parsed and submitted to the AI, restoring the intended functionality.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b9d26d and d14e74e.

📒 Files selected for processing (1)
  • app/actions.tsx (1 hunks)

Comment on lines +57 to +58
: ((formData?.get('related_query') as string) ||
(formData?.get('input') as string))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Logical inconsistency between input sourcing and type assignment.

Prioritizing related_query over input creates a mismatch with the type assignment logic on lines 182-185:

  • If both input and related_query are present in formData, these lines will use related_query as the content
  • But lines 182-183 will assign type 'input' (because formData?.has('input') is checked first)
  • This creates a mismatch where the content comes from related_query but the type is 'input' instead of 'input_related'

Additionally, according to the PR comments, the root cause of the recommended prompts issue is that clicking a prompt sets the input value but doesn't trigger form submission. This change only affects which field is read for content—it doesn't address the auto-submission problem. Consider:

  1. Updating the type assignment logic to check has('related_query') before has('input') to match the input sourcing priority
  2. Implementing one of the solutions proposed in the PR comments (exposing a submit method via ref or using a state flag with useEffect) to address the auto-submission issue

Apply this diff to align the type assignment with input sourcing:

   const type = skip
     ? undefined
-    : formData?.has('input') || formData?.has('file')
-    ? 'input'
-    : formData?.has('related_query')
+    : formData?.has('related_query')
     ? 'input_related'
+    : formData?.has('input') || formData?.has('file')
+    ? 'input'
     : 'inquiry'

Run this script to verify if both fields can be set simultaneously:


🏁 Script executed:

#!/bin/bash
# Description: Search for code that sets both 'input' and 'related_query' in FormData

# Search for FormData append/set operations with 'input'
echo "=== Searching for FormData operations with 'input' field ==="
rg -n -B3 -A3 "FormData.*input|append.*input|set.*input" --type=tsx --type=ts

# Search for FormData append/set operations with 'related_query'
echo "=== Searching for FormData operations with 'related_query' field ==="
rg -n -B3 -A3 "FormData.*related_query|append.*related_query|set.*related_query" --type=tsx --type=ts

# Search for form submissions that might set these fields
echo "=== Searching for form elements with name='input' or name='related_query' ==="
rg -n -B2 -A2 "name=['\"]input['\"]|name=['\"]related_query['\"]" --type=tsx --type=ts

Length of output: 291


🏁 Script executed:

#!/bin/bash
echo "=== Searching for 'related_query' references ==="
rg -n 'related_query' -C3

echo "=== Searching for JSX form elements with name='input' or 'related_query' ==="
rg -n 'name\s*=\s*["\'"](input|related_query)["\'"]' -C3 -g '*.tsx' -g '*.jsx'

Length of output: 1989


Align type assignment with input sourcing priority.

Swap the ternary checks so that related_query is evaluated before input:

 const type = skip
   ? undefined
-  : formData?.has('input') || formData?.has('file')
-    ? 'input'
-    : formData?.has('related_query')
-    ? 'input_related'
+  : formData?.has('related_query')
+    ? 'input_related'
+    : formData?.has('input') || formData?.has('file')
+    ? 'input'
   : 'inquiry'
🤖 Prompt for AI Agents
In app/actions.tsx around lines 57 to 58, the current ternary evaluates input
before related_query; swap the checks so related_query is evaluated first (use
related_query || input) and ensure the type assertions remain the same
((formData?.get('related_query') as string) || (formData?.get('input') as
string)) to preserve the original typings and sourcing priority.

@ngoiyaeric ngoiyaeric merged commit ef78b3c into main Oct 3, 2025
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments