Skip to content

Enhance ModelDetailsCard component: improve description overflow hand… - #14

Merged
FranciscoMoretti merged 2 commits into
mainfrom
codex/hide-expand-button
Apr 12, 2026
Merged

Enhance ModelDetailsCard component: improve description overflow hand…#14
FranciscoMoretti merged 2 commits into
mainfrom
codex/hide-expand-button

Conversation

@FranciscoMoretti

@FranciscoMoretti FranciscoMoretti commented Apr 11, 2026

Copy link
Copy Markdown
Owner

…ling and layout adjustments

Summary by Sourcery

Improve ModelDetailsCard description overflow detection and collapsed layout for more robust rendering across models.

Enhancements:

  • Refine description overflow measurement using a hidden measurement element and model-aware layout effect in ModelDetailsCard.
  • Adjust collapsed description styling with explicit minimum height and model-keyed Collapsible to ensure consistent layout when switching models.

Summary by CodeRabbit

  • Bug Fixes

    • More reliable description truncation and display in the model details card: text overflow is now detected and updated correctly on model change, font loading, and resizing to prevent incorrect clipping.
  • Chores

    • Updated .gitignore to exclude local package manager store directories.

Summary by cubic

Improves ModelDetailsCard overflow detection and collapsed description layout so the expand/collapse button appears correctly and the card stays steady when switching models. Adds guarded cleanup to prevent stale measurements when the model changes.

  • Bug Fixes

    • Compute overflow with a hidden measurement element and line-height, using useLayoutEffect, ResizeObserver, and font-ready checks for accurate detection.
    • Key the collapsible by model.id, set a min-height for the clamped text, observe both elements, and guard cleanup to avoid updates after unmount/model switch.
  • Refactors

    • Ignore .pnpm-store in .gitignore.

Written for commit 7741f43. Summary will update on new commits.

@sourcery-ai

sourcery-ai Bot commented Apr 11, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refines how the ModelDetailsCard handles long model descriptions by improving overflow detection, making layout more robust, and slightly restructuring the collapsible description UI.

Sequence diagram for description overflow measurement in ModelDetailsCard

sequenceDiagram
  actor User
  participant Browser
  participant ModelDetailsCard
  participant ClampedParagraph as ClampedParagraph
  participant MeasureParagraph as MeasureParagraph
  participant ResizeObserverInstance as ResizeObserver
  participant Window
  participant DocumentFonts as DocumentFonts

  User->>Browser: Navigate to compare page
  Browser->>ModelDetailsCard: Render with model
  ModelDetailsCard->>ModelDetailsCard: useLayoutEffect(model)
  ModelDetailsCard->>ClampedParagraph: Attach clampedRef
  ModelDetailsCard->>MeasureParagraph: Attach measureRef
  ModelDetailsCard->>ModelDetailsCard: measure()
  ModelDetailsCard->>MeasureParagraph: window.getComputedStyle(measureEl)
  MeasureParagraph-->>ModelDetailsCard: CSSStyleDeclaration
  ModelDetailsCard->>ModelDetailsCard: getLineHeightPx(styles)
  ModelDetailsCard->>MeasureParagraph: getBoundingClientRect().height
  MeasureParagraph-->>ModelDetailsCard: measuredHeight
  ModelDetailsCard->>ModelDetailsCard: compute collapsedHeight
  ModelDetailsCard->>ModelDetailsCard: overflowing = measuredHeight > collapsedHeight + 1
  ModelDetailsCard->>ModelDetailsCard: setIsDescriptionOverflowing(overflowing)

  ModelDetailsCard->>ResizeObserverInstance: new ResizeObserver(measure)
  ModelDetailsCard->>ResizeObserverInstance: observe(clampedEl)
  ModelDetailsCard->>Window: addEventListener(resize, measure)
  ModelDetailsCard->>DocumentFonts: fonts.ready.then(measure)

  Window-->>ModelDetailsCard: resize event
  ModelDetailsCard->>ModelDetailsCard: measure()

  ResizeObserverInstance-->>ModelDetailsCard: size change callback
  ModelDetailsCard->>ModelDetailsCard: measure()

  User-->>Browser: Navigate away or change model
  Browser-->>ModelDetailsCard: Unmount or re-render with new model
  ModelDetailsCard->>ResizeObserverInstance: disconnect()
  ModelDetailsCard->>Window: removeEventListener(resize, measure)
Loading

File-Level Changes

Change Details Files
Improve overflow detection for model descriptions using measured line height and a hidden measurement element.
  • Introduce constants for collapsed description line count and min height
  • Add getLineHeightPx utility to derive line height from computed styles with a fallback based on font size
  • Replace previous scrollHeight-based overflow check with a comparison between measured description height and the calculated collapsed height
  • Switch from useEffect to useLayoutEffect and add model to the dependency array so measurements are tied to the current model
  • Hook overflow measurement into ResizeObserver, window resize, and font loading via document.fonts.ready
apps/website/app/(models)/compare/model-details-card.tsx
Adjust the collapsible description layout to support accurate measurement and stable visual height.
  • Add a measureRef for an invisible paragraph used solely for measurement and keep clampedRef for the visible collapsed text
  • Wrap the description paragraphs in a relatively positioned container and add an absolutely positioned, invisible duplicate paragraph for measuring full height
  • Set an explicit minHeight on the clamped paragraph using the collapsed description min-height constant to prevent layout jumpiness
  • Key the Collapsible component by model.id so it resets when switching models
  • Reorder imports and add the ModelData type import for clearer typing
apps/website/app/(models)/compare/model-details-card.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@vercel

vercel Bot commented Apr 11, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
ai-registry Ready Ready Preview, Comment Apr 12, 2026 7:44am
ai-registry-website Ready Ready Preview, Comment Apr 12, 2026 7:44am

@coderabbitai

coderabbitai Bot commented Apr 11, 2026

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This pull request adds .pnpm-store to .gitignore and refactors overflow measurement in the model details card to use layout-based measurement with a hidden measurement element, useLayoutEffect, ResizeObserver, font readiness handling, and forced remounting of Collapsible on model changes.

Changes

Cohort / File(s) Summary
Build Configuration
/.gitignore
Added .pnpm-store entry to ignore pnpm's local store directory; inserted after existing lockfile ignore patterns.
Component Refactor
apps/website/app/(models)/compare/model-details-card.tsx
Replaced simple scrollHeight vs clientHeight check with layout-based measurement using a hidden <p ref={measureRef}>; switched useEffectuseLayoutEffect with model dependency and cancellation guard; added ResizeObserver on visible and measure elements; re-measured after document.fonts?.ready; restructured DOM to include relative wrapper and visible clamped paragraph with computed minHeight; added key={model.id} to Collapsible to force remount.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is a truncated/incomplete sentence that ends with 'hand…' instead of the full phrase. However, it clearly refers to the main change: improving description overflow handling in ModelDetailsCard, which is the primary focus of the PR's substantial changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/hide-expand-button

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.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • In the useLayoutEffect setup, the ResizeObserver is attached to clampedEl while the measurement logic uses measureEl; consider observing measureRef instead so the observer is directly tracking the element whose height you use for overflow detection.
  • The collapsed description height is defined twice with implicit magic numbers (COLLAPSED_DESCRIPTION_MIN_HEIGHT using calc(2 * 1.625 * 0.875rem) and the 1.625 factor in getLineHeightPx); it would be clearer and less error-prone to centralize these values or derive the min-height from the same constants used in the JS calculation.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the `useLayoutEffect` setup, the `ResizeObserver` is attached to `clampedEl` while the measurement logic uses `measureEl`; consider observing `measureRef` instead so the observer is directly tracking the element whose height you use for overflow detection.
- The collapsed description height is defined twice with implicit magic numbers (`COLLAPSED_DESCRIPTION_MIN_HEIGHT` using `calc(2 * 1.625 * 0.875rem)` and the `1.625` factor in `getLineHeightPx`); it would be clearer and less error-prone to centralize these values or derive the min-height from the same constants used in the JS calculation.

## Individual Comments

### Comment 1
<location path="apps/website/app/(models)/compare/model-details-card.tsx" line_range="36-37" />
<code_context>
 import { formatNumberCompact } from "../../../lib/format-number-compact";

+const COLLAPSED_DESCRIPTION_LINES = 2;
+const COLLAPSED_DESCRIPTION_MIN_HEIGHT =
+  "calc(2 * 1.625 * 0.875rem)";
+
+function getLineHeightPx(styles: CSSStyleDeclaration) {
</code_context>
<issue_to_address>
**suggestion:** The hardcoded min-height formula duplicates typography assumptions and can drift out of sync with the actual line-height/font-size.

This constant is tightly coupled to the current `text-sm` (0.875rem) and `leading-relaxed` (1.625) values. If those utilities or the base font-size change, the min-height will no longer match the actual line height, causing subtle layout issues. Since `useLayoutEffect` already measures line height, consider deriving the collapsed height from that measurement in JS, or at least centralize the `1.625` multiplier and `COLLAPSED_DESCRIPTION_LINES` into shared constants used both here and in the measurement logic.

Suggested implementation:

```typescript
const COLLAPSED_DESCRIPTION_LINES = 2;
const DESCRIPTION_LINE_HEIGHT_MULTIPLIER = 1.625;
const BASE_FONT_SIZE_REM = 0.875;

const COLLAPSED_DESCRIPTION_MIN_HEIGHT = `calc(${COLLAPSED_DESCRIPTION_LINES} * ${DESCRIPTION_LINE_HEIGHT_MULTIPLIER} * ${BASE_FONT_SIZE_REM}rem)`;

```

```typescript
function getLineHeightPx(styles: CSSStyleDeclaration) {
  const lineHeightPx = Number.parseFloat(styles.lineHeight);
  if (Number.isFinite(lineHeightPx)) {
    return lineHeightPx;
  }

  const fontSizePx = Number.parseFloat(styles.fontSize);
  return Number.isFinite(fontSizePx)
    ? fontSizePx * DESCRIPTION_LINE_HEIGHT_MULTIPLIER
    : 0;
}

```

To fully align with your comment about deriving the collapsed height from the measured line height instead of typography assumptions, you could:
1. Store the measured line height from `getLineHeightPx` in state inside the `useLayoutEffect` that measures the description.
2. Compute the collapsed height as `measuredLineHeight * COLLAPSED_DESCRIPTION_LINES` in JS and apply it via an inline style or a CSS custom property, instead of relying on `COLLAPSED_DESCRIPTION_MIN_HEIGHT`.
3. Remove or narrow the usage of `BASE_FONT_SIZE_REM` once all consumers use the runtime measurement rather than the fallback formula.
These changes require touching the layout/measuring logic further down in the file, which isn't shown in the snippet.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread apps/website/app/(models)/compare/model-details-card.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/website/app/`(models)/compare/model-details-card.tsx:
- Around line 131-164: The effect's document.fonts?.ready.then callback can call
measure() after cleanup and mutate state for a different model; fix by tracking
cancellation inside useLayoutEffect (e.g., a local `let mounted = true` or an
AbortController) and only call measure() or setIsDescriptionOverflowing when
still mounted, and ensure the cleanup sets mounted = false (or aborts) so the
deferred promise handler no-ops after the effect has been torn down; update the
code around useLayoutEffect, the measure function, document.fonts?.ready.then,
and the cleanup to implement this guard.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9cfce06b-2575-49be-9767-0419aed55b2e

📥 Commits

Reviewing files that changed from the base of the PR and between ea9a408 and 04db56d.

📒 Files selected for processing (2)
  • .gitignore
  • apps/website/app/(models)/compare/model-details-card.tsx

Comment thread apps/website/app/(models)/compare/model-details-card.tsx

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 2 files

@FranciscoMoretti
FranciscoMoretti merged commit ff08a07 into main Apr 12, 2026
3 of 6 checks passed
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.

1 participant