From 9f71c1619d8d0b9b530d16036f3e8c0979ca2277 Mon Sep 17 00:00:00 2001 From: Matt Czech Date: Tue, 4 Nov 2025 13:17:13 -0600 Subject: [PATCH] [PM-26063] Move IllustratedMessageView to BitwardenKit (#2096) --- ...IllustratedMessageView+SnapshotTests.swift | 9 +-- ...tratedMessageView+ViewInspectorTests.swift | 4 +- .../Views/IllustratedMessageView.swift | 68 ++++-------------- .../Views/OrientationBasedValue.swift | 8 +-- ...snapshot_largeTextTintedIcon.landscape.png | Bin ..._snapshot_largeTextTintedIcon.portrait.png | Bin .../test_snapshot_mediumImage.landscape.png | Bin .../test_snapshot_mediumImage.portrait.png | Bin ...pshot_mediumImage_withButton.landscape.png | Bin ...apshot_mediumImage_withButton.portrait.png | Bin .../test_snapshot_smallImage.landscape.png | Bin .../test_snapshot_smallImage.portrait.png | Bin .../IllustratedMessageView+Extensions.swift | 53 ++++++++++++++ TestPlans/Authenticator-Default.xctestplan | 7 ++ TestPlans/Authenticator-Unit.xctestplan | 7 ++ TestPlans/Bitwarden-Default.xctestplan | 14 ++++ 16 files changed, 105 insertions(+), 65 deletions(-) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/IllustratedMessageView+SnapshotTests.swift (92%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/IllustratedMessageView+ViewInspectorTests.swift (91%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/IllustratedMessageView.swift (85%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/OrientationBasedValue.swift (83%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.landscape.png (100%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.portrait.png (100%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.landscape.png (100%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.portrait.png (100%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.landscape.png (100%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.portrait.png (100%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.landscape.png (100%) rename {BitwardenShared => BitwardenKit}/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.portrait.png (100%) create mode 100644 BitwardenShared/UI/Platform/Application/Extensions/IllustratedMessageView+Extensions.swift diff --git a/BitwardenShared/UI/Platform/Application/Views/IllustratedMessageView+SnapshotTests.swift b/BitwardenKit/UI/Platform/Application/Views/IllustratedMessageView+SnapshotTests.swift similarity index 92% rename from BitwardenShared/UI/Platform/Application/Views/IllustratedMessageView+SnapshotTests.swift rename to BitwardenKit/UI/Platform/Application/Views/IllustratedMessageView+SnapshotTests.swift index d009685b3..b342ea8f6 100644 --- a/BitwardenShared/UI/Platform/Application/Views/IllustratedMessageView+SnapshotTests.swift +++ b/BitwardenKit/UI/Platform/Application/Views/IllustratedMessageView+SnapshotTests.swift @@ -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, diff --git a/BitwardenShared/UI/Platform/Application/Views/IllustratedMessageView+ViewInspectorTests.swift b/BitwardenKit/UI/Platform/Application/Views/IllustratedMessageView+ViewInspectorTests.swift similarity index 91% rename from BitwardenShared/UI/Platform/Application/Views/IllustratedMessageView+ViewInspectorTests.swift rename to BitwardenKit/UI/Platform/Application/Views/IllustratedMessageView+ViewInspectorTests.swift index 2c1b9e3d2..c2eaf7dcd 100644 --- a/BitwardenShared/UI/Platform/Application/Views/IllustratedMessageView+ViewInspectorTests.swift +++ b/BitwardenKit/UI/Platform/Application/Views/IllustratedMessageView+ViewInspectorTests.swift @@ -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, diff --git a/BitwardenShared/UI/Platform/Application/Views/IllustratedMessageView.swift b/BitwardenKit/UI/Platform/Application/Views/IllustratedMessageView.swift similarity index 85% rename from BitwardenShared/UI/Platform/Application/Views/IllustratedMessageView.swift rename to BitwardenKit/UI/Platform/Application/Views/IllustratedMessageView.swift index 0e78bd03d..c857cfd9c 100644 --- a/BitwardenShared/UI/Platform/Application/Views/IllustratedMessageView.swift +++ b/BitwardenKit/UI/Platform/Application/Views/IllustratedMessageView.swift @@ -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: View { +public struct IllustratedMessageView: View { // MARK: Properties /// An optional accessory to display after the message, such as a button. @@ -30,7 +29,7 @@ struct IllustratedMessageView: View { // MARK: View - var body: some View { + public var body: some View { dynamicStackView { image .resizable() @@ -73,7 +72,7 @@ struct IllustratedMessageView: 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: 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: 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( diff --git a/BitwardenShared/UI/Platform/Application/Views/OrientationBasedValue.swift b/BitwardenKit/UI/Platform/Application/Views/OrientationBasedValue.swift similarity index 83% rename from BitwardenShared/UI/Platform/Application/Views/OrientationBasedValue.swift rename to BitwardenKit/UI/Platform/Application/Views/OrientationBasedValue.swift index a4cdfb887..cf4719c52 100644 --- a/BitwardenShared/UI/Platform/Application/Views/OrientationBasedValue.swift +++ b/BitwardenKit/UI/Platform/Application/Views/OrientationBasedValue.swift @@ -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: Equatable, Sendable { +public struct OrientationBasedValue: Equatable, Sendable { // MARK: Properties /// The dimension size in portrait mode. @@ -20,7 +20,7 @@ struct OrientationBasedValue: 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: 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: 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 } } diff --git a/BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.landscape.png b/BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.landscape.png similarity index 100% rename from BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.landscape.png rename to BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.landscape.png diff --git a/BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.portrait.png b/BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.portrait.png similarity index 100% rename from BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.portrait.png rename to BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_largeTextTintedIcon.portrait.png diff --git a/BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.landscape.png b/BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.landscape.png similarity index 100% rename from BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.landscape.png rename to BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.landscape.png diff --git a/BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.portrait.png b/BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.portrait.png similarity index 100% rename from BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.portrait.png rename to BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage.portrait.png diff --git a/BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.landscape.png b/BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.landscape.png similarity index 100% rename from BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.landscape.png rename to BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.landscape.png diff --git a/BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.portrait.png b/BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.portrait.png similarity index 100% rename from BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.portrait.png rename to BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_mediumImage_withButton.portrait.png diff --git a/BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.landscape.png b/BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.landscape.png similarity index 100% rename from BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.landscape.png rename to BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.landscape.png diff --git a/BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.portrait.png b/BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.portrait.png similarity index 100% rename from BitwardenShared/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.portrait.png rename to BitwardenKit/UI/Platform/Application/Views/__Snapshots__/IllustratedMessageViewTests/test_snapshot_smallImage.portrait.png diff --git a/BitwardenShared/UI/Platform/Application/Extensions/IllustratedMessageView+Extensions.swift b/BitwardenShared/UI/Platform/Application/Extensions/IllustratedMessageView+Extensions.swift new file mode 100644 index 000000000..8ac9ffdb4 --- /dev/null +++ b/BitwardenShared/UI/Platform/Application/Extensions/IllustratedMessageView+Extensions.swift @@ -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, + ) + } +} diff --git a/TestPlans/Authenticator-Default.xctestplan b/TestPlans/Authenticator-Default.xctestplan index ce1cee470..079ced98b 100644 --- a/TestPlans/Authenticator-Default.xctestplan +++ b/TestPlans/Authenticator-Default.xctestplan @@ -26,6 +26,13 @@ "testTimeoutsEnabled" : true }, "testTargets" : [ + { + "target" : { + "containerPath" : "container:BitwardenKit.xcodeproj", + "identifier" : "11D20029373CEF56CBBCF0AA", + "name" : "AuthenticatorBridgeKitTests" + } + }, { "target" : { "containerPath" : "container:Authenticator.xcodeproj", diff --git a/TestPlans/Authenticator-Unit.xctestplan b/TestPlans/Authenticator-Unit.xctestplan index 910fa4f71..813bdef8e 100644 --- a/TestPlans/Authenticator-Unit.xctestplan +++ b/TestPlans/Authenticator-Unit.xctestplan @@ -29,6 +29,13 @@ "testTimeoutsEnabled" : true }, "testTargets" : [ + { + "target" : { + "containerPath" : "container:BitwardenKit.xcodeproj", + "identifier" : "11D20029373CEF56CBBCF0AA", + "name" : "AuthenticatorBridgeKitTests" + } + }, { "target" : { "containerPath" : "container:Authenticator.xcodeproj", diff --git a/TestPlans/Bitwarden-Default.xctestplan b/TestPlans/Bitwarden-Default.xctestplan index 93be62c82..3a1fa410e 100644 --- a/TestPlans/Bitwarden-Default.xctestplan +++ b/TestPlans/Bitwarden-Default.xctestplan @@ -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",