[PM-26063] Move IllustratedMessageView to BitwardenKit (#2096)

This commit is contained in:
Matt Czech 2025-11-04 13:17:13 -06:00 committed by GitHub
parent 50c52bd6e1
commit 9f71c1619d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 105 additions and 65 deletions

View File

@ -4,8 +4,9 @@ import SnapshotTesting
import SwiftUI
import XCTest
@testable import BitwardenShared
@testable import BitwardenKit
@MainActor
class IllustratedMessageViewTests: BitwardenTestCase {
// MARK: Tests
@ -29,7 +30,7 @@ class IllustratedMessageViewTests: BitwardenTestCase {
/// Test snapshots of the mediumImage style.
func disabletest_snapshot_mediumImage() {
let subject = IllustratedMessageView(
image: Asset.Images.Illustrations.biometricsPhone,
image: SharedAsset.Icons.unlocked24,
style: .mediumImage,
title: Localizations.setUpUnlock,
message: Localizations.setUpBiometricsOrChooseAPinCodeToQuicklyAccessYourVaultAndAutofillYourLogins,
@ -46,7 +47,7 @@ class IllustratedMessageViewTests: BitwardenTestCase {
/// Test snapshots of the mediumImage style with a button.
func disabletest_snapshot_mediumImage_withButton() {
let subject = IllustratedMessageView(
image: Asset.Images.Illustrations.biometricsPhone,
image: SharedAsset.Icons.unlocked24,
style: .mediumImage,
title: Localizations.setUpUnlock,
message: Localizations.setUpBiometricsOrChooseAPinCodeToQuicklyAccessYourVaultAndAutofillYourLogins,
@ -69,7 +70,7 @@ class IllustratedMessageViewTests: BitwardenTestCase {
/// Test snapshots of the smallImage style.
func disabletest_snapshot_smallImage() {
let subject = IllustratedMessageView(
image: Asset.Images.Illustrations.biometricsPhone,
image: SharedAsset.Icons.unlocked24,
style: .smallImage,
title: Localizations.setUpUnlock,
message: Localizations.setUpBiometricsOrChooseAPinCodeToQuicklyAccessYourVaultAndAutofillYourLogins,

View File

@ -4,7 +4,7 @@ import SwiftUI
import ViewInspector
import XCTest
@testable import BitwardenShared
@testable import BitwardenKit
class IllustratedMessageViewTests: BitwardenTestCase {
// MARK: Tests
@ -14,7 +14,7 @@ class IllustratedMessageViewTests: BitwardenTestCase {
func test_button_tap() throws {
var tapped = false
let subject = IllustratedMessageView(
image: Asset.Images.Illustrations.biometricsPhone,
image: SharedAsset.Icons.unlocked24,
style: .mediumImage,
title: Localizations.setUpUnlock,
message: Localizations.setUpBiometricsOrChooseAPinCodeToQuicklyAccessYourVaultAndAutofillYourLogins,

View File

@ -1,4 +1,3 @@
import BitwardenKit
import BitwardenResources
import SwiftUI
@ -7,7 +6,7 @@ import SwiftUI
/// A view that renders a message view with an image on top. This support displaying a square image,
/// title, and message.
///
struct IllustratedMessageView<Accessory: View>: View {
public struct IllustratedMessageView<Accessory: View>: View {
// MARK: Properties
/// An optional accessory to display after the message, such as a button.
@ -30,7 +29,7 @@ struct IllustratedMessageView<Accessory: View>: View {
// MARK: View
var body: some View {
public var body: some View {
dynamicStackView {
image
.resizable()
@ -73,7 +72,7 @@ struct IllustratedMessageView<Accessory: View>: View {
/// - message: The message to display.
/// - accessory: An optional accessory view to display.
///
init(
public init(
image: Image,
style: IllustratedMessageStyle = .smallImage,
title: String? = nil,
@ -96,30 +95,7 @@ struct IllustratedMessageView<Accessory: View>: View {
/// - message: The message to display.
/// - accessory: An optional accessory view to display.
///
init(
image: ImageAsset,
style: IllustratedMessageStyle = .smallImage,
title: String? = nil,
message: String,
@ViewBuilder accessory: () -> Accessory,
) {
self.accessory = accessory()
self.image = image.swiftUIImage
self.message = message
self.style = style
self.title = title
}
/// Initialize a `IllustratedMessageView`.
///
/// - Parameters:
/// - image: The image asset to display.
/// - style: The style of the message view.
/// - title: The title to display.
/// - message: The message to display.
/// - accessory: An optional accessory view to display.
///
init(
public init(
image: SharedImageAsset,
style: IllustratedMessageStyle = .smallImage,
title: String? = nil,
@ -148,7 +124,7 @@ struct IllustratedMessageView<Accessory: View>: View {
}
}
extension IllustratedMessageView where Accessory == EmptyView {
public extension IllustratedMessageView where Accessory == EmptyView {
/// Initialize a `IllustratedMessageView`.
///
/// - Parameters:
@ -170,27 +146,6 @@ extension IllustratedMessageView where Accessory == EmptyView {
self.title = title
}
/// Initialize a `IllustratedMessageView`.
///
/// - Parameters:
/// - image: The image asset to display.
/// - style: The style of the message view.
/// - title: The title to display.
/// - message: The message to display.
///
init(
image: ImageAsset,
style: IllustratedMessageStyle = .smallImage,
title: String? = nil,
message: String,
) {
accessory = nil
self.image = image.swiftUIImage
self.message = message
self.style = style
self.title = title
}
/// Initialize a `IllustratedMessageView`.
///
/// - Parameters:
@ -218,7 +173,7 @@ extension IllustratedMessageView where Accessory == EmptyView {
#if DEBUG
#Preview("SmallImage") {
IllustratedMessageView(
image: Asset.Images.Illustrations.biometricsPhone,
image: SharedAsset.Icons.plus24,
style: .smallImage,
title: Localizations.setUpUnlock,
message: Localizations.setUpBiometricsOrChooseAPinCodeToQuicklyAccessYourVaultAndAutofillYourLogins,
@ -227,7 +182,7 @@ extension IllustratedMessageView where Accessory == EmptyView {
#Preview("MediumImage") {
IllustratedMessageView(
image: Asset.Images.Illustrations.biometricsPhone,
image: SharedAsset.Icons.plus24,
style: .mediumImage,
title: Localizations.setUpUnlock,
message: Localizations.setUpBiometricsOrChooseAPinCodeToQuicklyAccessYourVaultAndAutofillYourLogins,
@ -236,7 +191,7 @@ extension IllustratedMessageView where Accessory == EmptyView {
#Preview("MediumImage With Button") {
IllustratedMessageView(
image: Asset.Images.Illustrations.biometricsPhone,
image: SharedAsset.Icons.plus24,
style: .mediumImage,
title: Localizations.setUpUnlock,
message: Localizations.setUpBiometricsOrChooseAPinCodeToQuicklyAccessYourVaultAndAutofillYourLogins,
@ -263,7 +218,7 @@ extension IllustratedMessageView where Accessory == EmptyView {
/// A `IllustratedMessageStyle` contains the metrics for rendering a `IllustratedMessageView`.
///
struct IllustratedMessageStyle: Sendable {
public struct IllustratedMessageStyle: Sendable {
// MARK: Properties
/// A foreground tint to apply to the image. Only applied if this has a value.
@ -317,7 +272,8 @@ private extension IllustratedMessageStyle {
// MARK: - IllustratedMessageStyle Constants
extension IllustratedMessageStyle {
public extension IllustratedMessageStyle {
/// A style with a large title text and a tinted icon image.
static let largeTextTintedIcon = IllustratedMessageStyle(
imageColor: SharedAsset.Colors.iconSecondary.swiftUIColor,
imageSize: OrientationBasedValue(
@ -331,6 +287,7 @@ extension IllustratedMessageStyle {
titleTextStyle: .hugeTitle,
)
/// A style with a medium-sized image.
static let mediumImage = IllustratedMessageStyle(
imageColor: nil,
imageSize: OrientationBasedValue(
@ -346,6 +303,7 @@ extension IllustratedMessageStyle {
titleTextStyle: .title2,
)
/// A style with a small-sized image.
static let smallImage = IllustratedMessageStyle(
imageColor: nil,
imageSize: OrientationBasedValue(

View File

@ -4,7 +4,7 @@ import SwiftUI
/// An `OrientationBasedValue` encapsulates values that might be different
/// for rendering based on orientation, such as image size or space between text.
struct OrientationBasedValue<T: Equatable & Sendable>: Equatable, Sendable {
public struct OrientationBasedValue<T: Equatable & Sendable>: Equatable, Sendable {
// MARK: Properties
/// The dimension size in portrait mode.
@ -20,7 +20,7 @@ struct OrientationBasedValue<T: Equatable & Sendable>: Equatable, Sendable {
/// - portrait: The value in portrait mode.
/// - landscape: The value in landscape mode.
///
init(portrait: T, landscape: T) {
public init(portrait: T, landscape: T) {
self.portrait = portrait
self.landscape = landscape
}
@ -29,7 +29,7 @@ struct OrientationBasedValue<T: Equatable & Sendable>: Equatable, Sendable {
/// - Parameters:
/// - both: The value in both portrait and landscape mode.
///
init(both: T) {
public init(both: T) {
portrait = both
landscape = both
}
@ -38,7 +38,7 @@ struct OrientationBasedValue<T: Equatable & Sendable>: Equatable, Sendable {
/// Convenience function for getting the correct value based on the orientation.
///
func value(_ verticalSizeClass: UserInterfaceSizeClass) -> T {
public func value(_ verticalSizeClass: UserInterfaceSizeClass) -> T {
verticalSizeClass == .regular ? portrait : landscape
}
}

View File

@ -0,0 +1,53 @@
import BitwardenKit
import SwiftUI
extension IllustratedMessageView {
/// Initialize a `IllustratedMessageView`.
///
/// - Parameters:
/// - image: The image asset to display.
/// - style: The style of the message view.
/// - title: The title to display.
/// - message: The message to display.
/// - accessory: An optional accessory view to display.
///
init(
image: ImageAsset,
style: IllustratedMessageStyle = .smallImage,
title: String? = nil,
message: String,
@ViewBuilder accessory: () -> Accessory,
) {
self.init(
image: image.swiftUIImage,
style: style,
title: title,
message: message,
accessory: accessory,
)
}
}
extension IllustratedMessageView where Accessory == EmptyView {
/// Initialize a `IllustratedMessageView`.
///
/// - Parameters:
/// - image: The image asset to display.
/// - style: The style of the message view.
/// - title: The title to display.
/// - message: The message to display.
///
init(
image: ImageAsset,
style: IllustratedMessageStyle = .smallImage,
title: String? = nil,
message: String,
) {
self.init(
image: image.swiftUIImage,
style: style,
title: title,
message: message,
)
}
}

View File

@ -26,6 +26,13 @@
"testTimeoutsEnabled" : true
},
"testTargets" : [
{
"target" : {
"containerPath" : "container:BitwardenKit.xcodeproj",
"identifier" : "11D20029373CEF56CBBCF0AA",
"name" : "AuthenticatorBridgeKitTests"
}
},
{
"target" : {
"containerPath" : "container:Authenticator.xcodeproj",

View File

@ -29,6 +29,13 @@
"testTimeoutsEnabled" : true
},
"testTargets" : [
{
"target" : {
"containerPath" : "container:BitwardenKit.xcodeproj",
"identifier" : "11D20029373CEF56CBBCF0AA",
"name" : "AuthenticatorBridgeKitTests"
}
},
{
"target" : {
"containerPath" : "container:Authenticator.xcodeproj",

View File

@ -54,6 +54,20 @@
"name" : "BitwardenKitTests"
}
},
{
"target" : {
"containerPath" : "container:BitwardenKit.xcodeproj",
"identifier" : "0F0F8167EDD3A9370CA429CE",
"name" : "BitwardenKitSnapshotTests"
}
},
{
"target" : {
"containerPath" : "container:BitwardenKit.xcodeproj",
"identifier" : "27C53FBF98252CF56973FD34",
"name" : "BitwardenKitViewInspectorTests"
}
},
{
"target" : {
"containerPath" : "container:Bitwarden.xcodeproj",