Skip to content

Commit

Permalink
[Link] PayWithLinkButton corner radius fixes (#1438)
Browse files Browse the repository at this point in the history
* Make Link button match corner radius behavior of PKPaymentButton

* Cleanup

* Fix typo

* Add test

* Rename test

* Cleanup

* Cleanup

* Add test

* Cleanup

* Make corners continuous when possible
  • Loading branch information
ramont-stripe authored Sep 16, 2022
1 parent fcf45a0 commit 23a6ba8
Show file tree
Hide file tree
Showing 21 changed files with 91 additions and 12 deletions.
57 changes: 49 additions & 8 deletions Stripe/PayWithLinkButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import UIKit
final class PayWithLinkButton: UIControl {

struct Constants {
static let defaultSize: CGSize = .init(width: 200, height: 44)
static let logoSize: CGSize = .init(width: 35, height: 16)
static let margins: NSDirectionalEdgeInsets = .init(top: 7, leading: 16, bottom: 7, trailing: 10)
static let emailContainerCornerRadius: CGFloat = 3
static let emailContainerMinimumCornerRadius: CGFloat = 3
static let emailContainerInsets: NSDirectionalEdgeInsets = .insets(amount: 6)
}

Expand All @@ -32,7 +33,7 @@ final class PayWithLinkButton: UIControl {

var cornerRadius: CGFloat = ElementsUI.defaultCornerRadius {
didSet {
applyStyle()
setNeedsLayout()
}
}

Expand All @@ -49,7 +50,7 @@ final class PayWithLinkButton: UIControl {
}

override var intrinsicContentSize: CGSize {
return CGSize(width: UIView.noIntrinsicMetric, height: 44)
return CGSize(width: UIView.noIntrinsicMetric, height: Constants.defaultSize.height)
}

private let titleBaseFont: UIFont = UIFont.systemFont(ofSize: 16, weight: .medium)
Expand Down Expand Up @@ -88,8 +89,7 @@ final class PayWithLinkButton: UIControl {

private lazy var emailLabelContainer: UIView = {
let container = UIView()
container.layer.cornerRadius = Constants.emailContainerCornerRadius
container.translatesAutoresizingMaskIntoConstraints = false
container.layer.cornerRadius = Constants.emailContainerMinimumCornerRadius
container.addSubview(emailLabel)
container.addAndPinSubview(emailLabel, insets: Constants.emailContainerInsets)
return container
Expand All @@ -100,7 +100,7 @@ final class PayWithLinkButton: UIControl {
}

init() {
super.init(frame: .zero)
super.init(frame: CGRect(origin: .zero, size: Constants.defaultSize))
isAccessibilityElement = true
setupUI()
applyStyle()
Expand All @@ -119,6 +119,11 @@ final class PayWithLinkButton: UIControl {
LinkAccountContext.shared.removeObserver(self)
}

override func layoutSubviews() {
super.layoutSubviews()
applyCornerRadius()
}

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
bounds.contains(point) ? self : nil
}
Expand Down Expand Up @@ -179,19 +184,55 @@ private extension PayWithLinkButton {

private extension PayWithLinkButton {

func applyStyle() {
layer.cornerRadius = cornerRadius
var effectiveCornerRadius: CGFloat {
// Matches the formula used by `PKPaymentButton` for calculating
// the effective corner radius. The effective corner radius is snapped
// to half the button's height if the corner radius is
// greater or equals than approx. 1/3 of the height (`threshold`).
let threshold = 0.32214

return cornerRadius >= bounds.height * threshold
? bounds.height / 2
: cornerRadius
}

var effectiveEmailContainerRadius: CGFloat {
guard cornerRadius >= 1 else {
// No round the container corners if `cornerRadius` is less than 1.
return 0.0
}

// Return a concentric radius (relative to `effectiveCornerRadius`) not
// smaller than `Constants.emailContainerMinimumCornerRadius`.
return max(
Constants.emailContainerMinimumCornerRadius,
effectiveCornerRadius - Constants.margins.top
)
}

func applyStyle() {
// Foreground
let foregroundColor = self.foregroundColor(for: state)
titleLabel.textColor = foregroundColor
logoView.tintColor = foregroundColor
stackView.tintColor = foregroundColor
emailLabel.textColor = foregroundColor
emailLabelContainer.backgroundColor = foregroundColor.withAlphaComponent(0.04)

// Background
backgroundColor = backgroundColor(for: state)
}

func applyCornerRadius() {
if #available(iOS 13.0, *) {
layer.cornerCurve = .continuous
emailLabelContainer.layer.cornerCurve = .continuous
}

layer.cornerRadius = effectiveCornerRadius
emailLabelContainer.layer.cornerRadius = effectiveEmailContainerRadius
}

func foregroundColor(for state: State) -> UIColor {
switch state {
case .highlighted:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ...ntSheetUITest.PaymentSheetSnapshotTests/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ...etUITest.PaymentSheetSnapshotTests/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ...ipeiOS_Tests.WalletHeaderViewSnapshotTests/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ..._Tests.WalletHeaderViewSnapshotTests/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 29 additions & 4 deletions Tests/Tests/PayWithLinkButtonSnapshotTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,30 @@ import StripeCoreTestUtils

class PayWithLinkButtonSnapshotTests: FBSnapshotTestCase {

private let emailAddress = "[email protected]"
private let longEmailAddress = "[email protected]"

override func setUp() {
super.setUp()
// recordMode = true
}

func testDefault() {
let sut = makeSUT()
sut.linkAccount = makeAccountStub(email: "[email protected]", isRegistered: false)
sut.linkAccount = makeAccountStub(email: emailAddress, isRegistered: false)
verify(sut)

sut.isHighlighted = true
verify(sut, identifier: "Highlighted")
}

func testDefault_rounded() {
let sut = makeSUT()
sut.cornerRadius = 16
sut.linkAccount = makeAccountStub(email: emailAddress, isRegistered: false)
verify(sut)
}

func testDisabled() {
let sut = makeSUT()
sut.isEnabled = false
Expand All @@ -36,13 +46,27 @@ class PayWithLinkButtonSnapshotTests: FBSnapshotTestCase {

func testRegistered() {
let sut = makeSUT()
sut.linkAccount = makeAccountStub(email: "[email protected]", isRegistered: true)
sut.linkAccount = makeAccountStub(email: emailAddress, isRegistered: true)
verify(sut)
}

func testRegistered_rounded() {
let sut = makeSUT()
sut.cornerRadius = 16
sut.linkAccount = makeAccountStub(email: emailAddress, isRegistered: true)
verify(sut)
}

func testRegisteredWithLongEmailAddress() {
func testRegistered_square() {
let sut = makeSUT()
sut.cornerRadius = 0
sut.linkAccount = makeAccountStub(email: emailAddress, isRegistered: true)
verify(sut)
}

func testRegistered_withLongEmailAddress() {
let sut = PayWithLinkButton()
sut.linkAccount = makeAccountStub(email: "[email protected]", isRegistered: true)
sut.linkAccount = makeAccountStub(email: longEmailAddress, isRegistered: true)
verify(sut)
}

Expand Down Expand Up @@ -79,4 +103,5 @@ private extension PayWithLinkButtonSnapshotTests {
func makeSUT() -> PayWithLinkButton {
return PayWithLinkButton()
}

}
13 changes: 13 additions & 0 deletions Tests/Tests/WalletHeaderViewSnapshotTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,19 @@ class WalletHeaderViewSnapshotTests: FBSnapshotTestCase {
verify(headerView)
}

func testCustomCornerRadius() {
var appearance = PaymentSheet.Appearance.default
appearance.cornerRadius = 14.5

let headerView = PaymentSheetViewController.WalletHeaderView(
options: [.applePay, .link],
appearance: appearance,
delegate: nil
)

verify(headerView)
}

func verify(
_ view: UIView,
identifier: String? = nil,
Expand Down

0 comments on commit 23a6ba8

Please sign in to comment.