diff --git a/Sources/Shared/Views/CapsuleButton.swift b/Sources/Shared/Views/CapsuleButton.swift index e3dfc57373b2b7562c4a1297ab78d8d543327605..348922df7277f36839f9bb83d31731ff76d364ed 100644 --- a/Sources/Shared/Views/CapsuleButton.swift +++ b/Sources/Shared/Views/CapsuleButton.swift @@ -1,11 +1,13 @@ -import UIKit import AppResources +import Combine +import SwiftUI +import UIKit public struct CapsuleButtonModel { public var title: String public var accessibility: String? public var style: CapsuleButtonStyle - + public init( title: String, style: CapsuleButtonStyle, @@ -33,7 +35,7 @@ public extension CapsuleButtonStyle { titleColor: Asset.brandPrimary.color, disabledTitleColor: Asset.neutralWhite.color.withAlphaComponent(0.5) ) - + static let brandColored = CapsuleButtonStyle( fill: .color(Asset.brandPrimary.color), borderWidth: 0, @@ -41,7 +43,7 @@ public extension CapsuleButtonStyle { titleColor: Asset.neutralWhite.color, disabledTitleColor: Asset.neutralWhite.color ) - + static let red = CapsuleButtonStyle( fill: .color(Asset.accentDanger.color), borderWidth: 0, @@ -49,7 +51,7 @@ public extension CapsuleButtonStyle { titleColor: Asset.neutralWhite.color, disabledTitleColor: Asset.neutralWhite.color ) - + static let seeThroughWhite = CapsuleButtonStyle( fill: .color(UIColor.clear), borderWidth: 2, @@ -57,7 +59,7 @@ public extension CapsuleButtonStyle { titleColor: Asset.neutralWhite.color, disabledTitleColor: Asset.neutralWhite.color.withAlphaComponent(0.5) ) - + static let seeThrough = CapsuleButtonStyle( fill: .color(UIColor.clear), borderWidth: 2, @@ -65,7 +67,7 @@ public extension CapsuleButtonStyle { titleColor: Asset.brandPrimary.color, disabledTitleColor: Asset.brandPrimary.color.withAlphaComponent(0.5) ) - + static let simplestColoredRed = CapsuleButtonStyle( fill: .color(UIColor.clear), borderWidth: 0, @@ -73,7 +75,7 @@ public extension CapsuleButtonStyle { titleColor: Asset.accentDanger.color, disabledTitleColor: Asset.brandDefault.color.withAlphaComponent(0.5) ) - + static let simplestColoredBrand = CapsuleButtonStyle( fill: .color(UIColor.clear), borderWidth: 0, @@ -107,9 +109,13 @@ public final class CapsuleButton: UIButton { $0.width.greaterThanOrEqualTo(minimumWidth) } } - + required init?(coder: NSCoder) { nil } + public override var intrinsicContentSize: CGSize { + CGSize(width: minimumWidth, height: height) + } + public func set( style: CapsuleButtonStyle, title: String, @@ -118,25 +124,84 @@ public final class CapsuleButton: UIButton { setTitle(title, for: .normal) accessibilityIdentifier = accessibility layer.borderWidth = style.borderWidth - + if let color = style.borderColor { layer.borderColor = color.cgColor } - + setBackgroundImage(style.fill, for: .normal) setTitleColor(style.titleColor, for: .normal) setTitleColor(style.disabledTitleColor, for: .disabled) } - + public func setStyle(_ style: CapsuleButtonStyle) { layer.borderWidth = style.borderWidth - + if let color = style.borderColor { layer.borderColor = color.cgColor } - + setBackgroundImage(style.fill, for: .normal) setTitleColor(style.titleColor, for: .normal) setTitleColor(style.disabledTitleColor, for: .disabled) } } + +extension CapsuleButton { + public struct SwiftUIView: UIViewRepresentable { + public final class Coordinator { + init(view: CapsuleButton.SwiftUIView) { + self.view = view + } + + var view: CapsuleButton.SwiftUIView + var cancellables = Set<AnyCancellable>() + } + + public init( + height: CGFloat = 55.0, + minimumWidth: CGFloat = 200, + style: CapsuleButtonStyle, + title: String, + accessibility: String? = nil, + action: @escaping () -> Void + ) { + self.height = height + self.minimumWidth = minimumWidth + self.style = style + self.title = title + self.accessibility = accessibility + self.action = action + } + + let height: CGFloat + let minimumWidth: CGFloat + var style: CapsuleButtonStyle + var title: String + var accessibility: String? + var action: () -> Void + + public func makeCoordinator() -> Coordinator { + Coordinator(view: self) + } + + public func makeUIView(context: Context) -> CapsuleButton { + let uiView = CapsuleButton( + height: height, + minimumWidth: minimumWidth + ) + uiView.publisher(for: .touchUpInside) + .sink { context.coordinator.view.action() } + .store(in: &context.coordinator.cancellables) + return uiView + } + + public func updateUIView(_ uiView: CapsuleButton, context: Context) { + uiView.set( + style: style, + title: title, + accessibility: accessibility + ) + } + } +}