Skip to content

iOS: establish a unified design system / styling guide #98317

Description

@joelnishanth

What Problem This Solves

The iOS app has grown organically with UI components scattered across files and multiple competing token systems. There is no single source of truth for colors, spacing, radii, typography, or reusable components. This leads to visual inconsistency, duplicated code, and makes it harder for contributors to build screens that look cohesive.

Component Inventory

An audit of the current codebase surfaces the following areas that need unification.

1. Design Tokens

Current state: Multiple competing token sources.

Source Tokens File
OpenClawBrand accent, danger, ok, warn, info, graphite, sheetBackground Sources/Design/OpenClawBrand.swift
OpenClawProMetric pagePadding (18), cardRadius (10), controlRadius (8), bottomScrollInset (96) Sources/Design/OpenClawProComponents.swift
SettingsLayout cardRadius (12), rowHeight (58) Sources/Design/SettingsProTabSupport.swift
AgentLayout cardRadius (12), filterHeight (34), rowMinHeight (104) Sources/Design/AgentProTab.swift
ChatUIConstants bubbleMaxWidth (560), bubbleCorner (18) OpenClawChatUI/ChatMessageViews.swift
OpenClawChatTheme Separate accent reds, canvas gradients, panel colors OpenClawChatUI/ChatTheme.swift

Needed: Single token module covering:

  • Color palette (semantic: primary, secondary, accent, danger, warning, success, info)
  • Typography scale (with named styles for headings, body, captions, monospaced)
  • Spacing scale (e.g., 4/8/12/16/20/24/32)
  • Corner radius scale (small/medium/large)
  • Elevation/shadow definitions
  • Animation timing curves

2. Primitive Components

Buttons — Currently fragmented across .borderedProminent, .bordered, .plain, .borderless with inconsistent sizing (.large in onboarding, .small/.mini in-app). No shared primary/secondary button styles.

  • OpenClawPrimaryButton — full-width, accent tint, large control size
  • OpenClawSecondaryButton — bordered outline, accent tint
  • OpenClawDangerButton — destructive variant
  • OpenClawTextButton — minimal/plain action links

Banners/AlertsGatewayProblemBanner and TalkRuntimeIssueBanner are nearly identical but implemented separately.

  • Unified OpenClawBanner (severity: info/warning/error/pairing, optional actions, optional details sheet)
  • OpenClawToast (extract from VoiceWakeToast)

Toggles — Custom switch implemented 3 times (settingsSwitchIndicator, onboardingButtonToggle, skillToggle) with identical geometry due to iOS 26 NavigationStack crash.

  • Single OpenClawToggle component

Icon BadgesProIconBadge uses radius 8, CommandSessionRow uses radius 9, SettingsApprovalRow uses solid fill vs tinted fill.

  • Unified OpenClawIconBadge with consistent sizing (30×30) and radius

Input Fields — Search field capsule implemented locally in 4 places (agent overview, skills, workboard, skill workshop).

  • Shared OpenClawSearchField component

Cards/Containers:

  • Review ProCard vs CommandPanel (thin wrapper) — consolidate
  • Standardize card radius across settings (12), pro components (10), banners (16), and onboarding (18-20)

Status indicators:

  • ProStatusDot — already exists, verify consistent usage
  • Loading states — standardize between ProgressView overlay, inline small, and text placeholder patterns
  • Empty states — unify CommandEmptyStateRow, emptyDetailRow, and stateSection("Empty")

3. Layout Patterns

Screen templates — document and standardize:

  • Pro screen (ScrollView + card stack with OpenClawProBackground)
  • Form screen (native Form for settings-style input)
  • Hero screen (centered content + bottom CTA, used in onboarding/success)
  • List/detail screen
  • Split/adaptive layout (iPad sidebar, command center dual-column)

Navigation chrome:

  • Some screens hide nav bar + custom header (Chat, Talk, Command)
  • Others use standard .navigationTitle(.inline) (agent sub-routes, docs)
  • Document when to use which pattern

4. Status Colors

Multiple sources for the same semantic meaning:

Context Source
App shell OpenClawBrand.ok/warn/danger
Gateway banners SwiftUI .orange, .yellow, .red
Privacy permissions SwiftUI .green, .orange, .yellow, .red
Chat notices OpenClawChatTheme.danger
  • Map all status colors to OpenClawBrand semantic tokens

5. Interactive Patterns

  • Copy-to-clipboard — standardize with haptic feedback + brief toast/label
  • DisclosureGroup styling — consistent font, padding, background
  • Context menu / swipe action conventions
  • Pull-to-refresh (.refreshable) — used across agent destinations but styling varies

6. Documentation

  • apps/ios/DESIGN.md — living design guide covering all token scales, component catalog with usage examples, and screen layout patterns
  • SwiftUI preview catalog target (optional, future) — renders all components in one scrollable view

Migration Path

Suggested order to minimize disruption:

  1. Unify tokens — consolidate into expanded OpenClawBrand + OpenClawMetric
  2. Extract shared primitives — buttons, banners, toggles, badges, search fields into Sources/Design/
  3. Deduplicate — merge GatewayProblemBanner / TalkRuntimeIssueBanner, merge background patterns
  4. Standardize status colors — migrate all SwiftUI color literals to brand tokens
  5. Document — write DESIGN.md as components stabilize
  6. Adopt — update existing screens file-by-file (settings, agent, onboarding, gateway)

Evidence

Component inventory derived from full audit of apps/ios/Sources/ and apps/shared/OpenClawKit/Sources/OpenClawChatUI/.

Key files with design debt:

  • OpenClawProComponents.swift (340+ LOC of core components + metric tokens)
  • SettingsProTabSupport.swift (competing layout metrics + duplicate toggles)
  • GatewayProblemView.swift / TalkRuntimeIssueBanner.swift (near-identical banners)
  • OnboardingWizardView.swift (standalone spacing, unique button patterns)

Joel Nishanth · offlyn.AI

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low-priority cleanup, docs, polish, ergonomics, or speculative work.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🌊 off-meta tidepoolIssue quality rating does not apply to this item.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions