Skip to content

fix(layers): truncate long layer names - #1591

Merged
giswqs merged 5 commits into
mainfrom
fix/issue-1586-truncate-layer-names
Jul 31, 2026
Merged

fix(layers): truncate long layer names#1591
giswqs merged 5 commits into
mainfrom
fix/issue-1586-truncate-layer-names

Conversation

@giswqs

@giswqs giswqs commented Jul 31, 2026

Copy link
Copy Markdown
Member

Summary

  • constrain the Layers scroll viewport so long content cannot widen the panel
  • allow layer names to shrink and truncate while preserving the type badge and opacity controls
  • add a Playwright regression test for long renamed layers

Verification

  • npm run build
  • npx playwright test e2e/layer-panel.spec.ts --grep "long layer names"
  • pre-commit run --files apps/geolibre-desktop/src/components/panels/LayerPanel.tsx packages/ui/src/components/scroll-area.tsx e2e/layer-panel.spec.ts
  • verified with us_cities.geojson in light and dark themes at default and narrowed Layers panel widths

Fixes #1586

Summary by CodeRabbit

  • Bug Fixes

    • Prevented horizontal overflow in the layer panel.
    • Long layer names now truncate with an ellipsis while keeping layer type labels visible.
    • Preserved panel dimensions and ensured content remains within the scroll area.
  • Tests

    • Added end-to-end coverage for exceptionally long layer names and panel layout behavior.

Copilot AI review requested due to automatic review settings July 31, 2026 18:54

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@giswqs, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 14 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9bd685d6-28ee-401a-abef-22be34c46d75

📥 Commits

Reviewing files that changed from the base of the PR and between 601a4cc and e0c1d8b.

📒 Files selected for processing (2)
  • apps/geolibre-desktop/src/components/panels/LayerPanel.tsx
  • e2e/layer-panel.spec.ts
📝 Walkthrough

Walkthrough

The layer panel now constrains group, viewport, and card widths. Long layer names shrink and truncate without displacing type labels or expanding the panel. End-to-end coverage verifies ellipsis styling and layout bounds.

Changes

Layer panel overflow handling

Layer / File(s) Summary
Layer-list width constraints
apps/geolibre-desktop/src/components/panels/LayerPanel.tsx
Group headers and the scroll viewport use full-width, minimum-width, and shrinkable sizing.
Layer-card truncation and validation
apps/geolibre-desktop/src/components/panels/LayerPanel.tsx, e2e/layer-panel.spec.ts
Layer cards and header contents shrink within the panel. Layer names truncate while type labels remain visible. End-to-end coverage checks ellipsis styling, viewport containment, row bounds, and horizontal overflow.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: pythonbass, craun718

Poem

A rabbit trims names with a CSS glow,
Long labels shrink where the card must go.
Type tags stay clear, the panel stays sound,
Ellipses keep every edge tightly bound.
Hop, hop—overflow is gone!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: truncating long layer names.
Linked Issues check ✅ Passed The changes truncate long layer names and preserve the opacity controls and layer type badge required by issue #1586.
Out of Scope Changes check ✅ Passed The code and end-to-end test changes directly support the linked issue and stated panel layout objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 fix/issue-1586-truncate-layer-names

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.

@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🔍 Cloudflare PR preview

Item Value
Site https://e17e9743.geolibre-preview.pages.dev
Demo app https://e17e9743.geolibre-preview.pages.dev/demo/
Commit e0c1d8b

Comment thread apps/geolibre-desktop/src/components/panels/LayerPanel.tsx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Code review

Bugs

  • overflow-hidden added to the layer-row container (LayerPanel.tsx:2696) clips the absolutely-positioned drag-reorder drop indicators (-top-1/-bottom-1 bars) that are direct children of the same element and intentionally render outside its border box to mark the drop position between rows — they'll become invisible during a drag. overflow-x-hidden achieves the intended horizontal-growth fix without this side effect. Posted inline with a suggested fix. Confidence: high.

Security

  • None found.

Performance

  • None found; changes are pure CSS/layout, no new re-renders or expensive computation.

Quality

  • The [&>div]:!block [&>div]:!w-full [&>div]:!min-w-0 selector in scroll-area.tsx reaches into Radix ScrollArea's internal, unexported viewport-wrapper markup (the display: table content div Radix injects for scroll-size measurement). It's scoped correctly as an opt-in prop so it doesn't affect other ScrollArea consumers, but it will silently stop working (no build error) if a future @radix-ui/react-scroll-area bump changes that internal structure. Confidence: medium.
  • Otherwise the Tailwind min-w-0/flex-1/shrink-0 changes are the standard, correct fix for the classic flexbox "truncate doesn't work without min-width: 0 on ancestors" issue, and are well-targeted to just the layer name row.

CLAUDE.md

  • The project's established convention (documented for MAX_VECTOR_BYTES, MAP_PANEL_SELECTOR, propertySpecFor, etc.) is that any code depending on an unexported internal detail of a third-party package gets a CLAUDE.md note instructing future contributors to re-check it on version bumps. The new [&>div] selector against Radix's internal viewport markup is exactly this pattern (see Quality above) but isn't documented that way — a maplibre-gl-plugins-style Dependabot bump of @radix-ui/react-scroll-area could silently break the truncation fix with no signal. Confidence: low-medium (this is a convention observed elsewhere in the repo, not an explicit rule that all such couplings must be documented).
  • No other CLAUDE.md guidance (i18n, RTL logical properties, etc.) is implicated by this diff, and none is violated — all new classes are logical/non-directional and no user-facing strings were touched outside existing i18n keys.

- Preserve drag-reorder indicators by removing unnecessary overflow clipping.
- Document the Radix content-wrapper sizing dependency.
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🔍 GitHub Pages PR preview

Item Value
Site https://opengeos.org/pages-preview/GeoLibre/pr-1591/
Demo app https://opengeos.org/pages-preview/GeoLibre/pr-1591/demo/
Commit e0c1d8b

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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/geolibre-desktop/src/components/panels/LayerPanel.tsx`:
- Line 2543: Update the viewportClassName Tailwind utilities to use v4 important
suffix syntax, replacing the legacy [&>div]:!block, [&>div]:!w-full, and
[&>div]:!min-w-0 forms with the corresponding block!, w-full!, and min-w-0!
utilities while preserving the [&>div] selector.

In `@e2e/layer-panel.spec.ts`:
- Around line 73-81: Update the assertions around renamedRow and panel to verify
the panel itself remains within the viewport after renaming, not merely that the
row fits inside it. Capture or compare the panel’s width before and after the
rename, or validate both panel edges against the viewport; include the left-edge
boundary check so RTL layouts are covered.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: 829c9979-cd95-4968-95d8-0323d98a0945

📥 Commits

Reviewing files that changed from the base of the PR and between 62da3df and 21c498a.

📒 Files selected for processing (3)
  • apps/geolibre-desktop/src/components/panels/LayerPanel.tsx
  • e2e/layer-panel.spec.ts
  • packages/ui/src/components/scroll-area.tsx

Comment thread apps/geolibre-desktop/src/components/panels/LayerPanel.tsx Outdated
Comment thread e2e/layer-panel.spec.ts

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/geolibre-desktop/src/components/panels/LayerPanel.tsx`:
- Line 2699: Update the card className width logic near the grouped card
rendering so cards with group set do not combine w-full with ms-4 and exceed the
scroll content width. Use automatic width for grouped cards or subtract the
indentation amount, while preserving full width for ungrouped cards.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: 505ba0b2-6129-4e03-9247-34f48e8351b0

📥 Commits

Reviewing files that changed from the base of the PR and between 21c498a and c52caa7.

📒 Files selected for processing (1)
  • apps/geolibre-desktop/src/components/panels/LayerPanel.tsx

Comment thread apps/geolibre-desktop/src/components/panels/LayerPanel.tsx Outdated
Comment thread apps/geolibre-desktop/src/components/panels/LayerPanel.tsx Outdated
Comment thread apps/geolibre-desktop/src/components/panels/LayerPanel.tsx
@github-actions

Copy link
Copy Markdown
Contributor

Both inline comments posted successfully.

Code review

Bugs

  • The fix isn't applied to group headers: renderGroupHeader has the identical flex items-center gap-1 row + flex-1 truncate name-span pattern that this PR fixes for individual layers, but neither element got the min-w-0 treatment. Since group names are renamable the same way, a long group name likely still reproduces the panel-widening bug ([Bug]: UI elements get "hung up" on long names, instead of names getting truncated #1586) via a different path, and the new e2e test doesn't cover it. Confidence: medium-high (verified via code reading, not a live browser).

Security

  • None found.

Performance

  • None found; the CSS-only changes have no runtime cost of note.

Quality

  • The new viewportClassName prop on the shared ScrollArea (packages/ui/src/components/scroll-area.tsx) duplicates a fix already applied elsewhere for the identical Radix display:table viewport quirk (StoryMapPanel.tsx, issue Feature Request: Seamless Navigation Workflow for Story Map Creation #775), which instead uses a [&_[data-radix-scroll-area-viewport]>div]:!block selector directly on className without touching the shared primitive. Two different idioms now exist in the codebase for the same problem. Confidence: medium (a real inconsistency, but a matter of taste/maintainability rather than correctness).
  • Minor: some of the added width utilities (w-full/max-w-full on the row card, w-full/min-w-0 on the space-y-1 p-2 wrapper) sit on plain block-level children rather than flex/grid items, where they're redundant (block children already fill the containing block's width). Harmless, low priority — not filed as an inline comment.

CLAUDE.md

  • No violations found. UI strings are unchanged (no new user-facing text), no map/tile-host or Tauri CSP changes, no node_modules edits, and the scoped pre-commit run --files ... verification mentioned in the PR body matches the guidance for this repo.

Overall the core fix (Radix viewport table-sizing override plus min-w-0/shrink-0 down the flex chain, verified against the actual Radix 1.2.x ScrollAreaViewport implementation) is technically sound and the new Playwright test meaningfully exercises it, since the Layers panel width is driven by a fixed --layer-panel-width CSS variable rather than by content, so the bounding-box assertion is a valid regression guard.

giswqs added 2 commits July 31, 2026 15:05
- Keep grouped layer cards within the indented panel width.
- Assert the Layers panel bounds stay unchanged after renaming.
- Use Tailwind v4 important modifier syntax.
- Reuse the established scoped Radix viewport selector.
- Constrain long group names and grouped layer rows within the panel.

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/layer-panel.spec.ts`:
- Around line 77-92: Extend the visibility predicate around renamedRow to locate
the layer type badge and opacity slider, assert both are visible, and verify
each is contained within renamedRow alongside the existing panel bounds and
truncation checks.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: 778d9f9a-d58b-4d37-8f75-6b1b057c4e2f

📥 Commits

Reviewing files that changed from the base of the PR and between c52caa7 and 258ffa3.

📒 Files selected for processing (2)
  • apps/geolibre-desktop/src/components/panels/LayerPanel.tsx
  • e2e/layer-panel.spec.ts

Comment thread e2e/layer-panel.spec.ts Outdated
Comment thread apps/geolibre-desktop/src/components/panels/LayerPanel.tsx
@github-actions

Copy link
Copy Markdown
Contributor

Code review

Bugs: None found. The width/margin interplay for grouped vs. ungrouped rows (group ? "ms-4" : "w-full") is correct — omitting w-full on grouped rows lets width: auto fill the container minus the ms-4 margin, avoiding a 100% + margin overflow. (Medium confidence — left an inline maintainability note so this doesn't get "fixed" incorrectly later.)

Security: None — purely CSS/layout changes, no new user input handling.

Performance: None — no additional renders, listeners, or expensive computations introduced.

Quality:

  • The [&_[data-radix-scroll-area-viewport]>div]:...! override targets an undocumented, unexported internal DOM structure of @radix-ui/react-scroll-area (the injected display:table measurement wrapper). This is analogous to the several other "internal library detail" mirrors CLAUDE.md already tracks (e.g. MAP_PANEL_SELECTOR, MAX_VECTOR_BYTES) — a future Radix version bump could silently change that markup and reintroduce the panel-widening bug with no build error. The new Playwright test (long layer names truncate without widening the layer panel) does serve as the regression guard for this drift, similar to how the other mirrors are backed by a failing test, so the risk is mitigated, just worth being aware of. Low confidence this needs any change now.
  • Left one inline suggestion: add a short comment explaining why grouped rows must not receive w-full alongside ms-4, since the reasoning is subtle and easy to undo by a well-meaning future edit (medium confidence, non-blocking).
  • The PR's CodeRabbit-generated summary claims a new feature "customizing scroll area viewport styling," implying a prop was added to packages/ui/src/components/scroll-area.tsx, but the actual diff only touches LayerPanel.tsx and the e2e test — scroll-area.tsx is unchanged. This looks like a stale/inaccurate auto-generated summary rather than a code problem, but worth a glance before merge in case an earlier revision's approach was intended.

CLAUDE.md: No violations found. The change stays within apps/geolibre-desktop, doesn't touch any of the "mirror" constants CLAUDE.md calls out, doesn't add new external tile/map hosts, uses logical Tailwind utilities (ms-4) consistent with the RTL-mirroring convention, and adds Playwright coverage under e2e/ as instructed for UI regressions.

- Assert the layer type badge and opacity slider remain visible and contained.
- Document why grouped rows intentionally omit full-width sizing.
@giswqs
giswqs merged commit d71b750 into main Jul 31, 2026
30 checks passed
@giswqs
giswqs deleted the fix/issue-1586-truncate-layer-names branch July 31, 2026 19:20
Comment on lines +2541 to +2546
<ScrollArea
className="flex-1 [&_[data-radix-scroll-area-viewport]>div]:block! [&_[data-radix-scroll-area-viewport]>div]:w-full! [&_[data-radix-scroll-area-viewport]>div]:min-w-0!"
// Radix measures scroll content with an injected display:table
// wrapper. Opt this viewport into block sizing so long layer names
// cannot establish a wider min-content table.
>

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.

This CSS workaround targets an undocumented Radix internal (data-radix-scroll-area-viewport > div gets display:table from an inline style to support horizontal auto-sizing). It's a real and known quirk, and the override is technically sound (the !important suffix is needed to beat Radix's inline style), but two things worth considering:

  1. Scope: this is applied only at this one ScrollArea call site. A quick grep shows ~22 other components in this app also render ScrollArea (StylePanel, BrowserPanel, StyleManagerPanel, AttributeTable, etc.), several of which also truncate long text inside flex rows. If any of them hit the same "table wrapper lets truncated content force a min-content table width" issue, they'll need to duplicate this exact snippet. Moving the override into the shared packages/ui/src/components/scroll-area.tsx primitive (gated behind a prop, or simply as the default) would fix it once for every consumer instead of per call site.
  2. Fragility: since this couples to @radix-ui/react-scroll-area's internal DOM structure rather than a public API, a future bump could change/remove the wrapper div and silently reintroduce the panel-widening regression with no compile-time signal — only the new e2e test would catch it (and only if test:e2e runs on every dependency bump PR).

Not blocking — just flagging as a maintainability trade-off given how many other panels share this primitive.

@github-actions

Copy link
Copy Markdown
Contributor

Code review

Bugs: None found. The min-w-0/max-w-full additions on the flex rows and name spans correctly address the classic "flex item won't shrink below its content's intrinsic width" issue that blocks truncate from working, and the ScrollArea override correctly neutralizes Radix's inline display:table viewport wrapper (which is what let a long name's min-content width propagate up and drag the type badge/opacity slider along with it). Confidence: high, based on reading the surrounding flex/table layout and the actual Radix implementation detail being targeted.

Security: None applicable — pure CSS/layout change plus a Playwright test.

Performance: No concerns; the change is class-name-only, no new renders, listeners, or observers.

Quality:

  • The Radix-viewport CSS workaround (apps/geolibre-desktop/src/components/panels/LayerPanel.tsx:2541-2546) is scoped to this one ScrollArea call site, but ~22 other components in the app also render ScrollArea, some with truncated text in flex rows that could hit the same issue. Consider moving this fix into the shared packages/ui/src/components/scroll-area.tsx primitive so every consumer benefits rather than each needing to rediscover and copy this snippet. Also worth noting: it couples to an undocumented Radix internal DOM structure ([data-radix-scroll-area-viewport]>div with an inline display:table), so a future @radix-ui/react-scroll-area bump could silently reintroduce the regression — only the new e2e test would catch it, and only if test:e2e runs on dependency-bump PRs. Confidence: medium (architectural suggestion, not a defect).
  • Minor: the PR description's verification steps reference running pre-commit against packages/ui/src/components/scroll-area.tsx, but that file isn't touched in this diff (the fix ended up scoped locally in LayerPanel.tsx instead) — likely a stale leftover from an earlier iteration of the fix. Confidence: low, cosmetic only.

CLAUDE.md: No violations — logical ms-4 (not ml-) is preserved for RTL, no new user-facing strings requiring i18n, and no edits to node_modules or generated catalogs.

The new e2e test (e2e/layer-panel.spec.ts) is well constructed: it directly asserts the panel's bounding box doesn't move/grow after renaming to a long name, that the name/type-badge/slider stay within the row and panel bounds, and that the name element actually overflows its box (scrollWidth > clientWidth) to prove truncation — rather than just checking visibility, which would pass even if the bug still existed.

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.

[Bug]: UI elements get "hung up" on long names, instead of names getting truncated

2 participants