Files
Kordant/tasks/shieldai-unified-restructure/29-ios-design-system.md
2026-05-25 12:23:23 -04:00

6.3 KiB

29. iOS App — Design System Components Matching Web Theme

meta: id: shieldai-unified-restructure-29 feature: shieldai-unified-restructure priority: P1 depends_on: [shieldai-unified-restructure-28] tags: [ios, swiftui, design-system, components, mobile]

objective:

  • Build a comprehensive set of reusable SwiftUI components that mirror the web app's UI primitives (Button, Card, Input, Badge, Modal, Toast) using the iOS theme system from task 28. These components should feel native to iOS while maintaining visual consistency with the web app.

deliverables:

  • iOS/ShieldAI/Components/ShieldButton.swift — Button component:
    • Styles: primary (filled), secondary (outlined), ghost (text only), danger
    • Sizes: small, medium, large
    • States: enabled, disabled, loading (shows ProgressView)
    • Supports icons (leading/trailing)
  • iOS/ShieldAI/Components/ShieldCard.swift — Card container:
    • Gradient background matching web .gradient-card
    • Border with corner radius
    • Optional header and footer content
    • Tap gesture support
  • iOS/ShieldAI/Components/ShieldTextField.swift — Text input:
    • Label, placeholder, validation state
    • Secure text entry toggle for passwords
    • Error message display
    • Focus state styling
  • iOS/ShieldAI/Components/ShieldBadge.swift — Status badge:
    • Variants: default, success, warning, error, info
    • Small rounded pill shape
    • Icon + text or text only
  • iOS/ShieldAI/Components/ShieldModal.swift — Modal/sheet presentation:
    • .sheet wrapper with consistent styling
    • Title, content, and action buttons
    • Dismiss gesture support
  • iOS/ShieldAI/Components/ShieldToast.swift — Toast notification:
    • Slide-in from top or bottom
    • Auto-dismiss after 3-4 seconds
    • Variants: success, error, warning, info
    • Tap to dismiss
    • Uses overlay modifier on root view
  • iOS/ShieldAI/Components/ShieldAvatar.swift — User avatar:
    • Displays image or initials fallback
    • Sizes: small, medium, large
    • Online/away status indicator dot
  • iOS/ShieldAI/Components/ShieldProgressBar.swift — Progress indicator:
    • Linear progress bar with percentage label
    • Color variants
  • iOS/ShieldAI/Components/ShieldEmptyState.swift — Empty state view:
    • Icon, title, description, action button
  • iOS/ShieldAI/Components/ShieldSkeleton.swift — Skeleton loading:
    • Shimmer animation using LinearGradient mask
    • Text line and rectangle shapes

steps:

  1. Create iOS/ShieldAI/Components/ directory.
  2. ShieldButton:
    • Use Button with custom label
    • Primary: brandPrimary background, white text
    • Secondary: transparent with brandPrimary border and text
    • Ghost: transparent, brandPrimary text
    • Danger: red gradient background
    • Loading: replace label with ProgressView + reduce opacity
    • Use .frame(maxWidth: .infinity) for full-width buttons
  3. ShieldCard:
    • ZStack with gradient background shape
    • .overlay for border
    • VStack for content with padding
    • Corner radius: 16pt (matching web rounded-2xl)
  4. ShieldTextField:
    • VStack with label + TextField/SecureField + error text
    • Custom background using bgSecondary with border
    • Focus ring using .overlay with brandPrimary stroke on focus
    • Eye icon button for password visibility toggle
  5. ShieldBadge:
    • Text inside Capsule() background
    • Colors from semantic tokens
    • Small padding and font size
  6. ShieldModal:
    • View extension .shieldModal(isPresented:content:)
    • Wraps .sheet with consistent header and button bar
    • Uses ShieldCard styling for sheet background
  7. ShieldToast:
    • Create ToastManager as @Observable class (iOS 17+) or ObservableObject
    • showToast(message, variant, duration) method
    • Root view applies .overlay with ToastContainer
    • ToastContainer animates toast in/out with withAnimation
  8. ShieldAvatar:
    • AsyncImage or Image with circular clip
    • Fallback: Text with initials on brandPrimary circle
    • Status dot overlay
  9. ShieldProgressBar:
    • GeometryReader with filled Rectangle
    • Percentage label overlay
  10. ShieldEmptyState:
    • VStack with icon (Image(systemName:)), title, description, optional ShieldButton
  11. ShieldSkeleton:
    • Rectangle or RoundedRectangle with shimmer animation
    • Use LinearGradient masked with mask modifier
    • Animate gradient position with withAnimation(.linear(duration: 1.5).repeatForever())
  12. Create a preview/test view showing all components in light and dark mode.

steps:

  • Unit: Each component renders correctly in previews
  • Unit: ShieldButton action fires on tap
  • Unit: ShieldTextField validation shows error state
  • Unit: ShieldToast auto-dismisses after specified duration
  • Visual: All components match web app appearance in both color schemes
  • Visual: Components adapt to Dynamic Type (accessibility font sizes)

acceptance_criteria:

  • All 10 component types exist in iOS/ShieldAI/Components/
  • Each component supports light and dark modes
  • Button supports all 4 styles, 3 sizes, and loading state
  • TextField supports validation, secure entry, and focus styling
  • Toast system can queue and auto-dismiss multiple toasts
  • Card uses gradient background matching web theme
  • Skeleton has smooth shimmer animation
  • All components use theme tokens (no hardcoded colors)
  • Components adapt to accessibility font sizes

validation:

  • Open preview canvas for each component and verify appearance
  • Run app on simulator and navigate to component test screen
  • Toggle dark mode and verify all components shift colors
  • Enable large text in Accessibility settings and verify layouts don't break
  • Run unit tests via Xcode Cmd+U

notes:

  • SwiftUI previews are invaluable for component development. Create a ComponentsPreview.swift that shows all variants side by side.
  • Use @ViewBuilder closures for content slots in ShieldCard, ShieldModal, etc. to allow flexible content.
  • For the toast system, consider using the new @Observable macro (iOS 17+) instead of ObservableObject for better performance.
  • The shimmer animation can be implemented using a LinearGradient that moves across the view. Reference: https://swiftuirecipes.com/blog/swiftui-shimmer-effect
  • Keep components generic — they should not import service-specific types or business logic.