How to Customize UI Elements in FluidVoice: A Complete SwiftUI Theming Guide
You can customize UI elements in FluidVoice by modifying the centralized ThemePalette in ThemeEnvironment.swift for global changes, or by editing individual SwiftUI view structs in Sources/Fluid/UI/ for component-specific overrides.
FluidVoice is built entirely on SwiftUI and implements a centralized theming system that manages colors, typography, and spacing across the application. Because the UI is declarative and modular, you can tailor the appearance of any screen by adjusting theme values or modifying view code directly without touching lower-level AppKit APIs.
Understanding the Theming Architecture
The theming system centers on Sources/Fluid/Theme/ThemeEnvironment.swift, which defines the ThemePalette and typography structs used throughout the app. This theme is injected into the view hierarchy via @Environment(\.theme), allowing every UI component to access consistent styling values.
When you open any view file in Sources/Fluid/UI/, you will see references like self.theme.palette.accent for colors or self.theme.typography.title for fonts. This pattern ensures that changing a single value in the theme environment propagates automatically to every view that references it.
Global Customization via Theme Palette
To change the appearance of FluidVoice across the entire application, modify the ThemePalette struct in ThemeEnvironment.swift. This struct contains color definitions for window backgrounds, accent colors, and text.
For example, the default accent color is defined as a blue hex value:
// Sources/Fluid/Theme/ThemeEnvironment.swift
public struct ThemePalette {
public var accent = Color(hex: "#0A84FF") // ← default blue
// ...
}
To apply a custom teal accent globally, update the value:
public var accent = Color(hex: "#00BFA5")
All views referencing self.theme.palette.accent—such as the "Quick Setup" icon in WelcomeView.swift (lines 61-68)—will immediately adopt the new color when you rebuild the app.
Modifying Typography System-Wide
Font families and sizes are stored in theme.typography. By editing these values in ThemeEnvironment.swift, you can adjust the weight and size of titles, captions, and body text without touching individual view files.
The typography system follows the same environment pattern as the color palette, ensuring that text styling remains consistent across WelcomeView, CommandModeView, and MeetingTranscriptionView.
Component-Level Customization
For targeted changes to specific screens, edit the individual SwiftUI view structs in Sources/Fluid/UI/. Each component is self-contained, allowing you to add new visual elements, replace existing ones, or apply custom modifiers.
Adding Elements to Existing Views
You can insert new UI elements into existing stacks. For example, to add a settings button to the Welcome screen:
// Sources/Fluid/UI/WelcomeView.swift
private var commandModeGuide: some View {
VStack(alignment: .leading, spacing: 12) {
// Existing content …
HStack {
// New button that opens the Settings window
Button("Open Settings") {
NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:")!)
}
.buttonStyle(.bordered)
.controlSize(.small)
}
}
}
Because Button inherits the environment automatically, it respects the current theme colors without additional configuration.
Overriding Styles for Specific Views
When you need a one-off customization that shouldn't affect the global theme, apply modifiers directly to the view. For example, to use a custom font in MeetingTranscriptionView while keeping the theme's color:
// Sources/Fluid/UI/MeetingTranscriptionView.swift
var body: some View {
VStack(spacing: 0) {
// Header
VStack(spacing: 8) {
Image(systemName: "waveform.circle.fill")
.font(.system(size: 48))
.foregroundStyle(Color.fluidGreen.gradient)
Text("Meeting Transcription")
.font(.custom("HelveticaNeue-Bold", size: 28)) // ← custom font
.foregroundStyle(self.theme.palette.primaryText) // keep theme color
}
// …
}
}
Creating Custom Reusable Components
You can build new UI components that automatically respect the FluidVoice theme by accessing the environment. Create a new file in Sources/Fluid/UI/ and inject the theme:
// Sources/Fluid/UI/CustomBadge.swift
import SwiftUI
struct CustomBadge: View {
let label: String
@Environment(\.theme) private var theme
var body: some View {
Text(label)
.font(self.theme.typography.badge)
.foregroundStyle(.white)
.padding(.horizontal, 6)
.padding(.vertical, 2)
.background(self.theme.palette.accent, in: RoundedRectangle(cornerRadius: 4))
}
}
Drop CustomBadge(label: "Beta") into any view, and it will update automatically if you modify the theme palette.
Key Files for UI Customization
Sources/Fluid/Theme/ThemeEnvironment.swift— DefinesThemePaletteand typography; the entry point for global color and font changes.Sources/Fluid/Theme/NativeButtonStyles.swift— Contains custom button styling for.fluidButtoninstances; edit to change button appearance globally.Sources/Fluid/UI/WelcomeView.swift— Main onboarding screen; demonstrates theme usage for icons, text, and buttons (see lines 61-68 for accent color usage).Sources/Fluid/UI/CommandModeView.swift— UI for the command-mode hot-key overlay; useful for styling command-mode specific elements.Sources/Fluid/UI/MeetingTranscriptionView.swift— Complex UI with file pickers and result cards; reference for custom view composition.
Summary
- Global changes are made in
ThemeEnvironment.swiftby modifyingThemePaletteand typography values, which propagate via@Environment(\.theme). - Component-specific changes involve editing individual SwiftUI view files in
Sources/Fluid/UI/to add elements, apply modifiers, or rearrange layouts. - Custom components should use
@Environment(\.theme)to ensure they remain consistent with the app's visual language. - All changes are compile-time safe and immediately visible at runtime thanks to SwiftUI's declarative architecture.
Frequently Asked Questions
How do I change the accent color in FluidVoice?
Edit the accent property in Sources/Fluid/Theme/ThemeEnvironment.swift. Update the Color(hex:) value to your desired hex code, and all views referencing theme.palette.accent—including icons in WelcomeView.swift—will update automatically.
Can I add custom buttons to existing screens like the Welcome view?
Yes. Open Sources/Fluid/UI/WelcomeView.swift, locate the relevant VStack or HStack, and insert a standard SwiftUI Button. The button will inherit the environment's theme automatically, or you can apply specific styles using .buttonStyle() and .controlSize() modifiers.
How do I create a new UI component that matches FluidVoice's theme?
Create a new Swift file in Sources/Fluid/UI/ and define a View struct that accesses the theme via @Environment(\.theme) private var theme. Use self.theme.palette for colors and self.theme.typography for fonts to ensure your component stays synchronized with global theme changes.
Where are the font styles defined in FluidVoice?
Font families and sizes are defined in Sources/Fluid/Theme/ThemeEnvironment.swift within the typography struct. Views access these via self.theme.typography to ensure consistent text styling across the application.
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 →