diff --git a/Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md b/Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md index 0c7146a..acdbdc4 100644 --- a/Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md +++ b/Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md @@ -868,12 +868,12 @@ SettingsCard(backgroundColor: AppSurface.card, borderColor: AppBorder.subtle) { |-----------|----------|----------------| | `SettingsCard` | Group related settings | `backgroundColor`, `borderColor` | | `SettingsSectionHeader` | Section titles | `title`, `systemImage`, `accentColor` | -| `SettingsToggle` | Boolean settings | `title`, `subtitle`, `isOn`, `titleAccessory` | -| `SettingsSlider` | Numeric settings | `value`, `range`, `format`, icons | -| `SettingsNavigationRow` | Navigate to detail | `title`, `subtitle`, `destination` | -| `SettingsSegmentedPicker` | Option selection | `title`, `subtitle`, `options`, `titleAccessory` | +| `SettingsToggle` | Boolean settings | `title`, `subtitle`, `isOn`, `accentColor` | +| `SettingsSlider` | Numeric settings | `value`, `range`, `format`, `accentColor` | +| `SettingsNavigationRow` | Navigate to detail | `title`, `subtitle`, `backgroundColor` | +| `SettingsSegmentedPicker` | Option selection | `title`, `subtitle`, `options`, `accentColor` | | `SegmentedPicker` | Low-level picker | `title`, `options`, `selection` | -| `SettingsRow` | Action rows | `systemImage`, `title`, `action` | +| `SettingsRow` | Action rows | `systemImage`, `title`, `iconColor` | | `SelectableRow` | Card selection | `title`, `isSelected`, `badge` | | `BadgePill` | Price/tag badges | `text`, `isSelected` | | `iCloudSyncSettingsView` | iCloud sync controls | `viewModel: CloudSyncable`, colors | @@ -881,6 +881,19 @@ SettingsCard(backgroundColor: AppSurface.card, borderColor: AppBorder.subtle) { --- +## Light & Dark Mode Support + +All settings components use SwiftUI's semantic colors (`.primary`, `.secondary`, `.tertiary`) which automatically adapt to the system appearance. No extra configuration needed—components work in both light and dark mode out of the box. + +To force a specific appearance for your settings screen: + +```swift +SettingsView() + .preferredColorScheme(.dark) // Force dark mode +``` + +--- + ## Color Relationship Guide | Surface Level | Use Case | Visual Depth | diff --git a/Sources/Bedrock/Views/Settings/SettingsNavigationRow.swift b/Sources/Bedrock/Views/Settings/SettingsNavigationRow.swift index a52700c..6d82cf5 100644 --- a/Sources/Bedrock/Views/Settings/SettingsNavigationRow.swift +++ b/Sources/Bedrock/Views/Settings/SettingsNavigationRow.swift @@ -12,12 +12,23 @@ import SwiftUI /// Use this for settings that navigate to a detail view. /// /// ```swift +/// // Dark theme (default) /// SettingsNavigationRow( /// title: "Open Source Licenses", /// subtitle: "Third-party libraries used in this app" /// ) { /// LicensesView() /// } +/// +/// // Light theme +/// SettingsNavigationRow( +/// title: "Privacy Policy", +/// subtitle: "How we handle your data", +/// textColor: AppText.primary, +/// secondaryTextColor: AppText.secondary +/// ) { +/// PrivacyView() +/// } /// ``` public struct SettingsNavigationRow: View { /// The row title. @@ -58,12 +69,12 @@ public struct SettingsNavigationRow: View { VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) { Text(title) .font(.system(size: Design.BaseFontSize.body, weight: .medium)) - .foregroundStyle(.white) + .foregroundStyle(.primary) if let subtitle { Text(subtitle) .font(.system(size: Design.BaseFontSize.caption)) - .foregroundStyle(.white.opacity(Design.Opacity.medium)) + .foregroundStyle(.secondary) } } @@ -71,7 +82,7 @@ public struct SettingsNavigationRow: View { Image(systemName: "chevron.right") .font(.system(size: Design.BaseFontSize.caption)) - .foregroundStyle(.white.opacity(Design.Opacity.medium)) + .foregroundStyle(.secondary) } .padding(Design.Spacing.medium) .background(backgroundColor, in: RoundedRectangle(cornerRadius: Design.CornerRadius.medium)) diff --git a/Sources/Bedrock/Views/Settings/SettingsRow.swift b/Sources/Bedrock/Views/Settings/SettingsRow.swift index 29e678e..ded3159 100644 --- a/Sources/Bedrock/Views/Settings/SettingsRow.swift +++ b/Sources/Bedrock/Views/Settings/SettingsRow.swift @@ -28,6 +28,13 @@ public struct SettingsRow: View { public let action: () -> Void /// Creates a settings row. + /// - Parameters: + /// - systemImage: SF Symbol name for the icon. + /// - title: The row title. + /// - value: Optional value text. + /// - iconColor: The icon background color (default: primary accent). + /// - accessory: Optional accessory view. + /// - action: Action when tapped. public init( systemImage: String, title: String, @@ -56,14 +63,14 @@ public struct SettingsRow: View { Text(title) .font(.system(size: Design.BaseFontSize.medium)) - .foregroundStyle(.white) + .foregroundStyle(.primary) Spacer() if let value { Text(value) .font(.system(size: Design.BaseFontSize.body)) - .foregroundStyle(.white.opacity(Design.Opacity.medium)) + .foregroundStyle(.secondary) } if let accessory { @@ -71,12 +78,12 @@ public struct SettingsRow: View { } else { Image(systemName: "chevron.right") .font(.system(size: Design.BaseFontSize.body, weight: .medium)) - .foregroundStyle(.white.opacity(Design.Opacity.light)) + .foregroundStyle(.tertiary) } } .padding(.vertical, Design.Spacing.medium) .padding(.horizontal, Design.Spacing.medium) - .background(Color.Surface.card) + .background(Color(.secondarySystemGroupedBackground)) .clipShape(.rect(cornerRadius: Design.CornerRadius.small)) } .buttonStyle(.plain) diff --git a/Sources/Bedrock/Views/Settings/SettingsSectionHeader.swift b/Sources/Bedrock/Views/Settings/SettingsSectionHeader.swift index e449962..2d33303 100644 --- a/Sources/Bedrock/Views/Settings/SettingsSectionHeader.swift +++ b/Sources/Bedrock/Views/Settings/SettingsSectionHeader.swift @@ -23,7 +23,11 @@ public struct SettingsSectionHeader: View { /// - title: The section title. /// - systemImage: Optional SF Symbol name. /// - accentColor: The accent color (default: primary accent). - public init(title: String, systemImage: String? = nil, accentColor: Color = .Accent.primary) { + public init( + title: String, + systemImage: String? = nil, + accentColor: Color = .Accent.primary + ) { self.title = title self.systemImage = systemImage self.accentColor = accentColor @@ -39,7 +43,7 @@ public struct SettingsSectionHeader: View { Text(title) .font(.system(size: Design.BaseFontSize.caption, weight: .semibold)) - .foregroundStyle(.white.opacity(Design.Opacity.accent)) + .foregroundStyle(.secondary) .textCase(.uppercase) .tracking(0.5) diff --git a/Sources/Bedrock/Views/Settings/SettingsSegmentedPicker.swift b/Sources/Bedrock/Views/Settings/SettingsSegmentedPicker.swift index de982b8..840562e 100644 --- a/Sources/Bedrock/Views/Settings/SettingsSegmentedPicker.swift +++ b/Sources/Bedrock/Views/Settings/SettingsSegmentedPicker.swift @@ -81,7 +81,7 @@ public struct SettingsSegmentedPicker: View { HStack(spacing: Design.Spacing.xSmall) { Text(title) .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) - .foregroundStyle(.white) + .foregroundStyle(.primary) if let titleAccessory { titleAccessory @@ -92,7 +92,7 @@ public struct SettingsSegmentedPicker: View { // Subtitle Text(subtitle) .font(.system(size: Design.BaseFontSize.caption)) - .foregroundStyle(.white.opacity(Design.Opacity.medium)) + .foregroundStyle(.secondary) // Segmented buttons HStack(spacing: Design.Spacing.small) { @@ -103,12 +103,12 @@ public struct SettingsSegmentedPicker: View { } label: { Text(option.0) .font(.system(size: Design.BaseFontSize.body, weight: .medium)) - .foregroundStyle(selection == option.1 ? .black : .white.opacity(Design.Opacity.strong)) + .foregroundStyle(selection == option.1 ? Color.white : .primary) .padding(.vertical, Design.Spacing.small) .frame(maxWidth: .infinity) .background( Capsule() - .fill(selection == option.1 ? accentColor : Color.white.opacity(Design.Opacity.subtle)) + .fill(selection == option.1 ? accentColor : Color.secondary.opacity(Design.Opacity.subtle)) ) } .buttonStyle(.plain) diff --git a/Sources/Bedrock/Views/Settings/SettingsSlider.swift b/Sources/Bedrock/Views/Settings/SettingsSlider.swift index e40d36a..c3f75ab 100644 --- a/Sources/Bedrock/Views/Settings/SettingsSlider.swift +++ b/Sources/Bedrock/Views/Settings/SettingsSlider.swift @@ -112,24 +112,24 @@ public struct SettingsSlider: View where HStack { Text(title) .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) - .foregroundStyle(.white) + .foregroundStyle(.primary) Spacer() Text(format(value)) .font(.system(size: Design.BaseFontSize.body, weight: .medium, design: .rounded)) - .foregroundStyle(.white.opacity(Design.Opacity.medium)) + .foregroundStyle(.secondary) } Text(subtitle) .font(.system(size: Design.BaseFontSize.caption)) - .foregroundStyle(.white.opacity(Design.Opacity.medium)) + .foregroundStyle(.secondary) HStack(spacing: Design.Spacing.medium) { if let leadingIcon { leadingIcon .font(.system(size: Design.BaseFontSize.small)) - .foregroundStyle(.white.opacity(Design.Opacity.medium)) + .foregroundStyle(.secondary) } Slider(value: $value, in: range, step: step) @@ -138,7 +138,7 @@ public struct SettingsSlider: View where if let trailingIcon { trailingIcon .font(.system(size: Design.BaseFontSize.large)) - .foregroundStyle(.white.opacity(Design.Opacity.medium)) + .foregroundStyle(.secondary) } } } diff --git a/Sources/Bedrock/Views/Settings/SettingsToggle.swift b/Sources/Bedrock/Views/Settings/SettingsToggle.swift index 6ef55c4..6dfebd0 100644 --- a/Sources/Bedrock/Views/Settings/SettingsToggle.swift +++ b/Sources/Bedrock/Views/Settings/SettingsToggle.swift @@ -12,13 +12,22 @@ import SwiftUI /// Use this for boolean settings that can be turned on or off. /// /// ```swift -/// // Basic toggle +/// // Basic toggle (dark theme) /// SettingsToggle( /// title: "Dark Mode", /// subtitle: "Use dark appearance", /// isOn: $settings.darkMode /// ) /// +/// // Light theme toggle +/// SettingsToggle( +/// title: "Notifications", +/// subtitle: "Receive push notifications", +/// isOn: $settings.notifications, +/// textColor: AppText.primary, +/// secondaryTextColor: AppText.secondary +/// ) +/// /// // Premium toggle with crown icon /// SettingsToggle( /// title: "Flash Sync", @@ -71,7 +80,7 @@ public struct SettingsToggle: View { HStack(spacing: Design.Spacing.xSmall) { Text(title) .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) - .foregroundStyle(.white) + .foregroundStyle(.primary) if let titleAccessory { titleAccessory @@ -81,7 +90,7 @@ public struct SettingsToggle: View { Text(subtitle) .font(.system(size: Design.BaseFontSize.body)) - .foregroundStyle(.white.opacity(Design.Opacity.medium)) + .foregroundStyle(.secondary) } } .tint(accentColor)