You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(crd): cut collapsed posts under the 3rd line, no fade - #10546
Collapsed posts and phase descriptions used to fade out with a gradient and could cut through the middle of a line, especially after a paragraph break or over images. They now end cleanly under the third rendered line of text, leading images are cropped to 160px, later images are hidden until expanded, and a plain Read more / Show less link sits below the content.
Root cause
src/crd/components/common/ExpandableMarkdown.tsx clipped content at a fixed max-height of 3 x line-height and overlaid a surface gradient, so paragraph margins or headings in the first lines shifted the cut mid-line and images were faded rather than handled.
Fix
ExpandableMarkdown now measures real rendered line boxes (measureLines) and clips directly under the maxLines-th one, only when the text exceeds it; the gradient overlay is removed. classifyMedia tags each image or embed as hero (before any text, or every one in a text-free post: shown, cropped to 160px with object-fit cover) or hidden (after text: withheld while collapsed), and any media makes the block collapsible. Expanded, the content renders as authored. Measurement re-runs via a ResizeObserver and keeps the previous state when nothing changed, so idle resize callbacks cause no re-render. The toggle is a primary-colour, medium-weight link below the content with Read more / Show less labels in all six languages. PostCard and TabStateHeader both use the component, so posts and phase descriptions get the treatment; the admin collapse setting and expanded-by-default behaviour are unchanged.
Tests
src/crd/components/common/ExpandableMarkdown.test.tsx covers the cut under the 3rd line across a paragraph break, exactly 3 lines with no toggle, hero cropping with short text, hidden trailing and in-between images restored on expand, image-only posts, embeds, inline code in headings, out-of-order table cells, linear-time measurement of very long posts, and that a resize which leaves the measurement unchanged does not re-render (fails with 'expected 5 to be 3' without the state bail-out).
Verification
pnpm vitest run src/crd/components/common/ExpandableMarkdown.test.tsx: 13 passed; the new re-render test failed before the fix (expected 5 to be 3)
eslint and biome check on the touched files: clean; biome ci . reports pre-existing errors only in files this branch does not touch
Commits
260d5ab fix(crd): cut collapsed posts under the 3rd line, no fade
416cbd0 fix(crd): collapse embeds like images, bound line measurement
9b1765f perf(crd): skip re-render when a resize leaves the post cut unchanged
Delivered by Brokkr run land-the-client-web-slice-of-wor-8f73c557: Claude implements, the repository's own gates verify offline, and Codex judges. CodeRabbit findings are answered by the run's watch loop.
Reviewing files that changed from the base of the PR and between e51a429 and 9b1765f.
You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.
Use the checkbox below for a quick retry:
Trigger review
No actionable comments were generated in the recent review.
Walkthrough
ExpandableMarkdown now measures rendered text lines and media to determine collapsed overflow. It clips text below the configured line limit, crops leading media, and hides later media until expansion. TabStateHeader uses the component defaults, and space translations update the toggle labels.
Changes
Markdown truncation
Layer / File(s)
Summary
Visual-line and media measurement src/crd/components/common/ExpandableMarkdown.tsx, src/crd/components/common/ExpandableMarkdown.test.tsx
The component measures visual text lines, classifies images and embeds, and records the cut position and overflow state. Tests cover visual-line ordering, inline code, paragraph breaks, and measurement with 25,000 lines.
Collapsed rendering clips text at the measured line boundary, crops hero media, and hides later media. The toggle appears below the content. Iframe elements and wrappers receive data-embed. Tests cover expanded and collapsed states, media handling, and embeds.
Consumer and toggle labels src/crd/components/space/TabStateHeader.tsx, src/crd/i18n/space/space.*.json
TabStateHeader no longer passes responsive line limits or removed styling and label props. Bulgarian, German, English, Spanish, French, and Dutch translations replace readLess with showLess and remove leading ellipses from readMore.
No merge-blocking issue was identified in the collapsed preview changes.
Pre-merge checks: 4 · 1
Failed checks: 1 warning
Check name
Status
Explanation
Resolution
Docstring Coverage
Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta…
Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed checks: 4 passed
Check name
Status
Explanation
Description Check
Check skipped - CodeRabbit’s high-level summary is enabled.
Title check
The title names the main change: ExpandableMarkdown now cuts collapsed posts below the third line and drops the fade overlay. The changeset matches this. The summary confirms line-based clipping repla…
Linked Issues check
Issue #10372 is the only active direct target. Its coding requirements are met at head e51a429.
- Text cut under the 3rd line: measureLines counts rendered line boxes. cutAt ends at the bottom …
Out of Scope Changes check
The changes stay within the scope of #10372 or support it.
- ExpandableMarkdown.tsx: the media classification, line measurement, toggle, and resize handling implement the issue rules. - `MarkdownCo…
Full details: Title check
Explanation
The title names the main change: ExpandableMarkdown now cuts collapsed posts below the third line and drops the fade overlay. The changeset matches this. The summary confirms line-based clipping replaces the height-based clamp and the gradient overlay is removed. The title uses a conventional commit prefix and stays under one line, so it passes.
Full details: Linked Issues check
Explanation
Issue #10372 is the only active direct target. Its coding requirements are met at head e51a429.
Text cut under the 3rd line: measureLines counts rendered line boxes. cutAt ends at the bottom of line maxLines. The cut applies only when textOverflows (more than maxLines lines). The gradient overlay is removed.
Text of 3 lines or fewer: cutAt is null and maxHeight is undefined, so the text is not cut.
Hero media (before any text, or every item in a text-free post): classifyMedia tags it data-collapse=hero. The collapsed classes apply max-h-[160px], overflow-hidden, and object-cover. Any media sets overflow to 'yes', so the post is collapsible even with short text.
Media after text: tagged data-collapse=hidden and hidden with !hidden while collapsed.
Expanded: isCollapsed is false, so no collapse classes or maxHeight apply. Content renders as authored.
No toggle: showToggle requires overflow 'yes', which requires text overflow or media.
Labels: the toggle uses postSnippet.readMore and postSnippet.showLess. The six locale files (bg, de, en, es, fr, nl) carry these keys.
Phase descriptions: TabStateHeader renders the same component with default limits.
No server changes are in the reviewed change set.
The incremental change since the previous review adds the resize bail-out (setMeasurement returns the previous object when unchanged). This does not alter any requirement above. Its tests are reported in the PR, but I did not run them.
Full details: Out of Scope Changes check
Explanation
The changes stay within the scope of #10372 or support it.
ExpandableMarkdown.tsx: the media classification, line measurement, toggle, and resize handling implement the issue rules.
MarkdownContent.tsx and its iframe test: data-embed marks the outer box of embeds. ExpandableMarkdown uses this marker to crop or hide embeds with the same image rules. The issue does not name embeds, but an embed after text would otherwise break the 3-line cut. This is a related extension in the same media path, not an unrelated change.
TabStateHeader.tsx: removes the old per-screen line limits, surface, and label props, and uses the component defaults. This implements the phase-description requirement.
Locale files: the postSnippet keys change to the new labels. This implements the translation requirement.
ExpandableMarkdown.test.tsx: covers the requirement cases, including the resize re-render case.
No unrelated product, server, or configuration change appears in the reviewed set.
Limitation: the diff for MarkdownContent.tsx from the previous head returned no text, and the diff for ExpandableMarkdown.tsx was unavailable. I read the head version of ExpandableMarkdown.tsx directly. The data-embed marker in MarkdownContent.tsx is inferred from the PR summary and from the dataset.embed check in the head code. This does not change the verdict.
Full details: Docstring Coverage
Explanation
Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 6 functions across 5 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
Finishing Touches
Generate docstrings
Commit to this branch
Create a new PR
Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Tip
🎯 Customize your risk assessments
Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.
✅ Automatic approvals, with your rules
Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.
CodeRabbit Verify
Run CodeRabbit Verify to test the changes in this pull request.
Included review availability: This review used your included allowance. 3 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.
valentinyanakiev
changed the title
fix(crd): clean cut-off and Read more for collapsed posts
fix(crd): cut collapsed posts under the 3rd line, no fade
Nov 2, 2026
Collapsed post and phase descriptions were clipped at a fixed
3 x line-height and covered with a gradient. A paragraph break in the
first lines left half a line showing, and images were smeared under
the fade.
ExpandableMarkdown now measures the rendered line boxes and cuts
directly under line N. Only text over N lines is cut. An image before
the text, or every image of an image-only post, is cropped to 160px
with object-fit cover. Images after text are hidden until expanded,
and any image makes the content collapsible. Read more / Show less
is a primary-colour link below the content. The gradient, the chip
and the now-unused surface prop are removed. Labels are updated in
all six languages.
Refs #10372
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Address review of the collapsed-post treatment:
- Embeds: MarkdownContent tags an embed's outer box `data-embed`, and
ExpandableMarkdown treats it like an image - cropped to 160px before
any text, hidden after it, and collapsible on its own. An embed with
short text no longer escapes the collapse setting.
- Line measurement keeps only the first maxLines + 1 visual lines, so
each text fragment costs O(maxLines) instead of a scan of every line
so far. A 25,000-line post measured in 1.5s before, 13ms now.
- Fragments merge into one visual line when their vertical middles
overlap, so inline code in a heading no longer counts as a 2nd line.
- The collapsed preview rules are !important, so authored inline
display / min-height / max-height styles cannot defeat the crop or
the hiding. Expanded, the authored styles apply again.
- Phase descriptions use the shared 3-line budget and Read more label;
the now-unused label override props and seeFullDescription key
(all six languages) are removed.
Refs #10372
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The ResizeObserver re-measures on every callback, including the one it
fires on observe(); each call stored a fresh measurement object, so every
collapsed post and phase description committed again even when no line
moved. Keep the previous object when overflow and cut are unchanged.
Refs #10372
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #10372
Summary
Collapsed posts and phase descriptions used to fade out with a gradient and could cut through the middle of a line, especially after a paragraph break or over images. They now end cleanly under the third rendered line of text, leading images are cropped to 160px, later images are hidden until expanded, and a plain Read more / Show less link sits below the content.
Root cause
src/crd/components/common/ExpandableMarkdown.tsx clipped content at a fixed max-height of 3 x line-height and overlaid a surface gradient, so paragraph margins or headings in the first lines shifted the cut mid-line and images were faded rather than handled.
Fix
ExpandableMarkdown now measures real rendered line boxes (measureLines) and clips directly under the maxLines-th one, only when the text exceeds it; the gradient overlay is removed. classifyMedia tags each image or embed as hero (before any text, or every one in a text-free post: shown, cropped to 160px with object-fit cover) or hidden (after text: withheld while collapsed), and any media makes the block collapsible. Expanded, the content renders as authored. Measurement re-runs via a ResizeObserver and keeps the previous state when nothing changed, so idle resize callbacks cause no re-render. The toggle is a primary-colour, medium-weight link below the content with Read more / Show less labels in all six languages. PostCard and TabStateHeader both use the component, so posts and phase descriptions get the treatment; the admin collapse setting and expanded-by-default behaviour are unchanged.
Tests
src/crd/components/common/ExpandableMarkdown.test.tsx covers the cut under the 3rd line across a paragraph break, exactly 3 lines with no toggle, hero cropping with short text, hidden trailing and in-between images restored on expand, image-only posts, embeds, inline code in headings, out-of-order table cells, linear-time measurement of very long posts, and that a resize which leaves the measurement unchanged does not re-render (fails with 'expected 5 to be 3' without the state bail-out).
Verification
Commits
Delivered by Brokkr run
land-the-client-web-slice-of-wor-8f73c557: Claude implements, the repository's own gates verify offline, and Codex judges. CodeRabbit findings are answered by the run's watch loop.🤖 Generated with Claude Code