Skip to content

Cards width bugfix#1549

Merged
simo6529 merged 7 commits intomainfrom
cards-width-bugfix
Oct 16, 2025
Merged

Cards width bugfix#1549
simo6529 merged 7 commits intomainfrom
cards-width-bugfix

Conversation

@simo6529
Copy link
Copy Markdown
Collaborator

@simo6529 simo6529 commented Oct 16, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Improved layout and full-width sizing for link preview cards to prevent overflow
    • Enhanced container overflow and focus handling so content stays contained until focused
    • Strengthened text wrapping so long or unbroken URL segments wrap and don’t break card layout
  • Tests

    • Added a test ensuring long unbroken segments render with wrapping to prevent overflow
  • Documentation

    • Added a log entry about OpenGraphPreview regex/compatibility adjustments

Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Oct 16, 2025

Walkthrough

Adds width and overflow constraints to wave preview components, introduces wrapLongUnbrokenSegments with a 32-character threshold to wrap long unbroken text segments, applies removeBaseEndpoint to compute effectiveRelativeHref, and adds a test and ticket note. No public API changes.

Changes

Cohort / File(s) Summary
Wave UI & layout updates
components/waves/LinkHandlerFrame.tsx, components/waves/LinkPreviewCard.tsx, components/waves/OpenGraphPreview.tsx
Added Tailwind width/overflow classes (tw-min-w-0, tw-max-w-full, tw-w-full, tw-overflow-hidden, focus-within adjustments), strengthened text-wrapping (tw-break-words, tw-[overflow-wrap:anywhere]), and constrained inner widths. LinkHandlerFrame computes effectiveRelativeHref via removeBaseEndpoint and passes it to ChatItemHrefButtons.
Long-segment wrapping
components/waves/OpenGraphPreview.tsx
Introduced LONG_UNBROKEN_SEGMENT_THRESHOLD = 32 and wrapLongUnbrokenSegments(value) which tokenizes text and wraps segments >=32 chars in <span class="tw-break-all"> to prevent layout breakage; text rendering updated to use this function.
Tests
__tests__/components/waves/OpenGraphPreview.test.tsx
Added test that verifies very long unbroken URL segments are wrapped in a <span> with tw-break-all; mocks removeBaseEndpoint.
Docs / ticket
codex/tickets/TKT-0009.md
Added note about removing the unicode regex flag from OpenGraphPreview for TypeScript target compatibility and that type-checking remains blocked by unrelated test typing failures.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant P as Props (title/domain/description/href)
  participant LH as LinkHandlerFrame
  participant OG as OpenGraphPreview
  participant W as wrapLongUnbrokenSegments
  participant R as Renderer

  P->>LH: pass href / relativeHref
  LH->>LH: compute effectiveRelativeHref (use relativeHref or removeBaseEndpoint(href))
  LH->>OG: render preview with effectiveRelativeHref
  OG->>W: call for domain/title/description
  alt token length >= 32
    W-->>OG: return <span class="tw-break-all">long-token</span>
  else
    W-->>OG: return original token/fragment
  end
  OG->>R: render card with constrained containers (tw-min-w-0, tw-max-w-full, overflow rules)
  R-->>P: rendered preview with wrapped long segments
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Fix process.env use #1495 — Related changes around handling/stripping BASE_ENDPOINT; likely touches similar link normalization logic.

Suggested reviewers

  • ragnep
  • GelatoGenesis

Poem

🐰 I nibbled long URLs by night,

I split their stretches out of sight,
Boxes breathe and lines behave,
No more overflows to stave,
A hop, a wrap — the preview's bright. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Cards width bugfix" is clearly related to the primary purpose of the changeset. The modifications across LinkHandlerFrame.tsx, LinkPreviewCard.tsx, and OpenGraphPreview.tsx all focus on addressing width and overflow constraints on card components through the addition of Tailwind classes like tw-min-w-0, tw-max-w-full, and tw-overflow-hidden, along with text-wrapping enhancements. The title is concise, avoids vague terminology, and accurately reflects that the main objective is fixing width-related issues with cards. A teammate reviewing commit history would understand this is a width bugfix for card components.
✨ 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 cards-width-bugfix

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b408cb0 and a491ad0.

📒 Files selected for processing (2)
  • components/waves/LinkHandlerFrame.tsx (2 hunks)
  • components/waves/OpenGraphPreview.tsx (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • components/waves/OpenGraphPreview.tsx
  • components/waves/LinkHandlerFrame.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)

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.

Copy link
Copy Markdown

@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: 0

🧹 Nitpick comments (4)
components/waves/LinkPreviewCard.tsx (1)

89-91: Refine the word-breaking strategy.

The combination of tw-break-words, tw-break-all, and tw-[overflow-wrap:anywhere] is redundant. The tw-break-all class is particularly aggressive and will break words at any character, which can reduce readability. Typically, tw-break-words with tw-[overflow-wrap:anywhere] provides sufficient overflow handling while maintaining better text flow.

Consider applying this diff:

-          <div className="tw-flex tw-h-full tw-w-full tw-max-w-full tw-items-center tw-justify-start tw-overflow-hidden tw-break-words tw-break-all tw-[overflow-wrap:anywhere]">
+          <div className="tw-flex tw-h-full tw-w-full tw-max-w-full tw-items-center tw-justify-start tw-overflow-hidden tw-break-words tw-[overflow-wrap:anywhere]">
components/waves/LinkHandlerFrame.tsx (1)

19-22: Consider extracting the shared layout pattern.

The layout structure here is nearly identical to the one in LinkPreviewCardLayout in OpenGraphPreview.tsx (lines 200-203). Both implement the same flex-with-overflow-hidden pattern. While the current implementation works correctly, consider extracting this pattern into a shared component to reduce duplication.

Example shared component structure:

function OverflowConstrainedContainer({ 
  children, 
  actions 
}: { 
  readonly children: ReactNode; 
  readonly actions?: ReactNode; 
}) {
  return (
    <div className="tw-flex tw-items-stretch tw-w-full tw-min-w-0 tw-max-w-full tw-gap-x-1">
      <div className="tw-flex-1 tw-min-w-0 tw-max-w-full tw-overflow-hidden">
        {children}
      </div>
      {actions}
    </div>
  );
}
components/waves/OpenGraphPreview.tsx (2)

260-275: Refine the word-breaking strategy.

Similar to LinkPreviewCard.tsx, the combination of tw-break-words, tw-break-all, and tw-[overflow-wrap:anywhere] on line 271 is redundant. The tw-break-all class can reduce readability by breaking words at any character. Consider using only tw-break-words with tw-[overflow-wrap:anywhere].

Apply this diff to line 271:

-              className="tw-break-words tw-break-all tw-[overflow-wrap:anywhere] tw-text-sm tw-font-semibold tw-text-iron-100 tw-no-underline tw-transition tw-duration-200 hover:tw-text-white">
+              className="tw-break-words tw-[overflow-wrap:anywhere] tw-text-sm tw-font-semibold tw-text-iron-100 tw-no-underline tw-transition tw-duration-200 hover:tw-text-white">

306-323: Refine the word-breaking strategy.

Both the title link (line 316) and description (line 320) use the redundant combination of tw-break-words, tw-break-all, and tw-[overflow-wrap:anywhere]. Consider removing tw-break-all for better readability while still preventing overflow.

Apply these diffs:

-              className="tw-break-words tw-break-all tw-[overflow-wrap:anywhere] tw-text-lg tw-font-semibold tw-leading-snug tw-text-iron-100 tw-no-underline tw-transition tw-duration-200 hover:tw-text-white">
+              className="tw-break-words tw-[overflow-wrap:anywhere] tw-text-lg tw-font-semibold tw-leading-snug tw-text-iron-100 tw-no-underline tw-transition tw-duration-200 hover:tw-text-white">
-              <p className="tw-m-0 tw-text-sm tw-text-iron-300 tw-line-clamp-3 tw-break-words tw-break-all tw-[overflow-wrap:anywhere] tw-whitespace-pre-line">
+              <p className="tw-m-0 tw-text-sm tw-text-iron-300 tw-line-clamp-3 tw-break-words tw-[overflow-wrap:anywhere] tw-whitespace-pre-line">
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 44e7e77 and 26c630e.

📒 Files selected for processing (3)
  • components/waves/LinkHandlerFrame.tsx (1 hunks)
  • components/waves/LinkPreviewCard.tsx (2 hunks)
  • components/waves/OpenGraphPreview.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

**/*.{ts,tsx}: Use TypeScript for source code and follow existing code style and naming conventions
Adhere to clean code standards as measured by SonarQube

Files:

  • components/waves/OpenGraphPreview.tsx
  • components/waves/LinkPreviewCard.tsx
  • components/waves/LinkHandlerFrame.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Implement React components as functional components using hooks (no class components)

Files:

  • components/waves/OpenGraphPreview.tsx
  • components/waves/LinkPreviewCard.tsx
  • components/waves/LinkHandlerFrame.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
components/waves/LinkPreviewCard.tsx (1)

105-107: LGTM!

The addition of tw-w-full ensures consistent width behavior across different preview states.

components/waves/OpenGraphPreview.tsx (3)

200-203: Layout structure changes look good.

The flex-with-overflow-hidden pattern correctly addresses width constraint issues. Note that this pattern is duplicated in LinkHandlerFrame.tsx (see comment on that file for refactoring suggestion).


236-246: LGTM!

The addition of tw-w-full ensures consistent width behavior for the skeleton loading state.


282-305: LGTM!

The addition of tw-w-full ensures the card container takes full available width consistently.

Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Copy link
Copy Markdown

@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: 0

🧹 Nitpick comments (1)
components/waves/OpenGraphPreview.tsx (1)

348-350: Consider wrapping the domain label for consistency.

The domain label at Line 349 renders the domain directly without wrapping. While domain names are typically short, consider using wrapLongUnbrokenSegments(domain) for consistency and to handle edge cases of unusually long domain names.

Apply this diff if you'd like to add wrapping:

 {domain && (
-  <span className="tw-text-xs tw-font-medium tw-uppercase tw-tracking-wide tw-text-iron-400">
-    {domain}
-  </span>
+  <span className="tw-text-xs tw-font-medium tw-uppercase tw-tracking-wide tw-text-iron-400">
+    {wrapLongUnbrokenSegments(domain)}
+  </span>
 )}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26c630e and dfa871f.

📒 Files selected for processing (4)
  • __tests__/components/waves/OpenGraphPreview.test.tsx (1 hunks)
  • components/waves/LinkHandlerFrame.tsx (2 hunks)
  • components/waves/LinkPreviewCard.tsx (2 hunks)
  • components/waves/OpenGraphPreview.tsx (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/waves/LinkHandlerFrame.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

**/*.{ts,tsx}: Use TypeScript for source code and follow existing code style and naming conventions
Adhere to clean code standards as measured by SonarQube

Files:

  • __tests__/components/waves/OpenGraphPreview.test.tsx
  • components/waves/OpenGraphPreview.tsx
  • components/waves/LinkPreviewCard.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Implement React components as functional components using hooks (no class components)

Files:

  • __tests__/components/waves/OpenGraphPreview.test.tsx
  • components/waves/OpenGraphPreview.tsx
  • components/waves/LinkPreviewCard.tsx
__tests__/**

📄 CodeRabbit inference engine (tests/AGENTS.md)

Place Jest test suites under the __tests__ directory mirroring source folders (e.g., components, contexts, hooks, utils)

Files:

  • __tests__/components/waves/OpenGraphPreview.test.tsx
__tests__/components/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use @testing-library/react and @testing-library/user-event for React component tests

Files:

  • __tests__/components/waves/OpenGraphPreview.test.tsx
{**/__tests__/**,**/*.test.tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Place tests in tests directories or alongside components as ComponentName.test.tsx

Files:

  • __tests__/components/waves/OpenGraphPreview.test.tsx
{**/__tests__/**,**/*.test.{ts,tsx}}

📄 CodeRabbit inference engine (AGENTS.md)

Mock external dependencies and APIs in tests

Files:

  • __tests__/components/waves/OpenGraphPreview.test.tsx
🧬 Code graph analysis (1)
__tests__/components/waves/OpenGraphPreview.test.tsx (2)
helpers/Helpers.ts (1)
  • removeBaseEndpoint (791-793)
components/waves/OpenGraphPreview.tsx (1)
  • OpenGraphPreview (263-369)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
components/waves/LinkPreviewCard.tsx (2)

89-90: LGTM! Proper width and overflow handling for fallback content.

The combination of tw-w-full, tw-max-w-full, tw-overflow-hidden, and text-breaking utilities properly constrains the layout and handles long unbroken text segments.


105-105: LGTM! Consistent width handling for ENS preview.

The tw-w-full class ensures the ENS preview container spans the full available width, maintaining consistency with the fallback state.

components/waves/OpenGraphPreview.tsx (6)

1-1: LGTM! Fragment import required for the new wrapping utility.

The Fragment import is necessary for the wrapLongUnbrokenSegments function to wrap shorter text segments without introducing additional DOM nodes.


54-54: LGTM! Reasonable threshold for long segment detection.

A 32-character threshold is appropriate for detecting unbroken segments that could break layout (e.g., long URLs, hashes, or identifiers).


139-176: LGTM! Clean implementation of the text-wrapping utility.

The function efficiently handles long unbroken segments:

  • Splits text by whitespace while preserving spacing
  • Wraps segments ≥32 chars with tw-break-all for controlled breaking
  • Optimizes by returning the original string when no wrapping is needed
  • Uses proper React keys scoped to each invocation

240-243: LGTM! Effective layout constraints for the preview container.

The combination of tw-min-w-0, tw-max-w-full, and tw-overflow-hidden with focus-within:tw-overflow-visible ensures:

  • Proper width constraints in flex contexts
  • Hidden overflow for long content
  • Visible overflow when interactive elements receive focus

277-277: LGTM! Consistent full-width styling across all preview states.

Adding tw-w-full to the skeleton, unavailable, and normal card states ensures consistent width behavior across all rendering paths.

Also applies to: 301-301, 323-323


311-312: LGTM! Proper usage of the wrapping utility for text content.

Using wrapLongUnbrokenSegments for domain, title, and description text combined with tw-break-words and tw-[overflow-wrap:anywhere] effectively handles long content while maintaining readability.

Also applies to: 356-357, 360-361

__tests__/components/waves/OpenGraphPreview.test.tsx (1)

142-159: LGTM! Comprehensive test for the wrapping behavior.

The test effectively verifies that:

  • Long unbroken segments (48 chars) exceeding the threshold are detected
  • Segments are wrapped in a <span> element with tw-break-all class
  • The wrapping maintains the original text content

This provides good coverage for the core functionality introduced in the PR.

Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
@sonarqubecloud
Copy link
Copy Markdown

@simo6529 simo6529 merged commit 2a0dc65 into main Oct 16, 2025
8 checks passed
@simo6529 simo6529 deleted the cards-width-bugfix branch October 16, 2025 09:14
@coderabbitai coderabbitai Bot mentioned this pull request Jan 26, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants