Product Components/SettingsScreen
Screen

SettingsScreen

A fully-composed settings screen using DSListRow, DSToggle, DSAvatar, and destructive action buttons. Covers the most common settings patterns — notifications, appearance, account, danger zone.

Preview

Settings

AM

Ana Mello

ana@mello.dev

Preferences

Push notifications

Dark mode

Language

English

Account

Change password

Export data

Privacy policy

Delete account

Components used

DSAvatar

Profile picture with status

DSListRow

Each setting row with icon + chevron

DSToggle

Notifications, dark mode, etc.

DSNavigationBar

Top title + optional back button

DSButton

.destructive for delete account

DSModal

Confirmation before destructive action

DSToast

Feedback after saving changes

DSSection

Grouped rows (Preferences, Account)

Full implementation

SettingsScreen.swift
import SwiftUI
import SwiftDS

struct SettingsScreen: View {
    @StateObject private var vm = SettingsViewModel()

    var body: some View {
        DSPageLayout {
            DSNavigationBar(title: "Settings")

            // Profile card
            DSCard(variant: .outlined, isInteractive: true) {
                action: { vm.openProfile() }
                HStack(spacing: DSSpacing.md) {
                    DSAvatar(
                        imageURL: vm.user.avatarURL,
                        initials: vm.user.initials,
                        size: .lg,
                        status: .online
                    )
                    VStack(alignment: .leading, spacing: DSSpacing.xs) {
                        DSText(vm.user.name, style: .headline)
                        DSText(vm.user.email, style: .footnote)
                            .foregroundColor(DSColor.textSecondary)
                    }
                    Spacer()
                    DSIconButton(icon: "chevron.right", variant: .ghost, action: { vm.openProfile() })
                }
            }
            .padding(.horizontal, DSSpacing.md)

            // Preferences
            DSSection(title: "Preferences") {
                DSListRow(
                    icon: "bell.fill",
                    title: "Push notifications",
                    trailing: { DSToggle(isOn: $vm.notificationsEnabled) }
                )
                DSListRow(
                    icon: "moon.fill",
                    title: "Dark mode",
                    trailing: { DSToggle(isOn: $vm.darkModeEnabled) }
                )
                DSListRow(
                    icon: "globe",
                    title: "Language",
                    value: vm.language,
                    action: { vm.openLanguagePicker() }
                )
            }

            // Account
            DSSection(title: "Account") {
                DSListRow(icon: "lock.fill", title: "Change password", action: { vm.changePassword() })
                DSListRow(icon: "square.and.arrow.up", title: "Export data", action: { vm.exportData() })
                DSListRow(icon: "doc.text", title: "Privacy policy", action: { vm.openPrivacyPolicy() })
            }

            // Danger zone
            DSSection(title: "Danger Zone") {
                DSButton(
                    "Delete account",
                    variant: .destructive,
                    action: { vm.showDeleteConfirmation = true }
                )
                .padding(.horizontal, DSSpacing.md)
            }
        }
        .dsToast(
            isPresented: $vm.showSavedToast,
            title: "Settings saved",
            style: .success
        )
        .alert(
            "Delete account?",
            isPresented: $vm.showDeleteConfirmation
        ) {
            Button("Cancel", role: .cancel) {}
            Button("Delete", role: .destructive) { vm.deleteAccount() }
        } message: {
            Text("This action cannot be undone. All your data will be permanently deleted.")
        }
    }
}