Repository: airbnb/lottie-ios
File: Sources/Public/Configuration/ReducedMotionOption.swift (Swift)

Code before:
  }

  public func hash(into hasher: inout Hasher) {
    switch self {
    case .specific(let mode):
      hasher.combine(mode)
    case .dynamic(_, let dataID):
      hasher.combine(dataID)
    }
  }
}

// MARK: - ReducedMotionMode

public enum ReducedMotionMode: Hashable {
  /// The default behavior where Lottie animations play normally with no overrides
  /// By default this mode is used when the system "reduced motion" option is disabled.
  case standardMotion

  /// Lottie animations with a "reduced motion" marker will play that marker instead of any other animations.
  /// By default this mode is used when the system "reduced motion" option is enabled.
  case reducedMotion

  /// Animations are forced to render statically at their first frame instead of playing.
  /// This is useful for snapshot testing where animation non-determinism can cause flaky tests.
  case staticRendering
}

// MARK: - ReducedMotionOptionProvider

/// A type that returns a dynamic `ReducedMotionMode` which is checked when playing a Lottie animation.
public protocol ReducedMotionOptionProvider {
  var currentReducedMotionMode: ReducedMotionMode { get }
}

// MARK: - SystemReducedMotionOptionProvider

/// A `ReducedMotionOptionProvider` that returns `.reducedMotion` when
/// the system `UIAccessibility.isReduceMotionEnabled` option is `true`.
public struct SystemReducedMotionOptionProvider: ReducedMotionOptionProvider {
  public init() { }

  public var currentReducedMotionMode: ReducedMotionMode {
    #if canImport(UIKit)
    if UIAccessibility.isReduceMotionEnabled {
      return .reducedMotion
    } else {
      return .standardMotion
    }
    #else
    return .standardMotion

Review comment (suggestion):
For consistency with the other cases `standardMotion` and `reducedMotion`, how about:

```suggestion
  case disabledMotion
```

Code after:
  }

  public func hash(into hasher: inout Hasher) {
    switch self {
    case .specific(let mode):
      hasher.combine(mode)
    case .dynamic(_, let dataID):
      hasher.combine(dataID)
    }
  }
}

// MARK: - ReducedMotionMode

public enum ReducedMotionMode: Hashable {
  /// The default behavior where Lottie animations play normally with no overrides
  /// By default this mode is used when the system "reduced motion" option is disabled.
  case standardMotion

  /// Lottie animations with a "reduced motion" marker will play that marker instead of any other animations.
  /// By default this mode is used when the system "reduced motion" option is enabled.
  case reducedMotion

  /// Animations are disabled and render statically at their first frame instead of playing.
  /// This is useful for snapshot testing where animation non-determinism can cause flaky tests.
  case disabledMotion
}

// MARK: - ReducedMotionOptionProvider

/// A type that returns a dynamic `ReducedMotionMode` which is checked when playing a Lottie animation.
public protocol ReducedMotionOptionProvider {
  var currentReducedMotionMode: ReducedMotionMode { get }
}

// MARK: - SystemReducedMotionOptionProvider

/// A `ReducedMotionOptionProvider` that returns `.reducedMotion` when
/// the system `UIAccessibility.isReduceMotionEnabled` option is `true`.
public struct SystemReducedMotionOptionProvider: ReducedMotionOptionProvider {
  public init() { }

  public var currentReducedMotionMode: ReducedMotionMode {
    #if canImport(UIKit)
    if UIAccessibility.isReduceMotionEnabled {
      return .reducedMotion
    } else {
      return .standardMotion
    }
    #else
    return .standardMotion