Skip to content

Conversation

@google-labs-jules
Copy link
Contributor

@google-labs-jules google-labs-jules bot commented Jan 10, 2026

User description

This PR resolves several UI text overflow issues by removing whitespace-nowrap from button and label components, standardizing the mobile breakpoint, and refactoring the settings tabs to use the base Button component.


PR created automatically by Jules for task 8696950182480457087 started by @ngoiyaeric


PR Type

Bug fix, Enhancement


Description

  • Removed whitespace-nowrap from base Button component for text wrapping

  • Standardized mobile breakpoint from 768px to 1024px in Chat component

  • Refactored settings tabs to use Button component instead of inline styles

  • Removed whitespace-nowrap from checkbox label in Copilot component


Diagram Walkthrough

flowchart LR
  A["Button Component<br/>Remove whitespace-nowrap"] --> B["Settings Tabs<br/>Use Button component"]
  A --> C["Chat Component<br/>Update mobile breakpoint"]
  A --> D["Copilot Component<br/>Remove label nowrap"]
  B --> E["Improved Text Wrapping<br/>on Small Screens"]
  C --> E
  D --> E
Loading

File Walkthrough

Relevant files
Bug fix
button.tsx
Remove whitespace-nowrap from base Button                               

components/ui/button.tsx

  • Removed whitespace-nowrap from the base buttonVariants CVA definition
  • Allows button text to wrap naturally instead of being constrained to
    single line
  • Affects all Button component instances across the application
+1/-1     
copilot.tsx
Remove nowrap constraint from checkbox label                         

components/copilot.tsx

  • Removed whitespace-nowrap from checkbox label className
  • Allows long checkbox labels to wrap on smaller screens
  • Maintains text-sm and pr-4 spacing classes
+1/-1     
Enhancement
chat.tsx
Standardize mobile breakpoint to 1024px                                   

components/chat.tsx

  • Changed mobile breakpoint from 768px to 1024px in checkMobile function
  • Standardizes mobile detection to match CSS media query breakpoints
  • Improves consistency in responsive behavior
+1/-1     
settings.tsx
Refactor settings tabs to use Button component                     

components/settings/components/settings.tsx

  • Refactored four Tabs.Trigger elements to use Button component with
    asChild prop
  • Replaced inline button styling with reusable Button component variant
  • Maintains active state styling with data-[state=active]:bg-primary/80
    class
  • Reduces code duplication and improves maintainability
+12/-4   

This commit addresses several UI text overflow issues across the application.

- Standardized the mobile breakpoint to 1024px in `components/chat.tsx` to match the CSS media queries.
- Removed `whitespace-nowrap` from the base `Button` component in `components/ui/button.tsx` to allow button text to wrap by default.
- Refactored the settings tabs in `components/settings/components/settings.tsx` to use the `Button` component, fixing the overflow on smaller screens.
- Removed `whitespace-nowrap` from the label in `components/copilot.tsx` to allow long checkbox labels to wrap.
@google-labs-jules
Copy link
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel
Copy link

vercel bot commented Jan 10, 2026

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

Project Deployment Review Updated (UTC)
qcx Ready Ready Preview, Comment Jan 10, 2026 9:22pm

@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 Jan 10, 2026

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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

@qodo-code-review
Copy link
Contributor

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
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

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

@qodo-code-review
Copy link
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Use matchMedia for responsive detection

Replace the window.innerWidth check with the more performant window.matchMedia
API for responsive breakpoint detection.

components/chat.tsx [46-48]

-const checkMobile = () => {
-  setIsMobile(window.innerWidth < 1024)
-}
+const mediaQuery = window.matchMedia('(max-width: 1024px)')
+const updateMobile = (e: MediaQueryListEvent) => setIsMobile(e.matches)
+mediaQuery.addEventListener('change', updateMobile)
+// Set initial state
+setIsMobile(mediaQuery.matches)
+return () => mediaQuery.removeEventListener('change', updateMobile)
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion proposes a more performant and modern approach using matchMedia for responsive checks, which is superior to using a resize event listener with window.innerWidth.

Medium
Prevent unintended text wrapping in tabs

Add the whitespace-nowrap class to the tab Button components to prevent text
from wrapping on smaller screens and maintain a consistent layout.

components/settings/components/settings.tsx [156-167]

 <Tabs.Trigger value="system-prompt" asChild>
-  <Button variant="outline" className="data-[state=active]:bg-primary/80">System Prompt</Button>
+  <Button variant="outline" className="whitespace-nowrap data-[state=active]:bg-primary/80">System Prompt</Button>
 </Tabs.Trigger>
 <Tabs.Trigger value="model" asChild>
-  <Button variant="outline" className="data-[state=active]:bg-primary/80">Model Selection</Button>
+  <Button variant="outline" className="whitespace-nowrap data-[state=active]:bg-primary/80">Model Selection</Button>
 </Tabs.Trigger>
 <Tabs.Trigger value="user-management" asChild>
-  <Button variant="outline" className="data-[state=active]:bg-primary/80">User Management</Button>
+  <Button variant="outline" className="whitespace-nowrap data-[state=active]:bg-primary/80">User Management</Button>
 </Tabs.Trigger>
 <Tabs.Trigger value="map" asChild>
-  <Button variant="outline" className="data-[state=active]:bg-primary/80">Map</Button>
+  <Button variant="outline" className="whitespace-nowrap data-[state=active]:bg-primary/80">Map</Button>
 </Tabs.Trigger>
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies that removing whitespace-nowrap globally from the Button component could negatively affect this specific tab layout, and it proposes re-adding it locally to maintain UI consistency.

Low
Enable word wrapping on labels

Add the break-words utility class to the label to ensure long words without
spaces wrap correctly and do not overflow their container.

components/copilot.tsx [148-153]

 <label
-  className="text-sm pr-4"
+  className="text-sm pr-4 break-words"
   htmlFor={option?.value}
 >
   {option?.label}
 </label>
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why: This suggestion improves upon the PR's change by adding break-words, which prevents long, unbreakable words from overflowing the label's container, making the UI more robust.

Low
  • More

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.

This PR likely fixes the reported overflow, but it introduces a global behavioral change by removing whitespace-nowrap from the base Button, which may cause regressions across the app. components/chat.tsx could avoid unnecessary re-renders by preventing redundant setIsMobile updates on frequent resize events. The Tabs.Trigger asChild refactor is cleaner, but the active-state styling on the outline buttons is incomplete and may cause contrast/border inconsistencies depending on theme variables.

Summary of changes

Overview

This PR addresses several UI text overflow issues by:

  • Updating the “mobile” breakpoint detection in components/chat.tsx from 768px to 1024px.
  • Allowing text wrapping by default:
    • Removing whitespace-nowrap from checkbox option labels in components/copilot.tsx.
    • Removing whitespace-nowrap from the base Button styles in components/ui/button.tsx.
  • Refactoring settings tabs in components/settings/components/settings.tsx to render Tabs.Trigger via asChild and the shared <Button variant="outline" /> component, reducing duplicated class strings and improving consistency.

Key refactors

  • Replaced long, duplicated Tabs.Trigger className strings with shared button styles + targeted data-[state=active] overrides via className="data-[state=active]:bg-primary/80".

Comment on lines 7 to 9
const buttonVariants = cva(
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
{

Choose a reason for hiding this comment

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

Removing whitespace-nowrap from the base Button affects every button in the app, not just the ones that were overflowing. That’s a broad behavior change and may introduce regressions (e.g., buttons in tight toolbars or tables wrapping to two lines and increasing row height).

Given the PR goal (fix specific overflow cases), consider scoping wrapping behavior to the few problem buttons (or introducing an opt-in/out class/variant) rather than changing the global default.

Suggestion

Consider keeping the default as whitespace-nowrap and adding a variant/utility for wrapping, e.g.:

const buttonVariants = cva(
  'inline-flex items-center justify-center whitespace-nowrap ...',
  {
    variants: {
      wrap: {
        true: 'whitespace-normal break-words',
        false: 'whitespace-nowrap',
      },
      // ...
    },
    defaultVariants: {
      wrap: false,
    },
  }
)

Then apply wrap (or className="whitespace-normal") only where needed.

Reply with "@CharlieHelps yes please" if you'd like me to add a commit implementing this variant and updating the affected call sites.

Comment on lines 154 to +167
<Tabs.Root value={currentTab} onValueChange={setCurrentTab} className="w-full">
<Tabs.List className="grid w-full grid-cols-4 gap-x-2">
<Tabs.Trigger value="system-prompt" className="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 data-[state=active]:bg-primary/80">System Prompt</Tabs.Trigger>
<Tabs.Trigger value="model" className="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 data-[state=active]:bg-primary/80">Model Selection</Tabs.Trigger>
<Tabs.Trigger value="user-management" className="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 data-[state=active]:bg-primary/80">User Management</Tabs.Trigger>
<Tabs.Trigger value="map" className="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 data-[state=active]:bg-primary/80">Map</Tabs.Trigger>
<Tabs.Trigger value="system-prompt" asChild>
<Button variant="outline" className="data-[state=active]:bg-primary/80">System Prompt</Button>
</Tabs.Trigger>
<Tabs.Trigger value="model" asChild>
<Button variant="outline" className="data-[state=active]:bg-primary/80">Model Selection</Button>
</Tabs.Trigger>
<Tabs.Trigger value="user-management" asChild>
<Button variant="outline" className="data-[state=active]:bg-primary/80">User Management</Button>
</Tabs.Trigger>
<Tabs.Trigger value="map" asChild>
<Button variant="outline" className="data-[state=active]:bg-primary/80">Map</Button>
</Tabs.Trigger>

Choose a reason for hiding this comment

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

Using Tabs.Trigger asChild with your shared Button is a good consolidation, but be careful with styling: Button variant="outline" has its own hover/background/text rules that may conflict with the visual intent of an active tab.

Right now you only set data-[state=active]:bg-primary/80 but not the corresponding text color/border color. Depending on theme variables, this can yield low-contrast text or an outline border that looks incorrect when active.

Suggestion

Consider fully defining the active state styling (bg + text + border) to avoid theme-dependent contrast issues, e.g.:

<Button
  variant="outline"
  className="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:border-primary"
></Button>

If you want the inactive state to remain outlined, keep variant="outline" and only override the active state.

Reply with "@CharlieHelps yes please" if you'd like me to add a commit applying consistent active styles to all four triggers.

@charliecreates charliecreates bot removed the request for review from CharlieHelps January 10, 2026 21:27
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