Files
obsidian-vault/work/wiki/apple-browsers/design-system-designresourceskit.md
T

13 KiB

source, confidence, namespace, last_synced, alwaysApply
source confidence namespace last_synced alwaysApply
~/DuckDuckGo/apple-browsers.git/main/.cursor/rules/design-system-designresourceskit.mdc 0.9 work 2026-04-28 true

DuckDuckGo iOS Design System & DesignResourcesKit (DRK)

Overview

The DuckDuckGo iOS design system is implemented through DesignResourcesKit (DRK), a shared Swift package that contains our design tokens, type styles, colors, and design system elements.

Repository: https://github.com/duckduckgo/DesignResourcesKit

Figma Designs: 🖱️ iOS & iPadOS Components

What DRK Contains

Currently Included:

  • Type styles and typography (based on system styles)
  • Semantic color system (with light/dark mode support)
  • Design tokens and foundations

🔄 Future Expansion:

  • Reusable components (when patterns emerge)
  • Advanced interaction patterns

Not Included:

  • Icons (remain in iOS app directly for now)

⚠️ Critical Rule: Don't Break the Design System

If you take only one thing away from this documentation: Don't add new colors or type styles outside of the design system without reading the guidelines below.

Breaking the design system:

  • Undermines consistency across the app
  • Creates maintenance debt with scattered styles
  • Breaks accessibility features like dynamic type
  • Fragments the user experience

Typography System

Philosophy

Our typography system is based on system styles rather than hardcoded sizes. This ensures:

  • Automatic dynamic type support for accessibility
  • Consistent scaling across different user preferences
  • Platform-appropriate styling that feels native

UIKit Usage

DRK defines static functions on UIFont for all typography.

Example: See uikit-typography-usage.swift

Available Typography Styles

Example: See uikit-typography-styles.swift

Best Practices for UIKit

Example: See uikit-typography-best-practices.swift

SwiftUI Usage

DRK provides view modifiers and extensions for SwiftUI that should be used instead of direct font access.

Example: See swiftui-typography-usage.swift

Available SwiftUI Typography Modifiers

Example: See swiftui-typography-modifiers.swift

SwiftUI Code Review Guidelines

When reviewing PRs: Look for .font() usage as a red flag.

Example: See swiftui-code-review-red-flags.swift

Emergency Escape Hatch (Avoid!)

For legacy layout fixes only: If you absolutely must disable dynamic type, there's a deliberately obtusely named function:

// ❌ LAST RESORT: Only for fixing legacy layouts
let fixedFont = UIFont.daxFontOutsideOfTheDesignSystemToFixLegacyLayoutBreakage()

Important Notes:

  • This function may not exist in current DRK versions
  • If you need it, you must revert the commit that removed it: Commit 971979d
  • This is deliberately annoying to discourage usage
  • Always prefer fixing the layout to support dynamic type instead

Color System

Semantic Color Approach

Our color system uses semantic naming rather than literal colors (e.g., "primary text" instead of "black"). This enables:

  • Automatic dark mode support
  • Future theme flexibility
  • Accessibility compliance
  • Consistent visual hierarchy

Color Categories

Text Colors

UIKit Example: See colors-text-uikit.swift

SwiftUI Example: See colors-text-swiftui.swift

Background Colors

Example: See colors-background.swift

Control Colors

// UIKit
button.backgroundColor = UIColor(designSystemColor: .controlsFillPrimary)
button.backgroundColor = UIColor(designSystemColor: .controlsFillSecondary)

// SwiftUI
Button("Action") { }
    .foregroundColor(Color(designSystemColor: .controlsFillPrimary))
    .background(Color(designSystemColor: .controlsFillSecondary))

Button-Specific Colors

// UIKit
primaryButton.backgroundColor = UIColor(designSystemColor: .buttonPrimaryBackground)
primaryButton.setTitleColor(UIColor(designSystemColor: .buttonPrimaryText), for: .normal)

secondaryButton.backgroundColor = UIColor(designSystemColor: .buttonSecondaryBackground)
secondaryButton.setTitleColor(UIColor(designSystemColor: .buttonSecondaryText), for: .normal)

// SwiftUI
Button("Primary Action") { }
    .foregroundColor(Color(designSystemColor: .buttonPrimaryText))
    .background(Color(designSystemColor: .buttonPrimaryBackground))

Button("Secondary Action") { }
    .foregroundColor(Color(designSystemColor: .buttonSecondaryText))
    .background(Color(designSystemColor: .buttonSecondaryBackground))

Accent Colors

// UIKit
view.tintColor = UIColor(designSystemColor: .accent)

// SwiftUI
Image(systemName: "heart.fill")
    .foregroundColor(Color(designSystemColor: .accent))

Anti-patterns: What NOT to Do

Example: See colors-anti-patterns.swift

Enforcement and Code Review

Automated Enforcement

Danger Integration

Asset catalog enforcement: We use Danger to prevent new colors being added directly to iOS app asset catalogs.

Example: See danger-integration.rb

Manual Code Review Checklist

Look for in PRs:

  • DRK typography usage: UIFont.daxTitle1(), .daxBody() modifiers
  • DRK color usage: UIColor(designSystemColor: .textPrimary)
  • No hardcoded colors: No hex values, RGB tuples, or named colors
  • No .font() modifiers in SwiftUI (red flag for design system violations)
  • Semantic naming: Colors described by purpose, not appearance

Code Review Examples

Example: See code-review-checklist.swift

Opportunistic Improvements

Most of the iOS app currently does not use the design system, so you're encouraged to:

  1. Opportunistically refactor old code to use DRK when you encounter it
  2. Update hardcoded colors to semantic colors when working in an area
  3. Replace system fonts with DRK typography when touching text styling
  4. File follow-up tickets for systematic cleanup when you notice patterns

Example: Opportunistic Refactoring

Example: See opportunistic-refactoring.swift

Components

Current State: Minimal Component Library

We primarily use system components rather than custom ones, following iOS design guidelines. This is different from our Android app which has more custom components.

Philosophy:

  • System components first - leverages platform conventions
  • Custom components only when needed - avoid overengineering
  • Reusable when patterns emerge - extract when used in multiple places

Existing Custom Components

Blue Button (Reusable)

Our primary custom component used across multiple screens.

Example: See blue-button-component.swift

Candidate for DRK: This button is used in multiple places and should be extracted into DesignResourcesKit as a reusable component.

Future Component Strategy

When to Create Components

Create a component when:

  • Pattern is used in 3+ different contexts
  • Styling is complex or specialized
  • Behavior needs to be consistent across usage
  • Component encapsulates design system tokens

Don't create a component when:

  • Used in only one place (keep it local)
  • System component exists that meets needs
  • Component would be overly generic or complex

Emerging Patterns to Watch

Look for these patterns that might become components:

// Bottom sheets - if format becomes consistent
struct BottomSheetView: View {
    // Consistent styling, behavior, animation
    // Could become reusable component
}

// Info cards/panels - if layout patterns emerge  
struct InfoCardView: View {
    // Standard card styling with DRK colors
    // Could be extracted if reused
}

// Form elements - if custom styling is needed
struct FormFieldView: View {
    // Consistent form field styling
    // Could become component library
}

Component Creation Process

  1. Identify the pattern in your current work
  2. Check if existing implementations could be generalized
  3. Design the API to be flexible but opinionated
  4. Implement using DRK tokens for colors, typography, spacing
  5. Add to DesignResourcesKit package
  6. Update existing usages to use the new component
  7. Document the component with usage examples

Example: See component-creation-example.swift

Modularization Strategy

Why DRK is a Separate Package

High friction is a feature: Making DRK a separate module provides beneficial constraints:

  1. Immutability encouragement: Changes require more thought and process
  2. API stability: Forces consideration of breaking changes
  3. Reusability: Can be shared across iOS/macOS if needed
  4. Clear boundaries: Separates design tokens from app logic
  5. Version control: Can be tagged and versioned independently

Design System Evolution

Original Discussion: [Tech Design: How to modularise iOS/macOS design system elements](✓ Tech Design: How to modularise iOS/macOS design system elements)

Guiding Principles:

  • Start minimal: Don't over-engineer early
  • Evolve based on usage: Add components when patterns emerge
  • Maintain consistency: All additions should follow established patterns
  • Document decisions: Keep rationale for future developers

Working with DesignResourcesKit

Adding New Design Tokens

Process for adding colors/typography:

  1. Design system first: Ensure token is defined in Figma
  2. Semantic naming: Use purpose-based names (textPrimary not black)
  3. Light/dark variants: Define both light and dark mode values
  4. PR to DRK: Add to DesignResourcesKit repository
  5. Update app: Use new tokens in consuming apps
  6. Documentation: Update usage examples and guidelines

Updating DRK Version

In consuming app (iOS/macOS):

Example: See updating-drk-version.swift

Testing DRK changes:

  • Test in both light and dark modes
  • Verify dynamic type scaling works correctly
  • Check accessibility with larger text sizes
  • Test on different device sizes

Local Development

For iterating on DRK:

Example: See local-development.sh

Resources and References

Official Resources

  • Colors: [Tech Design: How to organise colors and icons in iOS and macOS wrt the design system](✓ Tech Design: How to organise colors and icons in iOS and macOS wrt the design system)
  • Colors Update: [Tech Design: Redefine design system colors in DesignResourcesKit](✓ Tech Design: Redefine design system colors in DesignResourcesKit)
  • Typography: [Tech Design: How to organise typography/label styles in iOS and macOS wrt the design system](✓ Tech Design: How to organise typography/label styles in iOS and macOS wrt the design system)
  • Enforcement: [Use danger to stop new colors being added to the iOS app](✓ Use danger to stop new colors being added to the iOS app)

Quick Reference

UIKit Checklist

  • Use UIFont.daxTitle1(), UIFont.daxBody(), etc.
  • Use UIColor(designSystemColor: .textPrimary) etc.
  • No hardcoded colors or fonts
  • No system colors for app content

SwiftUI Checklist

  • Use .daxTitle1(), .daxBody() modifiers
  • Use Color(designSystemColor: .textPrimary) etc.
  • Avoid .font() modifier (red flag in reviews)
  • No hardcoded colors

Code Review Checklist

  • No new colors in asset catalogs
  • DRK typography used consistently
  • Semantic color naming
  • No hardcoded styling
  • Opportunistic improvements to legacy code

Remember: The design system is only as strong as our commitment to using it. Every PR is an opportunity to improve consistency and user experience.