Skip to content

Scale sidebar workspace group header with sidebar font size (#5398) - #5401

Merged
austinywang merged 3 commits into
mainfrom
issue-5398-sidebar-group-header-scale
Jun 5, 2026
Merged

austinywang merged 3 commits into
mainfrom
issue-5398-sidebar-group-header-scale

Conversation

@austinywang

@austinywang austinywang commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #5398. cmux's sidebar font size is configurable via sidebar-font-size, and the workspace rows already scale with it — but the workspace group/folder header (the collapsible row with the chevron, folder icon, group name, unread badge, and + button) hardcoded every font size and frame, so enlarging the sidebar font left the header small and mismatched against the rows beneath it.

Root cause

SidebarWorkspaceGroupHeaderView (Sources/SidebarWorkspaceGroupHeaderView.swift) hardcoded every font (.system(size: 9/10/11)) and frame (14x14, 18x18) and never received the sidebar font scale. The workspace-row path threads settings.sidebarFontScale (= SidebarTabItemFontScale.scale(for:), 1.0 at the default size) into TabItemView and multiplies every size by it. The header is built at VerticalTabsSidebar+WorkspaceGroups.swift:77, where settings is already in scope, but the scale was never passed in.

Fix

  • Extracted the header's sizes/frames/badge padding into a pure, testable SidebarWorkspaceGroupHeaderMetrics value type that multiplies each base size by fontScale.
  • Added let fontScale: CGFloat to SidebarWorkspaceGroupHeaderView and included it in the Equatable == so a font-size change invalidates the header under the LazyVStack.
  • Threaded the existing settings.sidebarFontScale in at the call site — reusing the single scaling path that already feeds TabItemView, not adding a second one.
  • The header and the workspace rows now grow at the same rate.

The outer/inner HStack spacings stay fixed, matching TabItemView (which also keeps fixed spacing), so the row layout stays stable while glyphs/frames scale.

Tests

Two-commit red/green structure (SidebarWorkspaceGroupHeaderMetricsTests, Swift Testing):

  • Commit 1 extracts the metrics helper reflecting the current unscaled behavior plus a behavior-level test asserting the metrics scale at default (1.0) and enlarged (2.0) scales, and that the header reuses SidebarTabItemFontScale — CI goes red.
  • Commit 2 makes the metrics multiply by fontScale and wires the scale into the view + call site — CI goes green.

Test file is wired into the cmux unit test target in project.pbxproj (lint-pbxproj-test-wiring passes, 152 files).

Localization

No new user-facing strings.

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Note

Low Risk
Localized SwiftUI sizing and equatable snapshot changes for the group header, with unit tests and no auth or data-path changes.

Overview
Fixes workspace group/folder headers staying at fixed sizes when sidebar-font-size is increased, so they no longer look smaller than the workspace rows below them.

Introduces SidebarWorkspaceGroupHeaderMetrics with base design sizes multiplied by fontScale, and wires SidebarWorkspaceGroupHeaderView to use those metrics for chevron, icon, title, unread badge, and plus control instead of hardcoded .system(size:) and frames. The sidebar passes settings.sidebarFontScale (same path as TabItemView via SidebarTabItemFontScale) and includes fontScale in Equatable so font-size changes refresh the equatable header in the LazyVStack. Unit tests cover default, enlarged, and shrunk scaling plus shared scaling with row font scale.

Reviewed by Cursor Bugbot for commit 933425b. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Make the sidebar workspace group header scale with the configurable sidebar font size so it matches the workspace rows. Removes hardcoded sizes and uses the same scaling path as rows for consistent sizing.

  • Bug Fixes
    • Pass settings.sidebarFontScale into SidebarWorkspaceGroupHeaderView and include fontScale in Equatable to re-render on font-size change.
    • Centralize sizes in SidebarWorkspaceGroupHeaderMetrics, multiplying base values by the scale for icons, text, badge, and plus button.
    • Update the call site in VerticalTabsSidebar+WorkspaceGroups.swift; keep existing HStack spacings unchanged for stable layout.
    • Add SidebarWorkspaceGroupHeaderMetricsTests to verify scaling at default, enlarged, and shrunk sizes, and reuse of SidebarTabItemFontScale.

Written for commit 933425b. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Sidebar workspace group headers accept a font scale and adjust chevrons, icons, names, unread badges, and action buttons so sizing and padding scale consistently with user font preferences.
  • Tests

    • Added tests verifying header metric defaults and proportional scaling behavior across different font scales.

austinywang and others added 2 commits June 4, 2026 16:40
Extract the workspace group/folder header's font sizes, frames, and badge
padding into a pure SidebarWorkspaceGroupHeaderMetrics helper and add a
behavior-level test asserting the metrics scale with the sidebar font scale.

This commit captures only the current (unscaled) behavior plus the failing
test: the header still ignores the sidebar font scale, so the enlarged-scale
assertions go red. The fix follows in the next commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The collapsible workspace group/folder header (chevron, folder icon, group
name, unread badge, + button) hardcoded every font size and frame, so it
stayed small while the workspace rows grew with the configurable
sidebar-font-size.

Thread the existing sidebar font scale (settings.sidebarFontScale, the same
SidebarTabItemFontScale value that already feeds TabItemView) into
SidebarWorkspaceGroupHeaderView and drive every size through
SidebarWorkspaceGroupHeaderMetrics, which multiplies each base size by the
scale. fontScale joins the Equatable == so a font-size change invalidates the
header under the LazyVStack. No second scaling path is introduced; the header
and rows now grow at the same rate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 5, 2026 12:14am
cmux-staging Building Building Preview, Comment Jun 5, 2026 12:14am

@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds SidebarWorkspaceGroupHeaderMetrics to compute scaled sizes from fontScale; threads settings.sidebarFontScale into SidebarWorkspaceGroupHeaderView; the view uses metrics for chevron, icon, name, unread badge, and plus button sizing; tests verify proportional scaling.

Changes

Sidebar workspace group header font scaling

Layer / File(s) Summary
Metrics struct and scaling logic
Sources/SidebarWorkspaceGroupHeaderMetrics.swift
SidebarWorkspaceGroupHeaderMetrics defines design-time base* constants and computes scaled metrics by multiplying each base value by fontScale.
Header view font scale integration
Sources/SidebarWorkspaceGroupHeaderView.swift
View adds fontScale, includes it in Equatable, derives a metrics property, and refactors chevron, icon, name text, unread badge, and plus button styling to use metrics-driven font sizes, frames, and padding.
Settings wiring and project configuration
Sources/VerticalTabsSidebar+WorkspaceGroups.swift, cmux.xcodeproj/project.pbxproj
The header builder passes settings.sidebarFontScale to the view; the Xcode project file adds the metrics source and its tests to the app and test targets.
Metrics scaling validation tests
cmuxTests/SidebarWorkspaceGroupHeaderMetricsTests.swift
Unit tests validate that all header metrics equal base values at fontScale = 1, scale proportionally at other scales, and that the header name scale matches row scaling via SidebarTabItemFontScale.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • Ari4ka

Poem

🐰
I scaled each chevron, badge, and plus,
Nibbled old constants, made them adjust.
Fonts now grow when the sidebar grows,
Harmony hops where mismatch froze.
A tiny rabbit clap — all good, no fuss.

🚥 Pre-merge checks | ✅ 17 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (17 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: scaling the sidebar workspace group header with sidebar font size to fix issue #5398.
Linked Issues check ✅ Passed The PR fully addresses issue #5398 requirements: adds fontScale parameter to the header view, creates SidebarWorkspaceGroupHeaderMetrics to scale base sizes, threads settings.sidebarFontScale from the call site, and includes fontScale in Equatable. Comprehensive behavior-level tests verify scaling at default, enlarged, and shrunk sizes while reusing SidebarTabItemFontScale.
Out of Scope Changes check ✅ Passed All changes are directly in-scope: new SidebarWorkspaceGroupHeaderMetrics type, updates to SidebarWorkspaceGroupHeaderView for fontScale support, wiring at the call site, project configuration for new files, and comprehensive tests. No unrelated modifications detected.
Cmux Swift Actor Isolation ✅ Passed New metrics struct is a pure value type used only in a UI view, fitting allowed "small structs in MainActor UI types" case per review rules. No isolation issues found.
Cmux Swift Blocking Runtime ✅ Passed PR introduces only UI metric calculations with no blocking/timing synchronization. No semaphores, sleeps, locks, or delayed dispatch found in any modified source files.
Cmux No Hacky Sleeps ✅ Passed PR contains only Swift code; check applies to non-Swift runtime changes (TypeScript, JavaScript, shell, build/runtime scripts) per the rule file scope.
Cmux Algorithmic Complexity ✅ Passed PR adds O(1) metrics computation with scalar multiplications only; no collection scans, loops, or nested iterations. Reuses existing SidebarTabItemFontScale without algorithmic violations.
Cmux Swift Concurrency ✅ Passed PR introduces no legacy async patterns: no DispatchQueue, Combine state, completion handlers, or fire-and-forget Tasks. Changes are purely structural metrics and UI scaling.
Cmux Swift @Concurrent ✅ Passed PR introduces no async/await work, no @concurrent annotations, and correctly uses nonisolated on synchronous equality comparison; complies with Swift concurrent annotation rules.
Cmux Swift File And Package Boundaries ✅ Passed New 76-line metrics struct has single responsibility; modified files add ≤6 net lines; tests are independent and behavior-level; no mixed responsibilities detected.
Cmux Swift Logging ✅ Passed All new code in the PR contains no logging violations. New files have no logging; modified code added no logging statements. Pre-existing debug log guarded by #if DEBUG.
Cmux User-Facing Error Privacy ✅ Passed PR contains only UI scaling logic with numeric constants and existing localized strings. No new errors, alerts, API interactions, or sensitive information exposed in user-facing context.
Cmux Full Internationalization ✅ Passed PR adds no new user-facing strings; only scales existing UI elements via internal metrics and reuses existing localized string keys.
Cmux Swiftui State Layout ✅ Passed PR follows SwiftUI state layout rules: pure value-type metrics, fontScale snapshot parameter in view, only private @State for local UI state, no store references in row subtrees.
Cmux Architecture Rethink ✅ Passed Small correctness fix: pure value metrics type with clear invariant, single scaling path reuse, no timing repairs or observers, no split lifecycle ownership.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR modifies only a sidebar view component to scale with font size; contains no NSWindow, NSPanel, NSWindowController, SwiftUI Window/WindowGroup, or new auxiliary window creation code.
Description check ✅ Passed The PR description comprehensively covers all required sections: clear problem statement, root cause analysis, detailed fix explanation, testing approach with red/green structure, and localization note.

✏️ 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 issue-5398-sidebar-group-header-scale

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.

@greptile-apps

greptile-apps Bot commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the sidebar workspace group/folder header not scaling with the configurable sidebar-font-size, while workspace rows already did scale via settings.sidebarFontScale. The fix extracts all header sizing into a pure SidebarWorkspaceGroupHeaderMetrics value type, adds fontScale to SidebarWorkspaceGroupHeaderView, includes it in the manual Equatable implementation (preserving the .equatable() optimization under LazyVStack), and threads settings.sidebarFontScale in at the single call site.

  • New SidebarWorkspaceGroupHeaderMetrics: A 76-line pure value type holding scaled font sizes, frame edges, and badge padding — all base constants multiplied by fontScale, reusing the same SidebarTabItemFontScale path as TabItemView so header and rows grow at the same rate.
  • View + call-site wiring: SidebarWorkspaceGroupHeaderView gains let fontScale: CGFloat, replaces every hardcoded .system(size:) / .frame() / .padding() with metrics.*, and VerticalTabsSidebar+WorkspaceGroups.swift passes settings.sidebarFontScale.
  • Tests (SidebarWorkspaceGroupHeaderMetricsTests): Cover default scale (1.0), enlarged (2.0), shrunk (0.5), and verify shared scaling path with SidebarTabItemFontScale.

Confidence Score: 5/5

Safe to merge — a purely presentational change confined to the sidebar header with no data, auth, or business-logic impact.

The change is narrow and well-contained: a new pure value type extracts the scaling math, the view adds one immutable property and wires it through the existing single scaling path, and fontScale is correctly included in the manual Equatable implementation so the .equatable() optimisation under LazyVStack still triggers on font-size changes. No new state, no blocking primitives, no actor isolation issues, no new user-facing strings, and unit tests cover the key scaling invariants.

No files require special attention.

Important Files Changed

Filename Overview
Sources/SidebarWorkspaceGroupHeaderMetrics.swift New pure value type centralising all header font/frame/padding sizing; each metric is a base constant multiplied by fontScale.
Sources/SidebarWorkspaceGroupHeaderView.swift Adds fontScale let + manual Equatable entry; replaces hardcoded sizes with metrics.* properties; no new state, no layout instability introduced.
Sources/VerticalTabsSidebar+WorkspaceGroups.swift One-line addition passing settings.sidebarFontScale into the header; correctly reuses the existing sidebarFontScale path already used by TabItemView.
cmuxTests/SidebarWorkspaceGroupHeaderMetricsTests.swift Four Swift Testing cases cover default, enlarged, shrunk scales, and shared-path invariant; clean and complete for the extracted logic.
cmux.xcodeproj/project.pbxproj Correctly wires both new files into their respective targets (app Sources and cmuxTests); no structural anomalies.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[settings.sidebarFontScale] -->|"fontScale"| B[SidebarWorkspaceGroupHeaderView]
    A -->|"sidebarFontScale"| C[TabItemView]
    B --> D["SidebarWorkspaceGroupHeaderMetrics(fontScale:)"]
    D --> E[chevronFontSize / chevronFrame]
    D --> F[iconFontSize / iconFrame]
    D --> G[nameFontSize]
    D --> H[unreadFontSize / unreadHPad / unreadVPad]
    D --> I[plusFontSize / plusFrame]
    J[SidebarTabItemFontScale.scale] -->|"produces fontScale"| A
    B -->|".equatable() — fontScale in =="| K[LazyVStack invalidation]
Loading

Reviews (2): Last reviewed commit: "Add scale-down coverage for sidebar grou..." | Re-trigger Greptile

@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 `@cmuxTests/SidebarWorkspaceGroupHeaderMetricsTests.swift`:
- Around line 10-52: Add a new test in SidebarWorkspaceGroupHeaderMetricsTests
that verifies scaling down (fontScale < 1) by creating
SidebarWorkspaceGroupHeaderMetrics(fontScale: 0.5) and asserting the key metrics
(chevronFontSize, chevronFrame, iconFontSize, iconFrame, nameFontSize,
unreadFontSize, unreadHorizontalPadding, unreadVerticalPadding, plusFontSize,
plusFrame) equal their corresponding base values multiplied by 0.5; name the
test metricsScaleProportionallyWhenSidebarFontReduced to mirror
metricsScaleProportionallyWhenSidebarFontEnlarged and keep the same assertion
style (`#expect`) used in the suite.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 85922c56-ff82-4e1e-9878-1e4dbe5bc2bc

📥 Commits

Reviewing files that changed from the base of the PR and between 5b6325d and f080b16.

📒 Files selected for processing (5)
  • Sources/SidebarWorkspaceGroupHeaderMetrics.swift
  • Sources/SidebarWorkspaceGroupHeaderView.swift
  • Sources/VerticalTabsSidebar+WorkspaceGroups.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/SidebarWorkspaceGroupHeaderMetricsTests.swift

Comment thread cmuxTests/SidebarWorkspaceGroupHeaderMetricsTests.swift

@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 5 files

You’re at about 98% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Re-trigger cubic

Address CodeRabbit review: assert the metrics shrink proportionally at
fontScale < 1 (0.5) in addition to the enlarged (2.0) and default (1.0) cases,
covering the full proportional-scaling contract.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview – cmux — 933425b2 Deployed Jun 5, 2026 by vercel[bot]
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.

Sidebar group/folder header does not scale with the sidebar font size setting

1 participant