Skip to main content
Full technical details in your project at /docs/modules/DesignSystem.md

What You Get

  • Token system - Colors, spacing, typography, radius (never hardcode values)
  • 5 themes - System, Light, Dark, Aurora, Obsidian
  • Premium components - Buttons, inputs, cards, bubbles
  • BrandConfig - Single place to customize app identity
  • Accessibility - Dynamic Type, VoiceOver, Reduce Motion
  • Gradients & motion - Premium visual effects
Time saved: 20-32 hours of design system, theming infrastructure, component library, and testing.

BrandConfig (Customize Your App)

Single file to customize app identity. From BrandConfig.swift:
public enum BrandConfig {
    // Change this to your app name
    public static let appDisplayName = "SwiftAI Pro"
    
    // Accent color for highlights and CTAs
    public static let accentColor: Color = DSColors.primary
    
    // SF Symbol for default avatar
    public static let avatarFallbackSymbol = "person.circle.fill"
    
    // App icon background color
    public static let appIconBackground: Color = DSColors.primary
}
To rebrand:
  1. Change appDisplayName → Your app name
  2. Update AccentPrimary color in DesignSystemColors.xcassets
  3. Change avatarFallbackSymbol → Your icon
  4. Entire app updates automatically!

Design Tokens (Production System)

DSColors - Theme-Aware

Every color adapts to the active theme:
// Real usage from auth screen
Text(BrandConfig.appDisplayName)
    .foregroundStyle(DSColors.textPrimary)

Button("Sign In")
    .foregroundStyle(DSColors.accentPrimary)  // Pink in Aurora, blue in default

VStack {}
    .background(DSColors.background)         // Adapts to all 5 themes
Token categories:
  • Text: textPrimary, textSecondary
  • Surfaces: background, surface, surfaceElevated
  • Accents: accentPrimary, accentSecondary
  • Borders: borderHairline, borderSubtle
  • Semantic: success, warning, danger

DSSpacing

Consistent spacing scale:
// Usage
.padding(DSSpacing.md)
.spacing(DSSpacing.lg)

// Scale: xs (4pt) → sm (8pt) → md (16pt) → lg (24pt) → xl (32pt) → xxl (48pt)

DSTypography

Text styles with Dynamic Type:
// Usage
Text("Title").font(DSTypography.titleL)
Text("Body").font(DSTypography.body)

// Styles: titleXL, titleL, titleM, titleS, body, bodyBold, caption, footnote

DSRadius

Corner radius values:
// Usage
.cornerRadius(DSRadius.md)

// Scale: sm (8pt) → md (12pt) → lg (16pt) → xl (20pt) → xxl (24pt)

UI Components

  • Buttons
  • Inputs
  • Cards & Rows
  • Other
SAIButton("Primary", style: .primary) { action() }
SAIButton("Secondary", style: .secondary) { action() }
SAIButton("Destructive", style: .destructive) { action() }

Theme System

5 Built-in Themes

System

Follows iOS light/dark mode

Light

Always light appearance

Dark

Always dark appearance

Aurora

Teal/purple premium theme

Obsidian

Charcoal/amber professional

Applying Themes

// Set theme
await settingsViewModel.updateTheme(.aurora)

// Theme applies instantly app-wide!

How It Works

// 1. User selects theme
// 2. Saved to Settings (SwiftData)
// 3. DSColors reads preference
// 4. Returns theme-specific colors
// 5. SwiftUI updates automatically

Customization Examples

Create Custom Theme

1

Add Color Set

In DesignSystemColors.xcassets, create:
  • MyThemePrimary.colorset
  • MyThemeBackground.colorset
  • … (all semantic colors)
2

Add Theme Case

public enum UserThemePreference: String {
    case system, light, dark, aurora, obsidian
    case myTheme  // New theme
}
3

Map Colors

In DSColors.swift:
public static var primary: Color {
    switch currentTheme {
    case .myTheme:
        return Color("MyThemePrimary", bundle: .module)
    default:
        // ... existing mappings
    }
}
4

Add to Picker

In SettingsView:
Picker("Theme", selection: $viewModel.currentTheme) {
    // ... existing themes
    Text("My Theme").tag(UserThemePreference.myTheme)
}

Create Custom Component

public struct MyCustomCard: View {
    let title: String
    let subtitle: String
    
    public var body: some View {
        VStack(alignment: .leading, spacing: DSSpacing.sm) {
            Text(title)
                .font(DSTypography.titleM)
                .foregroundStyle(DSColors.textPrimary)
            
            Text(subtitle)
                .font(DSTypography.body)
                .foregroundStyle(DSColors.textSecondary)
        }
        .padding(DSSpacing.md)
        .background(DSColors.surface)
        .cornerRadius(DSRadius.md)
    }
}

Animations

Smooth, consistent animations:
// Spring animations
DSAnimations.spring
DSAnimations.springBouncy
DSAnimations.springSmooth

// Durations
DSAnimations.fast  // 0.2s
DSAnimations.medium  // 0.3s
DSAnimations.slow  // 0.5s

// Usage
.animation(.spring(DSAnimations.spring), value: isExpanded)

Accessibility

Built-in support for:
  • Dynamic Type - All text scales automatically
  • VoiceOver - All components labeled
  • High Contrast - Semantic colors adapt
  • Reduced Motion - Respects system preference
  • Minimum Touch Targets - 44pt minimum

Key Files

ComponentLocation
TokensPackages/DesignSystem/Sources/DesignSystem/Tokens/
ComponentsPackages/DesignSystem/Sources/DesignSystem/Components/
ColorsPackages/DesignSystem/Sources/DesignSystem/Resources/

Dependencies

  • None - DesignSystem is independent

Used By

  • All features - Every UI component
  • App Shell - Main app screens
  • Feature modules - Chat, Settings, Profile

Best Practices

  • Never hardcode colors
  • Never hardcode spacing
  • Use semantic names
  • Test in all themes
  • Use design tokens exclusively
  • Support all themes
  • Add accessibility labels
  • Test Dynamic Type
  • Include preview
  • Semantic colors only
  • Support light + dark
  • Instant switching
  • Persist preference

Learn More

Test Coverage

90%+ - Token and component testing Tests include:
  • Theme switching
  • Color mapping
  • Component rendering
  • Accessibility
  • Dynamic Type
I