From bd69d8fc0af1e8f2cff042d36e0f424038da0b44 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 27 Jan 2026 08:29:20 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- README.md | 2 +- .../Bedrock/Views/Settings/BadgePill.swift | 3 +- .../Bedrock/Views/Settings/LicensesView.swift | 8 ++--- .../Bedrock/Views/Settings/SETTINGS_GUIDE.md | 29 ++++++++++--------- .../Views/Settings/SegmentedPicker.swift | 4 +-- .../Views/Settings/SelectableRow.swift | 4 +-- .../Settings/SettingsNavigationRow.swift | 6 ++-- .../Bedrock/Views/Settings/SettingsRow.swift | 8 ++--- .../Settings/SettingsSectionHeader.swift | 4 +-- .../Settings/SettingsSegmentedPicker.swift | 8 ++--- .../Views/Settings/SettingsSlider.swift | 11 +++---- .../Views/Settings/SettingsToggle.swift | 6 ++-- .../Settings/iCloudSyncSettingsView.swift | 6 ++-- Tests/BedrockTests/BedrockTests.swift | 8 ++--- 14 files changed, 55 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index f4f6257..a6071a7 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ struct MyView: View { var body: some View { VStack(spacing: Design.Spacing.medium) { Text("Hello") - .font(.system(size: Design.BaseFontSize.title)) + .font(.title) .padding(Design.Spacing.large) Button("Tap Me") { } diff --git a/Sources/Bedrock/Views/Settings/BadgePill.swift b/Sources/Bedrock/Views/Settings/BadgePill.swift index 4a61764..8b3cee3 100644 --- a/Sources/Bedrock/Views/Settings/BadgePill.swift +++ b/Sources/Bedrock/Views/Settings/BadgePill.swift @@ -37,7 +37,8 @@ public struct BadgePill: View { public var body: some View { Text(text) - .font(.system(size: Design.BaseFontSize.body, weight: .bold, design: .rounded)) + .font(.subheadline.weight(.bold)) + .fontDesign(.rounded) .foregroundStyle(isSelected ? .black : accentColor) .padding(.horizontal, Design.Spacing.small) .padding(.vertical, Design.Spacing.xSmall) diff --git a/Sources/Bedrock/Views/Settings/LicensesView.swift b/Sources/Bedrock/Views/Settings/LicensesView.swift index ed6faab..cc29b31 100644 --- a/Sources/Bedrock/Views/Settings/LicensesView.swift +++ b/Sources/Bedrock/Views/Settings/LicensesView.swift @@ -76,16 +76,16 @@ public struct LicensesView: View { SettingsCard(backgroundColor: cardBackgroundColor, borderColor: cardBorderColor) { VStack(alignment: .leading, spacing: Design.Spacing.small) { Text(license.name) - .font(.system(size: Design.BaseFontSize.medium, weight: .bold)) + .font(.subheadline.weight(.bold)) .foregroundStyle(.white) Text(license.description) - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.white.opacity(Design.Opacity.strong)) HStack { Label(license.licenseType, systemImage: "doc.text") - .font(.system(size: Design.BaseFontSize.xSmall)) + .font(.caption2) .foregroundStyle(accentColor) Spacer() @@ -93,7 +93,7 @@ public struct LicensesView: View { if let linkURL = URL(string: license.url) { Link(destination: linkURL) { Label(String(localized: "View on GitHub"), systemImage: "arrow.up.right.square") - .font(.system(size: Design.BaseFontSize.xSmall)) + .font(.caption2) .foregroundStyle(accentColor) } } diff --git a/Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md b/Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md index 7a0f9ce..4ccc314 100644 --- a/Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md +++ b/Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md @@ -316,16 +316,16 @@ Toggle(isOn: $isOn) { VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) { HStack(spacing: Design.Spacing.xSmall) { Text(title) - .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.white) Image(systemName: "crown.fill") - .font(.system(size: Design.BaseFontSize.small)) + .font(.caption2) .foregroundStyle(AppStatus.warning) } Text(subtitle) - .font(.system(size: Design.BaseFontSize.body)) + .font(.subheadline) .foregroundStyle(.white.opacity(Design.Opacity.medium)) } } @@ -391,28 +391,29 @@ SettingsSlider( VStack(alignment: .leading, spacing: Design.Spacing.small) { HStack { Text("Ring Size") - .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.white) Spacer() Text("\(Int(viewModel.ringSize))pt") - .font(.system(size: Design.BaseFontSize.body, weight: .medium, design: .rounded)) + .font(.subheadline.weight(.medium)) + .fontDesign(.rounded) .foregroundStyle(.white.opacity(Design.Opacity.medium)) } Text("Adjusts the size of the ring") - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.white.opacity(Design.Opacity.medium)) HStack(spacing: Design.Spacing.medium) { Image(systemName: "circle") - .font(.system(size: Design.BaseFontSize.small)) + .font(.caption2) .foregroundStyle(.white.opacity(Design.Opacity.medium)) Slider(value: $viewModel.ringSize, in: 20...100, step: 5) .tint(AppAccent.primary) Image(systemName: "circle") - .font(.system(size: Design.BaseFontSize.large)) + .font(.callout) .foregroundStyle(.white.opacity(Design.Opacity.medium)) } } @@ -458,18 +459,18 @@ NavigationLink { HStack { VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) { Text("Open Source Licenses") - .font(.system(size: Design.BaseFontSize.body, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.white) Text("Third-party libraries used in this app") - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.white.opacity(Design.Opacity.medium)) } Spacer() Image(systemName: "chevron.right") - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.white.opacity(Design.Opacity.medium)) } .padding(Design.Spacing.medium) @@ -576,11 +577,11 @@ SettingsSegmentedPicker( // ❌ BEFORE: Inline title/subtitle with SegmentedPicker VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) { Text("Camera") - .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.white) Text("Choose between front and back camera lenses") - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.white.opacity(Design.Opacity.medium)) SegmentedPicker( @@ -923,7 +924,7 @@ SettingsView() 4. **Section-specific accents**: Use `AppStatus.warning` for premium sections, `AppStatus.error` for debug. -5. **Test with Dynamic Type**: Bedrock uses `Design.BaseFontSize` values that scale properly. +5. **Test with Dynamic Type**: Bedrock uses iOS semantic fonts (`.body`, `.caption`, etc.) that scale properly with Dynamic Type. 6. **Avoid `Color.` typealiases**: Use `App`-prefixed typealiases to prevent conflicts with Bedrock's defaults. diff --git a/Sources/Bedrock/Views/Settings/SegmentedPicker.swift b/Sources/Bedrock/Views/Settings/SegmentedPicker.swift index 8af0826..182dcd6 100644 --- a/Sources/Bedrock/Views/Settings/SegmentedPicker.swift +++ b/Sources/Bedrock/Views/Settings/SegmentedPicker.swift @@ -52,7 +52,7 @@ public struct SegmentedPicker: View { public var body: some View { VStack(alignment: .leading, spacing: Design.Spacing.small) { Text(title) - .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.white) HStack(spacing: Design.Spacing.small) { @@ -62,7 +62,7 @@ public struct SegmentedPicker: View { selection = option.1 } label: { Text(option.0) - .font(.system(size: Design.BaseFontSize.body, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(selection == option.1 ? .black : .white.opacity(Design.Opacity.strong)) .padding(.vertical, Design.Spacing.small) .frame(maxWidth: .infinity) diff --git a/Sources/Bedrock/Views/Settings/SelectableRow.swift b/Sources/Bedrock/Views/Settings/SelectableRow.swift index b2e2c97..4f796e6 100644 --- a/Sources/Bedrock/Views/Settings/SelectableRow.swift +++ b/Sources/Bedrock/Views/Settings/SelectableRow.swift @@ -68,11 +68,11 @@ public struct SelectableRow: View { HStack { VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) { Text(title) - .font(.system(size: Design.BaseFontSize.large, weight: .semibold)) + .font(.callout.weight(.semibold)) .foregroundStyle(.white) Text(subtitle) - .font(.system(size: Design.BaseFontSize.body)) + .font(.subheadline) .foregroundStyle(.white.opacity(Design.Opacity.medium)) } diff --git a/Sources/Bedrock/Views/Settings/SettingsNavigationRow.swift b/Sources/Bedrock/Views/Settings/SettingsNavigationRow.swift index 6d82cf5..bde6f85 100644 --- a/Sources/Bedrock/Views/Settings/SettingsNavigationRow.swift +++ b/Sources/Bedrock/Views/Settings/SettingsNavigationRow.swift @@ -68,12 +68,12 @@ public struct SettingsNavigationRow: View { HStack { VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) { Text(title) - .font(.system(size: Design.BaseFontSize.body, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.primary) if let subtitle { Text(subtitle) - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.secondary) } } @@ -81,7 +81,7 @@ public struct SettingsNavigationRow: View { Spacer() Image(systemName: "chevron.right") - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.secondary) } .padding(Design.Spacing.medium) diff --git a/Sources/Bedrock/Views/Settings/SettingsRow.swift b/Sources/Bedrock/Views/Settings/SettingsRow.swift index ded3159..6e55f02 100644 --- a/Sources/Bedrock/Views/Settings/SettingsRow.swift +++ b/Sources/Bedrock/Views/Settings/SettingsRow.swift @@ -55,21 +55,21 @@ public struct SettingsRow: View { Button(action: action) { HStack(spacing: Design.Spacing.medium) { Image(systemName: systemImage) - .font(.system(size: Design.BaseFontSize.medium)) + .font(.subheadline) .foregroundStyle(.white) .frame(width: Design.Size.iconContainerSmall, height: Design.Size.iconContainerSmall) .background(iconColor.opacity(Design.Opacity.heavy)) .clipShape(.rect(cornerRadius: Design.CornerRadius.xSmall)) Text(title) - .font(.system(size: Design.BaseFontSize.medium)) + .font(.subheadline) .foregroundStyle(.primary) Spacer() if let value { Text(value) - .font(.system(size: Design.BaseFontSize.body)) + .font(.subheadline) .foregroundStyle(.secondary) } @@ -77,7 +77,7 @@ public struct SettingsRow: View { accessory } else { Image(systemName: "chevron.right") - .font(.system(size: Design.BaseFontSize.body, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.tertiary) } } diff --git a/Sources/Bedrock/Views/Settings/SettingsSectionHeader.swift b/Sources/Bedrock/Views/Settings/SettingsSectionHeader.swift index 2d33303..f475627 100644 --- a/Sources/Bedrock/Views/Settings/SettingsSectionHeader.swift +++ b/Sources/Bedrock/Views/Settings/SettingsSectionHeader.swift @@ -37,12 +37,12 @@ public struct SettingsSectionHeader: View { HStack(spacing: Design.Spacing.small) { if let systemImage { Image(systemName: systemImage) - .font(.system(size: Design.BaseFontSize.medium)) + .font(.subheadline) .foregroundStyle(accentColor.opacity(Design.Opacity.strong)) } Text(title) - .font(.system(size: Design.BaseFontSize.caption, weight: .semibold)) + .font(.caption.weight(.semibold)) .foregroundStyle(.secondary) .textCase(.uppercase) .tracking(0.5) diff --git a/Sources/Bedrock/Views/Settings/SettingsSegmentedPicker.swift b/Sources/Bedrock/Views/Settings/SettingsSegmentedPicker.swift index 840562e..75426dc 100644 --- a/Sources/Bedrock/Views/Settings/SettingsSegmentedPicker.swift +++ b/Sources/Bedrock/Views/Settings/SettingsSegmentedPicker.swift @@ -80,18 +80,18 @@ public struct SettingsSegmentedPicker: View { // Title row with optional accessory HStack(spacing: Design.Spacing.xSmall) { Text(title) - .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.primary) if let titleAccessory { titleAccessory - .font(.system(size: Design.BaseFontSize.small)) + .font(.caption2) } } // Subtitle Text(subtitle) - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.secondary) // Segmented buttons @@ -102,7 +102,7 @@ public struct SettingsSegmentedPicker: View { selection = option.1 } label: { Text(option.0) - .font(.system(size: Design.BaseFontSize.body, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(selection == option.1 ? Color.white : .primary) .padding(.vertical, Design.Spacing.small) .frame(maxWidth: .infinity) diff --git a/Sources/Bedrock/Views/Settings/SettingsSlider.swift b/Sources/Bedrock/Views/Settings/SettingsSlider.swift index c3f75ab..0c38ad7 100644 --- a/Sources/Bedrock/Views/Settings/SettingsSlider.swift +++ b/Sources/Bedrock/Views/Settings/SettingsSlider.swift @@ -111,24 +111,25 @@ public struct SettingsSlider: View where VStack(alignment: .leading, spacing: Design.Spacing.small) { HStack { Text(title) - .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.primary) Spacer() Text(format(value)) - .font(.system(size: Design.BaseFontSize.body, weight: .medium, design: .rounded)) + .font(.subheadline.weight(.medium)) + .fontDesign(.rounded) .foregroundStyle(.secondary) } Text(subtitle) - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.secondary) HStack(spacing: Design.Spacing.medium) { if let leadingIcon { leadingIcon - .font(.system(size: Design.BaseFontSize.small)) + .font(.caption2) .foregroundStyle(.secondary) } @@ -137,7 +138,7 @@ public struct SettingsSlider: View where if let trailingIcon { trailingIcon - .font(.system(size: Design.BaseFontSize.large)) + .font(.callout) .foregroundStyle(.secondary) } } diff --git a/Sources/Bedrock/Views/Settings/SettingsToggle.swift b/Sources/Bedrock/Views/Settings/SettingsToggle.swift index 6dfebd0..aafbf88 100644 --- a/Sources/Bedrock/Views/Settings/SettingsToggle.swift +++ b/Sources/Bedrock/Views/Settings/SettingsToggle.swift @@ -79,17 +79,17 @@ public struct SettingsToggle: View { VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) { HStack(spacing: Design.Spacing.xSmall) { Text(title) - .font(.system(size: Design.BaseFontSize.medium, weight: .medium)) + .font(.subheadline.weight(.medium)) .foregroundStyle(.primary) if let titleAccessory { titleAccessory - .font(.system(size: Design.BaseFontSize.small)) + .font(.caption2) } } Text(subtitle) - .font(.system(size: Design.BaseFontSize.body)) + .font(.subheadline) .foregroundStyle(.secondary) } } diff --git a/Sources/Bedrock/Views/Settings/iCloudSyncSettingsView.swift b/Sources/Bedrock/Views/Settings/iCloudSyncSettingsView.swift index 8f1af40..4e8a4b5 100644 --- a/Sources/Bedrock/Views/Settings/iCloudSyncSettingsView.swift +++ b/Sources/Bedrock/Views/Settings/iCloudSyncSettingsView.swift @@ -116,11 +116,11 @@ public struct iCloudSyncSettingsView: View { if viewModel.iCloudEnabled && viewModel.iCloudAvailable { HStack(spacing: Design.Spacing.small) { Image(systemName: syncStatusIcon) - .font(.system(size: Design.BaseFontSize.body)) + .font(.subheadline) .foregroundStyle(syncStatusColor) Text(syncStatusText) - .font(.system(size: Design.BaseFontSize.caption)) + .font(.caption) .foregroundStyle(.white.opacity(Design.Opacity.medium)) Spacer() @@ -129,7 +129,7 @@ public struct iCloudSyncSettingsView: View { viewModel.forceSync() } label: { Text(String(localized: "Sync Now")) - .font(.system(size: Design.BaseFontSize.caption, weight: .medium)) + .font(.caption.weight(.medium)) .foregroundStyle(accentColor) } } diff --git a/Tests/BedrockTests/BedrockTests.swift b/Tests/BedrockTests/BedrockTests.swift index 8746ab1..1994dd2 100644 --- a/Tests/BedrockTests/BedrockTests.swift +++ b/Tests/BedrockTests/BedrockTests.swift @@ -45,10 +45,10 @@ final class BedrockTests: XCTestCase { XCTAssertGreaterThan(Design.Animation.springDuration, 0) } - func testFontSizesArePositive() { - XCTAssertGreaterThan(Design.BaseFontSize.small, 0) - XCTAssertGreaterThan(Design.BaseFontSize.body, 0) - XCTAssertGreaterThan(Design.BaseFontSize.title, 0) + func testIconSizesArePositive() { + XCTAssertGreaterThan(Design.IconSize.small, 0) + XCTAssertGreaterThan(Design.IconSize.medium, 0) + XCTAssertGreaterThan(Design.IconSize.large, 0) } func testMinimumTouchTargetMeetsHIG() {