fix: scale selection label arrow for narrow labels#165
Conversation
The arrow (16px wide) overflowed labels with short tag names like "p". Arrow size now scales based on the inner panel width via a shared getArrowSize utility, and label positioning uses the actual arrow height to eliminate gaps. Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
@react-grab/cli
grab
@react-grab/ami
@react-grab/amp
@react-grab/claude-code
@react-grab/codex
@react-grab/cursor
@react-grab/droid
@react-grab/gemini
@react-grab/opencode
react-grab
@react-grab/relay
@react-grab/utils
commit: |
There was a problem hiding this comment.
Critical timing bug: Arrow renders before panelWidth is measured, causing scaling to fail on initial render.
| position={arrowPosition()} | ||
| leftPercent={computedPosition().arrowLeftPercent} | ||
| leftOffsetPx={computedPosition().arrowLeftOffset} | ||
| labelWidth={panelWidth()} |
There was a problem hiding this comment.
Critical bug: The Arrow component renders before panelRef is assigned (line 405). When Arrow initially renders, panelWidth() returns 0, causing getArrowSize(0) to return the default ARROW_HEIGHT_PX (8px) instead of the scaled size.
The arrow will only get the correct size on subsequent re-renders after measureContainer runs. On first render with short labels, you'll still see the overflow issue that this PR aims to fix.
Solution: Move the Arrow after the panelRef div, or add a conditional render that waits for panelWidth() > 0.
| const selectionBottom = bounds.y + bounds.height; | ||
| const selectionTop = bounds.y; | ||
|
|
||
| const actualArrowHeight = getArrowSize(panelWidth()); |
There was a problem hiding this comment.
This uses panelWidth() which is 0 during initial render. The positioning calculations will use the wrong arrow height (8px fallback) on first render, potentially causing the gap between arrow and panel that the PR description says it eliminates.
| const scaledSize = labelWidth * ARROW_MAX_LABEL_WIDTH_RATIO; | ||
| return Math.max(ARROW_MIN_SIZE_PX, Math.min(ARROW_HEIGHT_PX, scaledSize)); |
There was a problem hiding this comment.
For very narrow labels (15px wide), this produces 3px which gets clamped to 4px. Is 4px arrow still too large for the narrowest cases? The ratio and minimum should be validated against actual short tag names like p, b, i mentioned in the test plan.
|
|
||
| export const ARROW_HEIGHT_PX = 8; | ||
| export const ARROW_MIN_SIZE_PX = 4; | ||
| export const ARROW_MAX_LABEL_WIDTH_RATIO = 0.2; |
There was a problem hiding this comment.
The 20% ratio seems arbitrary. For a 30px label, arrow becomes 6px. Was this tested visually? Consider documenting the rationale.
Additional Finding: Context Menu Missing Same FixThe
Recommendation: Apply the same pattern to context-menu.tsx:
This would ensure consistent arrow sizing across both selection labels and context menus. |
…denybai#165) The arrow (16px wide) overflowed labels with short tag names like "p". Arrow size now scales based on the inner panel width via a shared getArrowSize utility, and label positioning uses the actual arrow height to eliminate gaps. Co-authored-by: Cursor <cursoragent@cursor.com>

Summary
pgetArrowSizeutility used by both theArrowcomponent and label positioning logicTest plan
p,b,i) and verify the arrow fits within the labeldiv,section) and verify the arrow remains the default sizeMade with Cursor
Note
Low Risk
UI-only sizing/positioning changes scoped to the selection label arrow, with minimal blast radius and no data/security impact.
Overview
Fixes selection label arrows overflowing narrow labels by scaling the CSS triangle size dynamically via a shared
getArrowSizeutility.SelectionLabelnow measures the inner panel width and uses the computed arrow height for above/below positioning, whileArrowPropsgains an optionallabelWidthto drive the new sizing behavior.Written by Cursor Bugbot for commit 7677809. This will update automatically on new commits. Configure here.
Summary by cubic
Scaled the selection label arrow to fit narrow labels and used the real arrow height for positioning to remove the gap. Wide labels keep the default arrow size.
Bug Fixes
Refactors
Written for commit 7677809. Summary will update on new commits.