diff --git a/ios/.swiftlint.yml b/ios/.swiftlint.yml index 13d1cb2..3c7d377 100644 --- a/ios/.swiftlint.yml +++ b/ios/.swiftlint.yml @@ -10,6 +10,11 @@ disabled_rules: # collection literals. SwiftLint's `trailing_comma` rule forbids them by # default, which conflicts. swift-format is authoritative — disable here. - trailing_comma + # swift-format wraps declarations with long protocol conformance lists + # onto multiple lines, placing the opening brace on its own line. + # SwiftLint's `opening_brace` insists the brace stay on the declaration + # line. Same precedent as `trailing_comma` — swift-format is authoritative. + - opening_brace # Design-system token names (MWSpacing.s, MWRadius.m, …) intentionally use # one- and two-character identifiers to match the canonical t-shirt scale. diff --git a/ios/Flashcards/App/RootView.swift b/ios/Flashcards/App/RootView.swift index 4b210d5..05b8a4d 100644 --- a/ios/Flashcards/App/RootView.swift +++ b/ios/Flashcards/App/RootView.swift @@ -60,22 +60,24 @@ struct RootView: View { .font(MWType.headingM).foregroundStyle(MWColor.ink) default: switch step { - case .splash: SplashView().task { - try? await Task.sleep(nanoseconds: 1_200_000_000) - step = .intro1 - } + case .splash: + SplashView().task { + try? await Task.sleep(nanoseconds: 1_200_000_000) + step = .intro1 + } case .intro1: Intro1View { step = .intro2 } case .intro2: Intro2View { step = .signup } - case .signup: SignUpWallView( - onAppleSignIn: { - try? await auth.signInWithApple() - }, - onRequestMagicLink: { email in - try? await auth.requestMagicLink(email: email) - emailSent = email - step = .magicLinkSent - } - ) + case .signup: + SignUpWallView( + onAppleSignIn: { + try? await auth.signInWithApple() + }, + onRequestMagicLink: { email in + try? await auth.requestMagicLink(email: email) + emailSent = email + step = .magicLinkSent + } + ) case .magicLinkSent: MagicLinkSentView(email: emailSent ?? "") } diff --git a/ios/Flashcards/DesignSystem/Components/Layout/MWScreen.swift b/ios/Flashcards/DesignSystem/Components/Layout/MWScreen.swift index e6cf308..333614d 100644 --- a/ios/Flashcards/DesignSystem/Components/Layout/MWScreen.swift +++ b/ios/Flashcards/DesignSystem/Components/Layout/MWScreen.swift @@ -35,6 +35,8 @@ public struct MWScreen: View { self.content = content } + /// Renders the canvas background, the optional grid overlay, and the + /// supplied `content()` stacked in a `ZStack`. public var body: some View { ZStack { MWColor.canvas.ignoresSafeArea() diff --git a/ios/Flashcards/DesignSystem/EnvironmentKeys/MWAccentKey.swift b/ios/Flashcards/DesignSystem/EnvironmentKeys/MWAccentKey.swift index 282b935..bfcb161 100644 --- a/ios/Flashcards/DesignSystem/EnvironmentKeys/MWAccentKey.swift +++ b/ios/Flashcards/DesignSystem/EnvironmentKeys/MWAccentKey.swift @@ -32,5 +32,7 @@ public extension EnvironmentValues { public extension View { /// Scopes the `mwAccent` environment value for the receiver and its descendants. /// - Parameter color: The accent color (usually an `MWAccent.color`). + /// - Returns: A view whose subtree reads the supplied accent colour via + /// `@Environment(\.mwAccent)`. func mwAccent(_ color: Color) -> some View { environment(\.mwAccent, color) } } diff --git a/ios/Flashcards/DesignSystem/Modifiers/MWButtonPress.swift b/ios/Flashcards/DesignSystem/Modifiers/MWButtonPress.swift index ad5b75f..a21ea0b 100644 --- a/ios/Flashcards/DesignSystem/Modifiers/MWButtonPress.swift +++ b/ios/Flashcards/DesignSystem/Modifiers/MWButtonPress.swift @@ -26,6 +26,12 @@ public struct MWButtonPress: ViewModifier { @Environment(\.accessibilityReduceMotion) private var reduceMotion + /// Applies the press-scale + reduce-motion-safe animation to `content`. + /// + /// - Parameter content: The view being decorated. + /// - Returns: A view that scales to `pressedScale` while `isPressed` is + /// true, returning to `1.0` otherwise, with the transition collapsed + /// to an instantaneous change when Reduce Motion is enabled. public func body(content: Content) -> some View { content .scaleEffect(isPressed ? Self.pressedScale : 1.0) diff --git a/ios/Flashcards/DesignSystem/Tokens/Borders.swift b/ios/Flashcards/DesignSystem/Tokens/Borders.swift index d8fc5fb..411c3da 100644 --- a/ios/Flashcards/DesignSystem/Tokens/Borders.swift +++ b/ios/Flashcards/DesignSystem/Tokens/Borders.swift @@ -55,6 +55,7 @@ public extension View { /// - cornerRadius: Corner radius for the overlay shape. Defaults to `0` /// (sharp rectangle). Pass the same value used in an upstream /// `mwCornerRadius` so the stroke hugs the rounded clip. + /// - Returns: A view overlaid with the configured stroke. func mwStroke( color: Color = MWColor.ink, width: CGFloat = MWBorder.defaultWidth, diff --git a/ios/Flashcards/Features/Auth/AppleSignInService.swift b/ios/Flashcards/Features/Auth/AppleSignInService.swift index 2a5a024..0f39e3b 100644 --- a/ios/Flashcards/Features/Auth/AppleSignInService.swift +++ b/ios/Flashcards/Features/Auth/AppleSignInService.swift @@ -82,7 +82,8 @@ public final class AppleSignInService: NSObject, ObservableObject, ASAuthorizationControllerDelegate, - ASAuthorizationControllerPresentationContextProviding { + ASAuthorizationControllerPresentationContextProviding +{ /// Pending continuation for the in-flight `signIn()` call. Lives on /// the instance because the delegate callbacks can't capture it /// directly. Cleared the moment it is resumed. diff --git a/ios/Flashcards/Features/Onboarding/SignUpWallView.swift b/ios/Flashcards/Features/Onboarding/SignUpWallView.swift index 5ffc779..8f277cf 100644 --- a/ios/Flashcards/Features/Onboarding/SignUpWallView.swift +++ b/ios/Flashcards/Features/Onboarding/SignUpWallView.swift @@ -54,18 +54,25 @@ struct SignUpWallView: View { MWEyebrow("Save your progress") Text("No password required.") .font(MWType.headingL).foregroundStyle(MWColor.ink) - // swiftlint:disable:next line_length - Text("We ask for your email so your flashcards live in your account, not just this device. If you lose your phone, you won't lose a single card.") - .font(MWType.bodyL).foregroundStyle(MWColor.inkMuted) + Text( + "We ask for your email so your flashcards live in your account, " + + "not just this device. If you lose your phone, you won't " + + "lose a single card." + ) + .font(MWType.bodyL).foregroundStyle(MWColor.inkMuted) MWButton("Continue with Apple") { - Task { isSubmitting = true; await onAppleSignIn(); isSubmitting = false } + Task { + isSubmitting = true; await onAppleSignIn(); isSubmitting = false + } } MWTextField(label: "Email", text: $email, contentType: .emailAddress, keyboard: .emailAddress) MWButton("Continue with email", kind: .secondary) { - Task { isSubmitting = true; await onRequestMagicLink(email); isSubmitting = false } + Task { + isSubmitting = true; await onRequestMagicLink(email); isSubmitting = false + } }.disabled(email.isEmpty || isSubmitting) Text("Free to use. No payment needed. We won't sell your data or email you marketing.")