Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.swiftaiboilerplate.com/llms.txt

Use this file to discover all available pages before exploring further.

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
  • Liquid Glass primitive - SAIGlass with iOS 26 glass and iOS 17–25 Material fallback (new in v2.0)
  • 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.

Liquid Glass

v2.0 introduces SAIGlass, a Liquid Glass primitive that uses the iOS 26 Glass material on iOS 26+ and falls back to SwiftUI Material on iOS 17–25. Same call sites, progressive enhancement at runtime. Location: Packages/DesignSystem/Sources/DesignSystem/Materials/SAIGlass.swift

SAIGlassStyle

public enum SAIGlassStyle {
    case regular  // Standard glass surface (cards, toolbars, sheets)
    case clear    // Edge-to-edge hero surfaces (paywall, onboarding)
}

The .saiGlass modifier

One-call glass treatment for any view:
// Simple card
VStack { /* content */ }
    .saiGlass(.regular)

// In a shape, interactive
Text("Tap me")
    .padding()
    .saiGlass(.regular, in: .capsule, interactive: true)
ModifierPurpose
.saiGlass(_:in:interactive:)Apply a glass material to any view. in: accepts any Shape; interactive: enables tap-response morphing on iOS 26.
.saiScrollEdgeGlass(_:)Glass treatment at scroll edges (under nav bars, tab bars).
.saiSidebarAdaptable()Adaptive sidebar styling for iPad and large displays.
.saiTabBarMinimize(_:)Opt into iOS 26 tab bar minimisation on scroll. iOS 17–25 no-op.

SAIGlassContainer

Use when multiple glass surfaces sit near each other so they sample the same background instead of stacking visually:
SAIGlassContainer {
    RatingCard()
    TipCard()
    UpsellCard()
}

SAITabBarMinimizeStyle

TabView { ... }
    .saiTabBarMinimize(.onScrollDown)  // iOS 26 only; no-op on iOS 17–25
Fighting glass? Stop. Do not pile .background(DSColors.background) or DSColors.background.ignoresSafeArea() onto SwiftUI containers. They block the Material SwiftUI already provides and wreck Liquid Glass on iOS 26. See the Migration Guide for cleanup steps.

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

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

Full Documentation

Complete DesignSystem guide

Feature Settings

Theme selection UI

Building Guide

Customize themes

Architecture

See how modules use DesignSystem

Test Coverage

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