How to Customize the Appearance of CodexBar's UI: A SwiftUI Guide
CodexBar's visual layer is built entirely with SwiftUI, and you can customize its appearance by modifying the BurnTheme struct for widget colors, adjusting @Environment(\.colorScheme) responses for dark mode, and editing PreferencesView.swift and PreferencesSidebar.swift for the settings window layout.
CodexBar is a macOS status bar application developed by steipete that displays burn-down charts and provider statistics using native SwiftUI components. To customize the appearance of CodexBar's UI, you must work within its SwiftUI-based architecture, modifying theme structs, environment values, and view layouts across several key source files. All visual customization happens through SwiftUI view modifications rather than external configuration files.
Understanding CodexBar's Visual Architecture
The BurnTheme Struct
The BurnTheme struct in Sources/CodexBarWidget/BurnDownWidgetViews.swift (line 447) serves as the central authority for all widget styling. This struct calculates provider-specific brand colors, text colors, chart line colors, background shades, and rendering modes. It evaluates both the dark boolean flag and the isMonochrome widget rendering mode to determine appropriate color values.
Environment-Driven Color Schemes
Every view that adapts to Light/Dark mode reads the @Environment(\.colorScheme) private var colorScheme property. The UI automatically swaps colors based on this environment value, ensuring real-time updates when the system appearance changes. In PreferencesView.swift (line 43), this environment value drives the root color scheme of the settings window.
Customizing Colors and Themes
Modifying Widget Colors
To change chart line colors, brand dots, or background shades, edit the computed properties inside BurnTheme. The struct provides properties like brandDot, chartLine, chartNowDot, and chartNowRing that return Color values based on the current theme state.
// In BurnDownWidgetViews.swift, extend BurnTheme for custom colors
extension BurnTheme {
var brandDot: Color { dark ? Color.purple : Color.yellow }
var chartLine: Color { dark ? Color.white : Color.black }
}
Overriding Dark Mode Palettes
Replace the default ternary expressions that check colorScheme == .dark with custom color definitions. This affects how backgrounds, text, and separators render in each mode.
let background = colorScheme == .dark
? Color.black.opacity(0.85)
: Color.white.opacity(0.85)
Customizing the Settings Window
Modifying the Sidebar Layout
The settings sidebar is defined in Sources/CodexBar/PreferencesSidebar.swift using SettingsSidebarPaneRow and SettingsSidebarProviderRow. Adjust icon sizes, row spacing, and padding within these private view structs to change the sidebar's visual density.
private struct SettingsSidebarPaneRow: View {
var body: some View {
HStack(spacing: 8) {
SettingsIconChip(systemImage: systemImage, color: color)
.frame(width: 24, height: 24) // Custom icon size
Text(title)
}
.padding(.vertical, 4) // Custom vertical padding
}
}
Adding New Settings Panes
Extend the SettingsPane enum in PreferencesView.swift to add new configuration sections. Each new case requires a corresponding view implementation in the detailView computed property.
// 1. Extend SettingsPane in PreferencesView.swift
enum SettingsPane: Hashable {
case general, providers, about
case theme // New custom pane
}
// 2. Provide view implementation
private var detailView: some View {
switch selection.pane {
case .theme:
ThemeCustomizationPane(settings: settings)
default:
EmptyView()
}
}
// 3. Add sidebar row in PreferencesSidebar.swift
SettingsSidebarPaneRow(
pane: .theme,
systemImage: "paintbrush.fill",
color: .orange
)
Synchronizing Native Window Chrome
The SettingsWindowAppearanceBridge class in Sources/CodexBar/PreferencesView.swift (lines 12-22) bridges SwiftUI color scheme changes to the underlying NSWindow. This ensures the title bar, separator lines, and native AppKit components stay synchronized with the SwiftUI theme.
Practical Customization Examples
Example 1: Custom Widget Theme
Override the default BurnTheme initialization to inject custom brand colors for specific providers.
let customTheme = BurnTheme(
provider: provider,
geom: geom,
dark: dark,
isMonochrome: isMonochrome)
// Override specific color properties
extension BurnTheme {
var brandDot: Color { isEnabled ? Color.orange : Color.gray }
var chartLine: Color { dark ? Color.green : Color.blue }
}
Example 2: Sidebar Provider Row Styling
Reduce vertical padding in provider rows to create a more compact sidebar appearance.
private struct SettingsSidebarProviderRow: View {
let provider: Provider
let isEnabled: Bool
var body: some View {
HStack(spacing: 8) {
SettingsSidebarBrandIcon(provider: provider, isEnabled: isEnabled)
Text(store.metadata(for: provider).displayName)
Spacer()
}
.padding(.vertical, 4) // Reduced from default
}
}
Example 3: Combined Widget Layout Changes
Modify CombinedBurnDownLayout in Sources/CodexBarWidget/CombinedBurnDownWidgetViews.swift to adjust the arrangement of session and weekly burn-down rows.
var body: some View {
VStack(alignment: .leading, spacing: 12) {
Text("Custom Header") // Added headline
.font(.headline)
BurnDownRow(theme: theme, data: sessionData)
BurnDownRow(theme: theme, data: weeklyData)
}
.padding(.horizontal, 16) // Custom padding
}
Summary
- Color customization happens primarily in
BurnThemewithinBurnDownWidgetViews.swift, where you can override brand colors, chart lines, and background shades. - Dark mode support relies on the
@Environment(\.colorScheme)property, which views read to adapt their palettes automatically. - Settings window modifications require editing
PreferencesView.swiftfor pane logic andPreferencesSidebar.swiftfor sidebar row styling. - Native window synchronization is handled by
SettingsWindowAppearanceBridge, ensuring the title bar matches the SwiftUI theme. - All UI components are standard SwiftUI views, enabling customization through standard view modifiers and struct extensions.
Frequently Asked Questions
Where are CodexBar's color definitions stored?
Color definitions reside in the BurnTheme struct inside Sources/CodexBarWidget/BurnDownWidgetViews.swift. This struct provides computed properties like brandDot, chartLine, and backgroundColor that return SwiftUI Color values based on the current dark mode flag and isMonochrome rendering state.
How do I add a new settings category to CodexBar?
Add a new case to the SettingsPane enum in Sources/CodexBar/PreferencesView.swift, then implement the corresponding view in the detailView computed property. Finally, add a SettingsSidebarPaneRow entry in Sources/CodexBar/PreferencesSidebar.swift to display the new category in the sidebar.
Can I change the status bar icon appearance?
The status bar icon rendering depends on the widget views defined in Sources/CodexBarWidget/BurnDownWidgetViews.swift and CombinedBurnDownWidgetViews.swift. You can modify the BurnTheme struct to change icon colors or edit the layout structs to adjust icon sizing and spacing within the menu bar extra.
Does CodexBar support external theme files or CSS?
No, CodexBar does not support external CSS or JSON theme files. All theming is compile-time SwiftUI code. To apply custom themes, you must fork the repository and modify the SwiftUI view code directly, specifically the BurnTheme struct and individual view implementations in the Sources/CodexBar and Sources/CodexBarWidget directories.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →