Skip to content

chore(Breadcrumbs): add story reproducing false collapse on content-sized container - #2732

Open
ykamendrovskiy wants to merge 1 commit into
gravity-ui:mainfrom
ykamendrovskiy:fix/breadcrumbs-false-collapse
Open

chore(Breadcrumbs): add story reproducing false collapse on content-sized container#2732
ykamendrovskiy wants to merge 1 commit into
gravity-ui:mainfrom
ykamendrovskiy:fix/breadcrumbs-false-collapse

Conversation

@ykamendrovskiy

@ykamendrovskiy ykamendrovskiy commented Jul 7, 2026

Copy link
Copy Markdown

What & why

Breadcrumbs with a few short items collapses part of them into the popover immediately — even when there is plenty of free space and nothing overflows. It happens whenever the breadcrumbs' <ol> is sized to its content (shrink-wrap), e.g. when <Breadcrumbs> sits in a flex row without flex: 1 — a very common page-header layout.

This PR adds a Storybook story reproducing the issue: Components/Navigation/BreadcrumbsFalseCollapseOnContentWidth. No fix is included — the proposed solution is described below for your consideration.

Root cause

useCollapseChildren compares two measurements taken in different box models:

  • the container — container.getBoundingClientRect().width, which on the flex <ol> equals the sum of the items' margin-boxes;
  • each item — measured with getBoundingClientRect().width, i.e. the border-box, without margins.

The current item (.g-breadcrumbs__item_current) carries a negative inset margin (margin: -2px, paired with padding: 2px to inset the focus ring). So on a content-sized container the summed item widths exceed the container width by that margin, availableWidth becomes -4px < 0, and the list collapses. It is deterministic (measured Δ = exactly −4px), not a sub-pixel or real-overflow effect.

Proposed solution (not applied)

Measure items in the same box model as the container by including their horizontal margins in Breadcrumbs' getChildWidth:

 getChildWidth: (child) => {
-    const width = child.getBoundingClientRect().width;
+    const {marginLeft, marginRight} = window.getComputedStyle(child);
+    const width =
+        child.getBoundingClientRect().width + parseFloat(marginLeft) + parseFloat(marginRight);
     const maxWidth = child.dataset.current ? 200 : Infinity;
     return Math.min(maxWidth, width);
 },

With this change the summed item widths equal the container width (availableWidth === 0), so the list no longer collapses when it fits, while real overflow still collapses as before. I verified it locally against the story above.

Why scoped to Breadcrumbs and not the hook. The mismatch itself is more general — useCollapseChildren measures the container in its margin-box but each child in its border-box, so any consumer whose children carry margins can hit it. The other consumer, Tabs, already accounts for its item margins by passing them as the hook's gap, so making the hook's default measurement margin-aware would double-count them for Tabs. Hence the local fix. If you'd rather solve it once at the hook, that path would need to reconcile the two (e.g. document the box-model contract the hook expects, or make margin-vs-gap handling explicit).

Happy to open a follow-up with the fix + a regression test if you'd prefer.

@ykamendrovskiy
ykamendrovskiy requested a review from ValeraS as a code owner July 7, 2026 14:03
@sourcery-ai

sourcery-ai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Scopes a layout-measurement bug fix to Breadcrumbs by measuring each breadcrumb item in the same box model as the container (including horizontal margins), and adds a visual regression test ensuring Breadcrumbs do not collapse when they fit within a flex row with extra space.

File-Level Changes

Change Details Files
Measure breadcrumb item widths including horizontal margins to align with container measurement and prevent false collapsing.
  • Replace raw getBoundingClientRect width usage with a width calculation that adds parsed margin-left and margin-right from getComputedStyle.
  • Document in code comments that container width already accounts for item margins and explain the negative-margin current-item case.
  • Clamp the adjusted width using the existing maxWidth logic, preserving the 200px cap for the current item and Infinity for others.
src/components/Breadcrumbs/Breadcrumbs.tsx
Add a visual regression test ensuring Breadcrumbs stay expanded when they fit within a content-sized flex row.
  • Mount Breadcrumbs inside a fixed-width flex container where the ordered list shrink-wraps its content but still has surrounding free space.
  • Assert that all breadcrumb items remain visible (expected count 5).
  • Assert that the collapse menu element is not rendered (expected count 0).
  • Tag the new test as a smoke test and document the regression scenario in comments.
src/components/Breadcrumbs/__tests__/Breadcrumbs.visual.test.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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • When summing horizontal margins in getChildWidth, consider defensively normalizing marginLeft/marginRight (e.g., treating NaN or non-pixel values as 0) so that unexpected computed styles (like auto) don’t propagate NaN and break the collapse logic.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- When summing horizontal margins in `getChildWidth`, consider defensively normalizing `marginLeft`/`marginRight` (e.g., treating `NaN` or non-pixel values as `0`) so that unexpected computed styles (like `auto`) don’t propagate `NaN` and break the collapse logic.

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.

@ykamendrovskiy
ykamendrovskiy force-pushed the fix/breadcrumbs-false-collapse branch from a263a92 to 764ff01 Compare July 7, 2026 14:19
@ykamendrovskiy ykamendrovskiy changed the title fix(Breadcrumbs): prevent false collapse when the list fits its container chore(Breadcrumbs): add story reproducing false collapse on content-sized container Jul 7, 2026
…ized container

Adds a Storybook story showing Breadcrumbs collapse into the "…" menu even
though nothing overflows, whenever the <ol> is sized to its content (a flex
child without `flex: 1`). See the PR description for the root cause and a
proposed fix.
@ykamendrovskiy
ykamendrovskiy force-pushed the fix/breadcrumbs-false-collapse branch from 764ff01 to 4bb613a Compare July 7, 2026 14:24
@gravity-ui

gravity-ui Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Preview is ready.

@gravity-ui

gravity-ui Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🎭 Component Tests Report is ready.

@ykamendrovskiy

Copy link
Copy Markdown
Author

hey guys, will you check the preview please?
@korvin89 @ValeraS

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