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

360 lines
13 KiB
Markdown

---
source: ~/DuckDuckGo/apple-browsers.git/main/.cursor/rules/design-system-designresourceskit.mdc
confidence: 0.9
namespace: work
last_synced: 2026-04-28
alwaysApply: 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](https://github.com/duckduckgo/DesignResourcesKit)
**Figma Designs**: [🖱️ iOS & iPadOS Components](https://www.figma.com/file/GzGKD6gR24AHoUqVykX1ah/%F0%9F%93%B1-iOS-%26-iPadOS-Components?type=design&node-id=3938%3A23329&mode=design&t=0fuiNF84nnV5zExC-1)
### 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](design-system-designresourceskit/uikit-typography-usage.swift)
#### Available Typography Styles
**Example:** See [uikit-typography-styles.swift](design-system-designresourceskit/uikit-typography-styles.swift)
#### Best Practices for UIKit
**Example:** See [uikit-typography-best-practices.swift](design-system-designresourceskit/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](design-system-designresourceskit/swiftui-typography-usage.swift)
#### Available SwiftUI Typography Modifiers
**Example:** See [swiftui-typography-modifiers.swift](design-system-designresourceskit/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](design-system-designresourceskit/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:
```swift
// ❌ 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](https://github.com/duckduckgo/DesignResourcesKit/pull/1/commits/971979d3dcd95567b9812b800eb22ab1611ce3a5)
- 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](design-system-designresourceskit/colors-text-uikit.swift)
**SwiftUI Example:** See [colors-text-swiftui.swift](design-system-designresourceskit/colors-text-swiftui.swift)
#### Background Colors
**Example:** See [colors-background.swift](design-system-designresourceskit/colors-background.swift)
#### Control Colors
```swift
// 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
```swift
// 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
```swift
// 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](design-system-designresourceskit/colors-anti-patterns.swift)
## Enforcement and Code Review
### Automated Enforcement
#### Danger Integration
**Asset catalog enforcement**: We use [Danger](https://danger.systems/) to prevent new colors being added directly to iOS app asset catalogs.
**Example:** See [danger-integration.rb](design-system-designresourceskit/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](design-system-designresourceskit/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](design-system-designresourceskit/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](design-system-designresourceskit/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:
```swift
// 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](design-system-designresourceskit/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](design-system-designresourceskit/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](design-system-designresourceskit/local-development.sh)
## Resources and References
### Official Resources
- **GitHub Repository**: [duckduckgo/DesignResourcesKit](https://github.com/duckduckgo/DesignResourcesKit)
- **Figma Designs**: [iOS & iPadOS Components](https://www.figma.com/file/GzGKD6gR24AHoUqVykX1ah/%F0%9F%93%B1-iOS-%26-iPadOS-Components?type=design&node-id=3938%3A23329&mode=design&t=0fuiNF84nnV5zExC-1)
### Related Documentation
- **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.