Skip to content

style(desktop): polish v2 diff pane header, file path, and unmodified-lines strip#3899

Merged
Kitenite merged 1 commit intomainfrom
style-changes-pane
Apr 30, 2026
Merged

style(desktop): polish v2 diff pane header, file path, and unmodified-lines strip#3899
Kitenite merged 1 commit intomainfrom
style-changes-pane

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Apr 30, 2026

Summary

  • Each file header in the v2 Changes pane now matches the sidebar ChangesHeader chrome (border-y + bg-muted/30), with the StatusIndicator moved next to the +/- diff stats.
  • Filename is split into directory + basename so the basename always stays visible — the directory truncates with instead of hiding the file you actually care about.
  • Added a Copy path button next to the filename and removed the Copy file contents button.
  • Diff body now blends with the terminal pane surface (overrides pierre/diffs' inline --diffs-light-bg / --diffs-dark-bg on [data-diff]).
  • Flattened the "N unmodified lines" expander flush to the pane edges (covers both line-info and line-info-basic separators, kills the wrapper / content / expand-button rounding and inline gaps).
  • Extracted the inline DiffViewModeToggle from usePaneRegistry.tsx into a co-located DiffPaneHeaderExtras (matches the FilePaneHeaderExtras / CommentPaneHeaderExtras pattern); standardized icon-button padding (p-0.5p-1); replaced the hand-rolled "Show diff" button with <Button size=\"xs\" variant=\"outline\">; loading state distinguishes "Loading…" from "No changes".

Test plan

  • Open a workspace, open the Changes diff pane — header bar reads as a single muted strip with top + bottom rules
  • Resize the pane narrow with a deeply nested file open — the directory part truncates but the basename stays readable
  • Click Copy path on a file header — clipboard gets the path; icon flips to a check + tooltip reads "Copied" briefly
  • Confirm Copy file contents button is gone; Discard, Viewed, eye-toggle still work
  • StatusIndicator (added/modified/deleted glyph) sits to the left of the +/- counters on the right
  • Diff body background matches the terminal pane background (not pure black)
  • Click an "N unmodified lines" expander on both split and unified views — strip is flush to both pane edges, no rounded corners
  • Open a file with a deep path — header doesn't wrap to two rows

Summary by cubic

Polishes the v2 Changes diff pane for clearer headers and consistent styling with the sidebar and terminal. Adds a Copy path action, better path display, and small UX tweaks for a smoother review experience.

  • New Features

    • File headers match ChangesHeader (border-y + muted bg); status icon sits next to the +/- counters.
    • Paths split into dir + basename so the filename stays visible; added Copy path; removed Copy file contents.
    • Diff background matches the terminal surface; “N unmodified lines” strip is flush to pane edges.
    • Empty state shows “Loading…” while fetching, otherwise “No changes”.
  • Refactors

    • Extracted DiffPaneHeaderExtras for the diff view toggle (replaces inline toggle).
    • Standardized icon-button padding and switched “Show diff” to <Button size="xs" variant="outline">.

Written for commit eb74dce. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • Added "Copy path" button to diff file headers for quick clipboard access
    • Introduced diff view mode toggle (unified/split) for customizable viewing
  • Bug Fixes

    • Fixed diff header layout to ensure filenames remain visible in narrow widths
  • Refactor

    • Migrated UI components to design system for improved visual consistency
    • Enhanced diff pane styling with terminal theming integration
    • Improved empty state messaging in diff view

…-lines strip

- Match ChangesHeader chrome on each file header (border-y + bg-muted/30)
- Split filename into dir + basename so the basename always stays visible
  on narrow widths instead of being truncated behind ellipsis
- Add a Copy path button next to the filename, drop Copy file contents
- Move StatusIndicator next to the +/- diff stats
- Blend diff body with the terminal pane surface color
- Flatten the "N unmodified lines" expander flush to the pane edges
  (kills pierre/diffs' wrapper / content / expand-button rounding +
  inline gaps for both line-info and line-info-basic separators)
- Standardize icon-button padding, drop the inline DiffViewModeToggle
  in favour of a co-located DiffPaneHeaderExtras component
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9e6005ae-2477-4fd5-8967-0f5ba06cb44c

📥 Commits

Reviewing files that changed from the base of the PR and between 03be01e and eb74dce.

📒 Files selected for processing (10)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/StatusIndicator/StatusIndicator.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/DiffPane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileEntry/DiffFileEntry.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffPaneHeaderExtras/DiffPaneHeaderExtras.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffPaneHeaderExtras/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/utils/gitDecorationColors/gitDecorationColors.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/utils/gitDecorationColors/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/usePaneRegistry.tsx

📝 Walkthrough

Walkthrough

Changes introduce a new DiffPaneHeaderExtras component for diff view mode selection and refactor diff pane rendering to use terminal theming. DiffFileHeader gains internal copy-to-clipboard functionality and improved layout, while UI controls migrate to component library variants.

Changes

Cohort / File(s) Summary
StatusIndicator Enhancement
StatusIndicator.tsx
Added optional iconClassName prop (defaulting to "w-3 h-3") forwarded to getStatusIcon for explicit icon sizing control.
DiffPane Empty State & Layout
DiffPane.tsx
Modified empty-state logic to show whenever files.length === 0, with message toggling between "Loading…" and "No changes" based on isLoading. Removed horizontal/vertical padding from content wrapper.
DiffFileEntry Button Migration
DiffFileEntry.tsx
Migrated "Show diff" control from native <button> to @superset/ui Button component with size="xs" and variant="outline". Removed rounded/bordered styling from placeholder container.
DiffFileHeader Refactoring
DiffFileHeader.tsx
Removed onCopyContents prop; added internal "Copy path" action via useCopyToClipboard hook with icon swap to checkmark and tooltip feedback. Restructured layout with non-wrapping flex, improved path/name rendering for narrow widths, and updated git stats coloring via new GIT_STAT_TEXT_CLASSES. Updated StatusIndicator styling with iconClassName="size-3.5".
New Diff Header Controls
DiffPaneHeaderExtras/DiffPaneHeaderExtras.tsx, DiffPaneHeaderExtras/index.ts
Added new DiffPaneHeaderExtras component that reads diffStyle from settings and renders toggle buttons for unified/split diff views with tooltips. Includes barrel export for convenient importing.
WorkspaceDiff Theming Refactor
WorkspaceDiff.tsx
Switched from git decoration color variables to useTerminalTheme hook for applying terminal surface background. Removed copy-to-clipboard hook and onCopyContents callback to DiffFileHeader. Removed bordered/rounded wrapper classes and adjusted unsafeCSS for flattened layout.
Git Decoration Utilities
gitDecorationColors.ts, gitDecorationColors/index.ts
Added new exported GIT_STAT_TEXT_CLASSES constant mapping git decoration categories to Tailwind text class names for light/dark themes. Created barrel export entry point.
usePaneRegistry Integration
usePaneRegistry.tsx
Refactored diff pane header to use new DiffPaneHeaderExtras component instead of inline DiffViewModeToggle. Removed related tooltip/settings imports and simplified header rendering.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hop along as controls grow smart,
Clipboard whispers "Copy path" with heart,
Theming shines through terminal's glow,
Headers dance where paths now show,
Diff modes toggle left and right!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: polishing the v2 diff pane header, file path display, and unmodified-lines strip styling. It is specific, concise, and clearly conveys the primary focus of the changeset.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering summary, test plan, and implementation details. It follows the repository template with Description, Type of Change, and Testing sections properly filled, though Related Issues section is not explicitly present.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 style-changes-pane

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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 30, 2026

Greptile Summary

This PR polishes the v2 diff pane: the file header gets a unified muted-strip style matching the sidebar ChangesHeader, paths are split into a truncating directory + sticky basename, a Copy Path button replaces the old Copy Contents action, the diff body background blends with the terminal surface, unmodified-line separators are flattened flush to the pane edges, and DiffViewModeToggle is extracted into a co-located DiffPaneHeaderExtras component. The changes are largely visual and the refactoring is clean.

Confidence Score: 5/5

Safe to merge; all remaining findings are P2 style/clarity suggestions with no hard correctness issues.

All findings are P2 — one clarifying question about intentionally dropped diff-highlight color overrides, one low-risk CSS-injection note in a Shadow DOM context, and a minor tooltip delay tweak. No data loss, broken flows, or runtime errors.

WorkspaceDiff.tsx — confirm whether the removal of --diffs-addition/deletion/modified-color-override CSS variables is intentional.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx Refactored header layout: flex-nowrap, dir/basename split for truncation, Copy path button added, Copy contents removed, StatusIndicator moved right, p-1 padding standardized, Tooltip delay removed.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx Removed gitDecorationColors CSS-var overrides and copy-contents logic; added terminal surface background blending via useTerminalTheme; injected flush-separator and user-select CSS via unsafeCSS.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/DiffPane.tsx Loading state now shows "Loading…" when files are empty and fetching; removed outer padding on Virtualizer contentClassName for flush layout.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffPaneHeaderExtras/DiffPaneHeaderExtras.tsx New co-located component extracted from usePaneRegistry; mirrors FilePaneHeaderExtras / CommentPaneHeaderExtras pattern; no logic changes.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/StatusIndicator/StatusIndicator.tsx Added iconClassName prop (default "w-3 h-3") so call sites can override icon size; backward-compatible.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/utils/gitDecorationColors/gitDecorationColors.ts New shared constant GIT_STAT_TEXT_CLASSES for addition/deletion/modified Tailwind color strings; extracted from inline styles for reuse.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileEntry/DiffFileEntry.tsx Removed outer rounded-md border wrapper; replaced hand-rolled "Show diff" button with <Button size="xs" variant="outline">.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/usePaneRegistry.tsx Removed inline DiffViewModeToggle; replaced with imported DiffPaneHeaderExtras; cleaned up now-unused imports.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    DP["DiffPane"] --> DFE["DiffFileEntry (per file)"]
    DFE --> DFH["DiffFileHeader\n(collapse · path+dir/basename · copy path\n· StatusIndicator · +/- stats · viewed · eye · discard)"]
    DFE --> WD["WorkspaceDiff\n(MultiFileDiff)"]
    WD -->|"useTerminalTheme()\nsurfaceBg"| BG["Diff body background\nblends with terminal surface"]
    WD -->|"unsafeCSS"| CSS["[data-diff] bg override\n+ flush separator styles"]
    PR["usePaneRegistry"] -->|"renderHeaderExtras"| DPHE["DiffPaneHeaderExtras\n(unified / split toggle)"]
    PR --> DP
Loading
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx:68-76
**Diff line highlight color overrides silently dropped**

The previous code set `--diffs-addition-color-override`, `--diffs-deletion-color-override`, and `--diffs-modified-color-override` on the `MultiFileDiff` style to keep line highlights in sync with the file tree's git decoration colors. Those three CSS-variable entries are gone from `themeVars` in this PR and are not replaced anywhere (neither in `unsafeCSS` nor in `getDiffViewerStyle`). The diff body will now fall back to whatever the pierre/diffs library defaults are, which may no longer match the sidebar. Is this drop intentional, or should the overrides be re-applied alongside the new background blending?

### Issue 2 of 3
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx:151-174
**`surfaceBg` interpolated into `unsafeCSS` without sanitization**

`surfaceBg` is injected verbatim into the CSS string (`--diffs-light-bg: ${surfaceBg} !important`). The value comes from `terminalTheme?.background`, which is user-controllable via custom themes. A crafted `background` value containing `}` or `;` could escape the declaration block. Given `unsafeCSS` already runs inside a Shadow DOM scoped context, the practical impact is limited, but a whitelist check (e.g. valid hex, `rgb(…)`, `var(…)`) would make this airtight.

### Issue 3 of 3
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx:68
**`Tooltip` instant-open on the file path button**

The old code used `<Tooltip delayDuration={300}>` for the open-file tooltip. The new code drops `delayDuration`, which typically defaults to `0` in Radix UI, so the `CLICK_HINT_TOOLTIP` will flash open on any hover without a settle delay. A short delay (200–300 ms) is the convention used elsewhere in this header and keeps the tooltip from feeling intrusive when the user is scanning file names.

```suggestion
			<Tooltip delayDuration={300}>
```

Reviews (1): Last reviewed commit: "style(desktop): polish v2 diff pane head..." | Re-trigger Greptile

Comment on lines 68 to 76
const themeVars = {
...baseThemeVars,
"--diffs-addition-color-override": gitDecorationColors.addition,
"--diffs-deletion-color-override": gitDecorationColors.deletion,
"--diffs-modified-color-override": gitDecorationColors.modified,
...getDiffViewerStyle(activeTheme, {
fontFamily: fontSettings?.editorFontFamily ?? undefined,
fontSize: Number.isFinite(parsedEditorFontSize)
? parsedEditorFontSize
: undefined,
}),
backgroundColor: surfaceBg,
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Diff line highlight color overrides silently dropped

The previous code set --diffs-addition-color-override, --diffs-deletion-color-override, and --diffs-modified-color-override on the MultiFileDiff style to keep line highlights in sync with the file tree's git decoration colors. Those three CSS-variable entries are gone from themeVars in this PR and are not replaced anywhere (neither in unsafeCSS nor in getDiffViewerStyle). The diff body will now fall back to whatever the pierre/diffs library defaults are, which may no longer match the sidebar. Is this drop intentional, or should the overrides be re-applied alongside the new background blending?

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx
Line: 68-76

Comment:
**Diff line highlight color overrides silently dropped**

The previous code set `--diffs-addition-color-override`, `--diffs-deletion-color-override`, and `--diffs-modified-color-override` on the `MultiFileDiff` style to keep line highlights in sync with the file tree's git decoration colors. Those three CSS-variable entries are gone from `themeVars` in this PR and are not replaced anywhere (neither in `unsafeCSS` nor in `getDiffViewerStyle`). The diff body will now fall back to whatever the pierre/diffs library defaults are, which may no longer match the sidebar. Is this drop intentional, or should the overrides be re-applied alongside the new background blending?

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 151 to 174
unsafeCSS: `
* {
user-select: text;
-webkit-user-select: text;
* { user-select: text; -webkit-user-select: text; }
/* Pierre sets --diffs-light-bg/--diffs-dark-bg
* inline on <pre data-diff> from the Shiki theme;
* inline beats :host so we override at the pre. */
[data-diff] {
--diffs-light-bg: ${surfaceBg} !important;
--diffs-dark-bg: ${surfaceBg} !important;
}
/* Flatten the "N unmodified lines" strip flush to
* the pane edges (kills wrapper/content/expand-
* button rounding + inline gap on both
* line-info and line-info-basic). */
[data-separator^='line-info'] [data-separator-wrapper],
[data-separator^='line-info'] [data-separator-content],
[data-separator^='line-info'] [data-expand-up],
[data-separator^='line-info'] [data-expand-down],
[data-separator^='line-info'] [data-expand-both] {
border-radius: 0 !important;
margin-inline: 0 !important;
padding-inline: 0 !important;
}
`,
}}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 surfaceBg interpolated into unsafeCSS without sanitization

surfaceBg is injected verbatim into the CSS string (--diffs-light-bg: ${surfaceBg} !important). The value comes from terminalTheme?.background, which is user-controllable via custom themes. A crafted background value containing } or ; could escape the declaration block. Given unsafeCSS already runs inside a Shadow DOM scoped context, the practical impact is limited, but a whitelist check (e.g. valid hex, rgb(…), var(…)) would make this airtight.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx
Line: 151-174

Comment:
**`surfaceBg` interpolated into `unsafeCSS` without sanitization**

`surfaceBg` is injected verbatim into the CSS string (`--diffs-light-bg: ${surfaceBg} !important`). The value comes from `terminalTheme?.background`, which is user-controllable via custom themes. A crafted `background` value containing `}` or `;` could escape the declaration block. Given `unsafeCSS` already runs inside a Shadow DOM scoped context, the practical impact is limited, but a whitelist check (e.g. valid hex, `rgb(…)`, `var(…)`) would make this airtight.

How can I resolve this? If you propose a fix, please make it concise.

</button>
<StatusIndicator status={status} />
<Tooltip delayDuration={300}>
<Tooltip>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Tooltip instant-open on the file path button

The old code used <Tooltip delayDuration={300}> for the open-file tooltip. The new code drops delayDuration, which typically defaults to 0 in Radix UI, so the CLICK_HINT_TOOLTIP will flash open on any hover without a settle delay. A short delay (200–300 ms) is the convention used elsewhere in this header and keeps the tooltip from feeling intrusive when the user is scanning file names.

Suggested change
<Tooltip>
<Tooltip delayDuration={300}>
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/DiffFileHeader/DiffFileHeader.tsx
Line: 68

Comment:
**`Tooltip` instant-open on the file path button**

The old code used `<Tooltip delayDuration={300}>` for the open-file tooltip. The new code drops `delayDuration`, which typically defaults to `0` in Radix UI, so the `CLICK_HINT_TOOLTIP` will flash open on any hover without a settle delay. A short delay (200–300 ms) is the convention used elsewhere in this header and keeps the tooltip from feeling intrusive when the user is scanning file names.

```suggestion
			<Tooltip delayDuration={300}>
```

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@Kitenite Kitenite merged commit 90fed3b into main Apr 30, 2026
6 of 7 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ⚠️ Neon database branch

Thank you for your contribution! 🎉

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