Skip to content

feat(themes): add themeable bgTitleBar token for the window title bar#1102

Merged
pedramamini merged 1 commit into
mainfrom
feat/theme-title-bar-color
Jun 16, 2026
Merged

feat(themes): add themeable bgTitleBar token for the window title bar#1102
pedramamini merged 1 commit into
mainfrom
feat/theme-title-bar-color

Conversation

@pedramamini

@pedramamini pedramamini commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

The draggable window title bar (the top strip with the traffic-light buttons and the centered agent title) rendered transparent and showed bgMain behind it. Themes had no way to color that strip independently, so on light themes it always read as the lightest color in the palette.

This adds a themeable bgTitleBar token so the title bar can be colored per-theme.

What changed

  • src/shared/theme-types.ts - new optional bgTitleBar? field on ThemeColors. Optional (like the ANSI keys) so pre-existing saved/imported custom themes degrade gracefully.
  • src/shared/themes.ts - set bgTitleBar on all 20 built-in themes, each mirroring its own bgMain, so every existing theme looks pixel-identical after this change.
  • src/renderer/App.tsx - wire the title bar background to bgTitleBar ?? bgMain (the fallback reproduces today's behavior for any theme lacking the key).
  • src/renderer/components/CustomThemeBuilder.tsx - new editable "Title Bar Background" field + a title-bar strip in the live preview.
  • src/__tests__/renderer/constants/themes.test.ts - add bgTitleBar to REQUIRED_COLORS.

Backward compatibility

bgTitleBar defaults to bgMain everywhere it is unset (built-in themes set it explicitly; the runtime falls back via ?? bgMain). No theme changes appearance unless its bgTitleBar is deliberately set to something different.

Validation

  • Theme test suite: 11 pass / 0 fail
  • Touched files: 0 TypeScript errors, 0 ESLint errors
  • prettier + eslint --fix ran clean via lint-staged on commit

Notes

  • Requires an app restart (not just a theme re-import) to pick up the new App.tsx wiring.
  • A parallel PR targets rc with the same single commit cherry-picked.

Summary by CodeRabbit

  • New Features
    • Title bar background color is now customizable in the theme builder with a dedicated preview.
    • All built-in themes now include explicit title bar color configuration for consistent appearance.
    • Custom theme builder extends color options to include dedicated title bar styling.
    • Theme system validates title bar color requirements for all themes.

The draggable title bar (App.tsx) rendered transparent and showed bgMain
behind it, so themes had no way to color that top strip independently.

Add an optional bgTitleBar color token:
- New optional field on ThemeColors (falls back to bgMain when unset, so
  pre-existing saved/imported custom themes are unchanged).
- Wire the title bar to bgTitleBar ?? bgMain.
- Set bgTitleBar on all 20 built-in themes, each mirroring its own bgMain,
  so every existing theme looks pixel-identical.
- Expose it as an editable field in the Custom Theme Builder, with a
  title-bar strip added to the live preview.
- Add bgTitleBar to the REQUIRED_COLORS theme test.
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an optional bgTitleBar color to the ThemeColors interface. All built-in themes receive bgTitleBar set to their bgMain value. The draggable title bar in App.tsx uses this color with a bgMain fallback. CustomThemeBuilder registers the new color, renders it in the mini preview, and defaults its input to bgMain. The themes test adds bgTitleBar to required color assertions.

Changes

bgTitleBar theme color

Layer / File(s) Summary
ThemeColors type and built-in theme data
src/shared/theme-types.ts, src/shared/themes.ts
ThemeColors gains optional bgTitleBar?: string with inline documentation. Every theme entry in THEMES receives bgTitleBar set to its own bgMain hex value.
Title bar rendering, builder integration, and test coverage
src/renderer/App.tsx, src/renderer/components/CustomThemeBuilder.tsx, src/__tests__/renderer/constants/themes.test.ts
App.tsx title bar backgroundColor resolves bgTitleBar with a bgMain fallback. CustomThemeBuilder adds bgTitleBar to COLOR_CONFIG, renders a title-bar strip in MiniUIPreview, and defaults the ColorInput to bgMain when the value is absent. The themes test extends REQUIRED_COLORS to include bgTitleBar.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 A bar at the top, now painted just right,
bgTitleBar gleams in the soft window light.
Each theme gets its own little splash of hue,
With a fallback to bgMain if the value slips through.
The rabbit has painted the top — hop, hop, hooray!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: introducing a new themeable bgTitleBar token for the window title bar, which is the primary objective of this PR.
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 feat/theme-title-bar-color

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.

@pedramamini

Copy link
Copy Markdown
Collaborator Author

Companion RC PR: #1103 (same single commit cherry-picked onto rc).

@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown

Greptile Summary

Adds a bgTitleBar design token so the draggable window title bar can be independently themed; all 20 built-in themes are updated to set it equal to their bgMain, preserving the existing look exactly.

  • theme-types.ts / themes.ts: new optional bgTitleBar? field with explicit values on every built-in theme; runtime in App.tsx falls back to bgMain for custom themes that predate the token.
  • CustomThemeBuilder.tsx: exposes the new color via a ColorInput entry and adds a matching strip to the MiniUIPreview layout; the preview correctly reflects bgTitleBar ?? bgMain.
  • Test: bgTitleBar is added to REQUIRED_COLORS, enforcing it on all built-in themes while the TypeScript interface still marks it optional for backward-compatible custom themes.

Confidence Score: 4/5

Safe to merge — all built-in themes are updated, the runtime fallback is sound, and no existing theme changes appearance.

The change is well-scoped and the fallback logic is correct. Two minor observations: REQUIRED_COLORS in the test enforces a stronger invariant than the TypeScript optional type communicates, which could confuse future contributors; and the ColorInput in CustomThemeBuilder pre-fills bgMain as a display value for an unset bgTitleBar, which looks saved but isn't stored until the user edits it.

CustomThemeBuilder.tsx around the bgTitleBar default value display, and themes.test.ts around the REQUIRED_COLORS naming.

Important Files Changed

Filename Overview
src/shared/theme-types.ts Adds optional bgTitleBar?: string field to ThemeColors; placement and JSDoc are clear and consistent with other optional fields (ANSI keys).
src/shared/themes.ts Adds bgTitleBar matching bgMain to all 20 built-in themes; values are pixel-identical to current behavior so no visual regression.
src/renderer/App.tsx Wires backgroundColor: theme.colors.bgTitleBar ?? theme.colors.bgMain onto the draggable title bar div; fallback correctly reproduces legacy transparent behavior.
src/renderer/components/CustomThemeBuilder.tsx Adds bgTitleBar color entry and preview strip; the value fallback to bgMain in the ColorInput for an unset bgTitleBar could mislead users into thinking the field is saved when it isn't.
src/tests/renderer/constants/themes.test.ts Adds bgTitleBar to REQUIRED_COLORS, creating a conceptual tension with the ? optional marker in the TypeScript interface; test passes because all built-in themes set it explicitly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Theme loaded] --> B{bgTitleBar set?}
    B -- Yes --> C[Use bgTitleBar]
    B -- No --> D[Fallback: bgMain]
    C --> E[Apply to title bar div in App.tsx]
    D --> E
    E --> F[Render draggable title bar]

    G[CustomThemeBuilder open] --> H{bgTitleBar in customThemeColors?}
    H -- Yes --> I[Show stored value in ColorInput]
    H -- No --> J[Display bgMain as visual placeholder]
    J -.->|not persisted until user edits| K[(customThemeColors store)]
    I --> K
    K --> L[Export / save theme JSON]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Theme loaded] --> B{bgTitleBar set?}
    B -- Yes --> C[Use bgTitleBar]
    B -- No --> D[Fallback: bgMain]
    C --> E[Apply to title bar div in App.tsx]
    D --> E
    E --> F[Render draggable title bar]

    G[CustomThemeBuilder open] --> H{bgTitleBar in customThemeColors?}
    H -- Yes --> I[Show stored value in ColorInput]
    H -- No --> J[Display bgMain as visual placeholder]
    J -.->|not persisted until user edits| K[(customThemeColors store)]
    I --> K
    K --> L[Export / save theme JSON]
Loading

Reviews (1): Last reviewed commit: "feat(themes): add themeable bgTitleBar t..." | Re-trigger Greptile

'bgMain',
'bgSidebar',
'bgActivity',
'bgTitleBar',

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 Optional type, required in testbgTitleBar is declared bgTitleBar?: string in ThemeColors, but it is listed in REQUIRED_COLORS which the test asserts must be defined on every theme. The test passes today because all 20 built-in themes set the key explicitly, but a future contributor adding an optional UI-surface color may follow the same pattern and be surprised that their optional key must also appear in REQUIRED_COLORS. Consider either renaming the array (e.g. REQUIRED_BUILTIN_COLORS) to signal that this is a stricter contract than the TypeScript type, or adding a short comment explaining the intentional stronger invariant for built-in themes.

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!

Comment on lines +607 to +609
value={
customThemeColors[key] ?? (key === 'bgTitleBar' ? customThemeColors.bgMain : '')
}

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 Phantom pre-fill could surprise users on export — when customThemeColors.bgTitleBar is undefined (e.g. an imported pre-existing custom theme), the ColorInput displays bgMain's value as if the field is already populated. If the user inspects the color, reads the hex, and then exports the theme without touching bgTitleBar, the exported JSON will not contain bgTitleBar at all — the pre-filled value is purely cosmetic. This is silent but unlikely to cause data loss since the runtime fallback ?? bgMain recovers it correctly. A placeholder/hint approach (grey text, placeholder attribute) rather than a real color value would more honestly signal "not yet set".

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/renderer/components/CustomThemeBuilder.tsx (1)

382-390: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Import validation breaks backward compatibility for old custom themes.

The validation requires all COLOR_CONFIG keys to be present, including the newly added bgTitleBar. Old exported custom themes that don't have bgTitleBar will fail import with a "missing color keys" error, contradicting the PR's stated goal of "ensuring backward compatibility with existing custom themes."

🛡️ Proposed fix: Auto-fill missing bgTitleBar before validation
 		try {
 			const data = JSON.parse(e.target?.result as string);
 			if (data.colors && typeof data.colors === 'object') {
+				// Backward compatibility: auto-fill optional bgTitleBar with bgMain if missing
+				if (!data.colors.bgTitleBar && data.colors.bgMain) {
+					data.colors.bgTitleBar = data.colors.bgMain;
+				}
+
 				// Validate all required color keys exist
 				const requiredKeys = COLOR_CONFIG.map((c) => c.key);
🤖 Prompt for 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.

In `@src/renderer/components/CustomThemeBuilder.tsx` around lines 382 - 390, The
validation logic in the theme import handler breaks backward compatibility by
requiring all COLOR_CONFIG keys to be present, including newly added keys like
bgTitleBar. Old exported themes missing this key will fail validation. Before
performing the hasAllKeys validation check, add logic to auto-fill missing color
keys from data.colors with their corresponding default values from COLOR_CONFIG.
This way, old themes will have missing keys populated automatically before the
validation occurs, allowing them to import successfully while maintaining the
integrity check for genuinely invalid themes.
🤖 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.

Outside diff comments:
In `@src/renderer/components/CustomThemeBuilder.tsx`:
- Around line 382-390: The validation logic in the theme import handler breaks
backward compatibility by requiring all COLOR_CONFIG keys to be present,
including newly added keys like bgTitleBar. Old exported themes missing this key
will fail validation. Before performing the hasAllKeys validation check, add
logic to auto-fill missing color keys from data.colors with their corresponding
default values from COLOR_CONFIG. This way, old themes will have missing keys
populated automatically before the validation occurs, allowing them to import
successfully while maintaining the integrity check for genuinely invalid themes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1f5ce690-e5fa-4218-9ca2-d4b94e1023e3

📥 Commits

Reviewing files that changed from the base of the PR and between fe4c8ab and 27cfb3e.

📒 Files selected for processing (5)
  • src/__tests__/renderer/constants/themes.test.ts
  • src/renderer/App.tsx
  • src/renderer/components/CustomThemeBuilder.tsx
  • src/shared/theme-types.ts
  • src/shared/themes.ts

@pedramamini
pedramamini merged commit 1ba41aa into main Jun 16, 2026
4 of 5 checks passed
@pedramamini
pedramamini deleted the feat/theme-title-bar-color branch June 16, 2026 17:15
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