Skip to content

Commit

Permalink
🎨 Introduce PaymentSheet.Appearance and refactor primary and backgrou…
Browse files Browse the repository at this point in the history
…nd color (#800)

* Add PaymentSheetAppearance

* Migrate background color to PaymentSheetAppearance

* Try to fix namespace

* Add TODO

* Refactor primary color

* Fix checkbox stroke color

* Add comment

* Fix tests

* Default checkbox stroke to black

* Update Stripe/PaymentSheetAppearance.swift

Co-authored-by: Yuki <[email protected]>

* Group appearance APIs, remove didSet as well

* Make checkbox black stroke

* Revert change on primaryButtonColor

* Add TOOD comment

* Re-record tests

* Update check circle background to match appearance primary

* 🎨  Text, secondary text, icon, danger, border, componentBackground colors (#821)

* Refactor text color

* primary and secondary text color refactor

* refactor for icon color

* dangerColor, componentBorderColor, componentBackgroundColor

* Audit changes thus far

* Refactor for componentDividerColor

* Refactor corner radius

* Border width refactor

* Set corner radius on link button

* Refactor for shadows

* Revert "Refactor for componentDividerColor"

This reverts commit 028ebfc60934ac58ae4b57251c7f0cb9a86de6da.

* Revert form element changes

* Revert sepa mandate change, update checkbox stroke

* Little bit more clean up

* Fix build issue

* Fill checkbox with componentBackground

* Set border on checkbox

* Set checkbox label color

* Fix shadow corner radius

* Fix build issue

* Update snapshots

* update checkbox snapshot tests

* comment out record

* Don't modify link appearance

* update link snapshot tests

* update snapshots

* PR feedback

* Make link checkbox blue

* update new snapshot tests :/

* Update snapshots from latest

* Fix test

* Record dark mode tests

Co-authored-by: Yuki <[email protected]>
  • Loading branch information
porter-stripe and yuki-stripe authored Mar 9, 2022
1 parent aed6174 commit a005391
Show file tree
Hide file tree
Showing 53 changed files with 339 additions and 177 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ class PaymentSheetUITest: XCTestCase {
XCTAssertTrue(webviewCloseButton.waitForExistence(timeout: 10.0))
webviewCloseButton.tap()
}

func testAffirmPaymentMethod() throws {
app.staticTexts["PaymentSheet (test playground)"].tap()
app.buttons["new"].tap() // new customer
Expand All @@ -336,6 +337,7 @@ class PaymentSheetUITest: XCTestCase {
reload()
app.buttons["Checkout (Complete)"].tap()
let payButton = app.buttons["Pay $50.99"]


// Select affirm
guard let affirm = scroll(collectionView: app.collectionViews.firstMatch, toFindCellWithId: "Affirm") else {
Expand Down
8 changes: 8 additions & 0 deletions Stripe.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@
618E787B26EFDD310034A01F /* ServerErrorMapperTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618E787A26EFDD310034A01F /* ServerErrorMapperTest.swift */; };
61924D46273999E1003CF2DB /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 61924D44273999E0003CF2DB /* [email protected] */; };
61924D47273999E1003CF2DB /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 61924D45273999E1003CF2DB /* [email protected] */; };
61A0935227CDB8DC00AA4520 /* CALayer+PaymentSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A0935127CDB8DC00AA4520 /* CALayer+PaymentSheet.swift */; };
61A3785F2720960700B949C5 /* STPPaymentMethodKlarnaParamsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A3785E2720960700B949C5 /* STPPaymentMethodKlarnaParamsTests.swift */; };
61A378612721C48000B949C5 /* STPPaymentMethodKlarnaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A378602721C48000B949C5 /* STPPaymentMethodKlarnaTests.swift */; };
61A9D1A027B177E100B7B5A8 /* Data+SHA256.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A9D19F27B177E100B7B5A8 /* Data+SHA256.swift */; };
Expand All @@ -494,6 +495,7 @@
61DBE71E27308195008565C8 /* KlarnaHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61DBE71D27308195008565C8 /* KlarnaHelper.swift */; };
61DBE720273082EC008565C8 /* KlarnaHelperTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61DBE71F273082EC008565C8 /* KlarnaHelperTest.swift */; };
61EA8CEE26DD84DF00B2879D /* Error+PaymentSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61EA8CED26DD84DF00B2879D /* Error+PaymentSheet.swift */; };
61EC9FD327C5763200048318 /* PaymentSheetAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61EC9FD227C5763200048318 /* PaymentSheetAppearance.swift */; };
69A6C30A246EA195005FF304 /* STPPaymentMethodEPSParamsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 69A6C309246EA195005FF304 /* STPPaymentMethodEPSParamsTests.m */; };
6B48784F27BC7E0900B7632D /* STPPaymentMethodAffirm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B48784E27BC7E0900B7632D /* STPPaymentMethodAffirm.swift */; };
6B48785127BC8A3900B7632D /* STPPaymentMethodAffirmParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B48785027BC8A3900B7632D /* STPPaymentMethodAffirmParams.swift */; };
Expand Down Expand Up @@ -1463,6 +1465,7 @@
618E787A26EFDD310034A01F /* ServerErrorMapperTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerErrorMapperTest.swift; sourceTree = "<group>"; };
61924D44273999E0003CF2DB /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
61924D45273999E1003CF2DB /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
61A0935127CDB8DC00AA4520 /* CALayer+PaymentSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+PaymentSheet.swift"; sourceTree = "<group>"; };
61A3785E2720960700B949C5 /* STPPaymentMethodKlarnaParamsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = STPPaymentMethodKlarnaParamsTests.swift; sourceTree = "<group>"; };
61A378602721C48000B949C5 /* STPPaymentMethodKlarnaTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = STPPaymentMethodKlarnaTests.swift; sourceTree = "<group>"; };
61A9D19F27B177E100B7B5A8 /* Data+SHA256.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+SHA256.swift"; sourceTree = "<group>"; };
Expand All @@ -1474,6 +1477,7 @@
61DBE71D27308195008565C8 /* KlarnaHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KlarnaHelper.swift; sourceTree = "<group>"; };
61DBE71F273082EC008565C8 /* KlarnaHelperTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KlarnaHelperTest.swift; sourceTree = "<group>"; };
61EA8CED26DD84DF00B2879D /* Error+PaymentSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+PaymentSheet.swift"; sourceTree = "<group>"; };
61EC9FD227C5763200048318 /* PaymentSheetAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentSheetAppearance.swift; sourceTree = "<group>"; };
69A6C309246EA195005FF304 /* STPPaymentMethodEPSParamsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodEPSParamsTests.m; sourceTree = "<group>"; };
6B48784E27BC7E0900B7632D /* STPPaymentMethodAffirm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = STPPaymentMethodAffirm.swift; sourceTree = "<group>"; };
6B48785027BC8A3900B7632D /* STPPaymentMethodAffirmParams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = STPPaymentMethodAffirmParams.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2809,6 +2813,7 @@
isa = PBXGroup;
children = (
61EA8CED26DD84DF00B2879D /* Error+PaymentSheet.swift */,
61A0935127CDB8DC00AA4520 /* CALayer+PaymentSheet.swift */,
B6BB89CF266EF7F8005E044F /* Intent.swift */,
B6689185265324C600A5488F /* New Payment Method Screen */,
B6E40E8C254253E400A5BABD /* PanModal */,
Expand All @@ -2818,6 +2823,7 @@
B68A9E602582A82500E904B5 /* PaymentSheet+API.swift */,
31319EE025B11C8A00C89E30 /* PaymentSheet+SwiftUI.swift */,
B68A9E662582B88400E904B5 /* PaymentSheetConfiguration.swift */,
61EC9FD227C5763200048318 /* PaymentSheetAppearance.swift */,
B68A9E39257EE77000E904B5 /* PaymentSheetError.swift */,
B684476A25538874005C4089 /* PaymentSheetFlowController.swift */,
B6689186265324D500A5488F /* Saved Payment Method Screen */,
Expand Down Expand Up @@ -4131,6 +4137,7 @@
B6E40EA9254253E400A5BABD /* PanModalPresentationAnimator.swift in Sources */,
36AC3D2C252521D700F252D7 /* STPPaymentIntentParams.swift in Sources */,
B67243212524E514002E1AAF /* STPPaymentMethodSEPADebit.swift in Sources */,
61EC9FD327C5763200048318 /* PaymentSheetAppearance.swift in Sources */,
317ABF462511983100CC59EF /* STPColorUtils.swift in Sources */,
31B49EA826E9743D00A0464A /* StripeCore+Import.swift in Sources */,
B6E6C0E92655705100445507 /* Images.swift in Sources */,
Expand Down Expand Up @@ -4416,6 +4423,7 @@
B6D9CEBC2515243900AAD424 /* STPPaymentMethodCardChecks.swift in Sources */,
363B926027431C4800BA52EC /* Enums+CustomStringConvertible.swift in Sources */,
3111C32F2526BE8600207E32 /* NSDecimalNumber+Stripe_Currency.swift in Sources */,
61A0935227CDB8DC00AA4520 /* CALayer+PaymentSheet.swift in Sources */,
31D49B23251D75BA003FDB84 /* STPToken.swift in Sources */,
B63A414425F9759900929729 /* STPPaymentMethodBLIKParams.swift in Sources */,
B66F0CA426717B8C0097C2E8 /* PaymentSheetFormFactory.swift in Sources */,
Expand Down
3 changes: 2 additions & 1 deletion Stripe/AddPaymentMethodViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class AddPaymentMethodViewController: UIViewController {
}()
private lazy var paymentMethodTypesView: PaymentMethodTypeCollectionView = {
let view = PaymentMethodTypeCollectionView(
paymentMethodTypes: paymentMethodTypes, delegate: self)
paymentMethodTypes: paymentMethodTypes, appearance: configuration.appearance, delegate: self)
return view
}()
private lazy var paymentMethodDetailsContainerView: DynamicHeightContainerView = {
Expand Down Expand Up @@ -102,6 +102,7 @@ class AddPaymentMethodViewController: UIViewController {
self.delegate = delegate
self.linkAccount = linkAccount
super.init(nibName: nil, bundle: nil)
self.view.backgroundColor = configuration.appearance.color.background
}

// MARK: - UIViewController
Expand Down
9 changes: 6 additions & 3 deletions Stripe/BottomSheet3DS2ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class BottomSheet3DS2ViewController: UIViewController {
weak var delegate: BottomSheet3DS2ViewControllerDelegate? = nil

lazy var navigationBar: SheetNavigationBar = {
let navBar = SheetNavigationBar(isTestMode: isTestMode)
let navBar = SheetNavigationBar(isTestMode: isTestMode,
appearance: appearance)
navBar.setStyle(.back)
navBar.delegate = self
return navBar
Expand All @@ -32,10 +33,12 @@ class BottomSheet3DS2ViewController: UIViewController {
}

let challengeViewController: UIViewController
let appearance: PaymentSheet.Appearance
let isTestMode: Bool

required init(challengeViewController: UIViewController, isTestMode: Bool) {
required init(challengeViewController: UIViewController, appearance: PaymentSheet.Appearance, isTestMode: Bool) {
self.challengeViewController = challengeViewController
self.appearance = appearance
self.isTestMode = isTestMode
super.init(nibName: nil, bundle: nil)
}
Expand All @@ -49,7 +52,7 @@ class BottomSheet3DS2ViewController: UIViewController {
view.backgroundColor = CompatibleColor.systemBackground
addChild(challengeViewController)

let headerLabel = PaymentSheetUI.makeHeaderLabel()
let headerLabel = PaymentSheetUI.makeHeaderLabel(appearance: appearance)
headerLabel.text =
STPThreeDSNavigationBarCustomization.defaultSettings().navigationBarCustomization
.headerText
Expand Down
7 changes: 5 additions & 2 deletions Stripe/BottomSheetViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class BottomSheetViewController: UIViewController, PanModalPresentable {
}

let isTestMode: Bool
let appearance: PaymentSheet.Appearance

private var contentViewController: BottomSheetContentViewController {
didSet(oldContentViewController) {
Expand Down Expand Up @@ -89,8 +90,9 @@ class BottomSheetViewController: UIViewController, PanModalPresentable {

var linkPaymentDetails: (PaymentSheetLinkAccount, ConsumerPaymentDetails)? = nil

required init(contentViewController: BottomSheetContentViewController, isTestMode: Bool) {
required init(contentViewController: BottomSheetContentViewController, appearance: PaymentSheet.Appearance, isTestMode: Bool) {
self.contentViewController = contentViewController
self.appearance = appearance
self.isTestMode = isTestMode

super.init(nibName: nil, bundle: nil)
Expand All @@ -101,6 +103,7 @@ class BottomSheetViewController: UIViewController, PanModalPresentable {
contentViewController.didMove(toParent: self)
contentContainerView.addArrangedSubview(contentViewController.view)
navigationBarContainerView.addArrangedSubview(contentViewController.navigationBar)
self.view.backgroundColor = appearance.color.background
}

required init?(coder: NSCoder) {
Expand Down Expand Up @@ -252,7 +255,7 @@ extension BottomSheetViewController: PaymentSheetAuthenticationContext {
_ threeDS2ChallengeViewController: UIViewController, completion: @escaping () -> Void
) {
let threeDS2ViewController = BottomSheet3DS2ViewController(
challengeViewController: threeDS2ChallengeViewController, isTestMode: isTestMode)
challengeViewController: threeDS2ChallengeViewController, appearance: appearance, isTestMode: isTestMode)
threeDS2ViewController.delegate = self
pushContentViewController(threeDS2ViewController)
completion()
Expand Down
33 changes: 33 additions & 0 deletions Stripe/CALayer+PaymentSheet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// CALayer+PaymentSheet.swift
// StripeiOS
//
// Created by Nick Porter on 2/28/22.
// Copyright © 2022 Stripe, Inc. All rights reserved.
//

import Foundation
import QuartzCore
import UIKit

extension CALayer {

func applyShadowAppearance(shape: PaymentSheet.Appearance.Shape) {
shadowColor = shape.componentShadow.color.cgColor
shadowOpacity = shape.componentShadow.alpha
shadowOffset = shape.componentShadow.offset
shadowRadius = CGFloat(shape.componentShadow.radius)

if shape.componentShadow.spread == 0 {
shadowPath = nil
} else {
let dx = CGFloat(-shape.componentShadow.spread)
let rect = bounds.insetBy(dx: dx, dy: dx)
shadowPath = UIBezierPath(
roundedRect: rect,
cornerRadius: shape.cornerRadius
).cgPath
}
}

}
5 changes: 4 additions & 1 deletion Stripe/CardDetailsEditView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class CardDetailsEditView: UIView, STP_Internal_CardScanningViewDelegate {
let includeCardScanning: Bool
let prefillDetails: STPCardFormView.PrefillDetails?
let inputMode: STPCardNumberInputTextField.InputMode
let appearance: PaymentSheet.Appearance
private(set) var hasCompleteDetails: Bool = false

var paymentMethodParams: STPPaymentMethodParams? {
Expand Down Expand Up @@ -56,7 +57,8 @@ class CardDetailsEditView: UIView, STP_Internal_CardScanningViewDelegate {

lazy var checkboxView: CheckboxButton = {
let saveThisCardCheckbox = CheckboxButton(
text: checkboxText ?? ""
text: checkboxText ?? "",
appearance: appearance
)
saveThisCardCheckbox.isSelected = false
return saveThisCardCheckbox
Expand Down Expand Up @@ -127,6 +129,7 @@ class CardDetailsEditView: UIView, STP_Internal_CardScanningViewDelegate {
self.includeCardScanning = includeCardScanning
self.inputMode = inputMode
self.prefillDetails = prefillDetails
self.appearance = configuration.appearance

super.init(frame: .zero)

Expand Down
1 change: 1 addition & 0 deletions Stripe/CardScanningView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class CardScanningView: UIView, STPCardScannerDelegate {
}()

private lazy var closeButton: CircularButton = {
// TODO(porter): Customize card scanning view?
let button = CircularButton(style: .close)
button.accessibilityLabel = STPLocalizedString(
"Close card scanner", "Accessibility label for the button to close the card scanner.")
Expand Down
33 changes: 24 additions & 9 deletions Stripe/CheckboxButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class CheckboxButton: UIControl {
}()

private lazy var checkbox: CheckBox = {
let checkbox = CheckBox()
let checkbox = CheckBox(appearance: appearance)
checkbox.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
checkbox.setContentHuggingPriority(.defaultHigh, for: .horizontal)
checkbox.backgroundColor = .clear
Expand Down Expand Up @@ -103,10 +103,13 @@ class CheckboxButton: UIControl {
setNeedsDisplay()
}
}

let appearance: PaymentSheet.Appearance

// MARK: - Initializers

init(text: String, description: String? = nil) {
init(text: String, description: String? = nil, appearance: PaymentSheet.Appearance = PaymentSheet.Appearance()) {
self.appearance = appearance
super.init(frame: .zero)

isAccessibilityElement = true
Expand All @@ -116,6 +119,7 @@ class CheckboxButton: UIControl {

label.text = text
descriptionLabel.text = description
layer.applyShadowAppearance(shape: appearance.shape)

setupUI()

Expand Down Expand Up @@ -173,11 +177,11 @@ class CheckboxButton: UIControl {
let hasDescription = descriptionLabel.text != nil

label.font = hasDescription ? emphasisFont : font
label.textColor = hasDescription ? CompatibleColor.label : CompatibleColor.secondaryLabel
label.textColor = hasDescription ? appearance.color.text : appearance.color.textSecondary

descriptionLabel.font = font
descriptionLabel.isHidden = !hasDescription
descriptionLabel.textColor = CompatibleColor.secondaryLabel
descriptionLabel.textColor = appearance.color.textSecondary

// Align checkbox to center of first line of text. The center of the checkbox is already
// pinned to the first baseline via a constraint, so we just need to calculate
Expand All @@ -196,7 +200,18 @@ class CheckBox: UIView {
setNeedsDisplay()
}
}


let appearance: PaymentSheet.Appearance

init(appearance: PaymentSheet.Appearance) {
self.appearance = appearance
super.init(frame: .zero)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func draw(_ rect: CGRect) {
let rect = rect.inset(by: superview!.alignmentRectInsets)
let borderRectWidth = min(16, rect.width - 2)
Expand All @@ -209,12 +224,12 @@ class CheckBox: UIView {
let borderPath = UIBezierPath(roundedRect: borderRect, cornerRadius: 3)
borderPath.lineWidth = 1
if isUserInteractionEnabled {
InputFormColors.backgroundColor.setFill()
appearance.color.componentBackground.setFill()
} else {
InputFormColors.disabledBackgroundColor.setFill()
InputFormColors.disabledBackgroundColor.setFill() // TODO(porter): Figure out disable state colors
}
borderPath.fill()
InputFormColors.outlineColor.setStroke()
appearance.color.componentBorder.setStroke()
borderPath.stroke()

if isSelected {
Expand All @@ -227,7 +242,7 @@ class CheckBox: UIView {
checkmarkPath.lineJoinStyle = .round
checkmarkPath.lineWidth = 2
if isUserInteractionEnabled {
InputFormColors.textColor.setStroke()
appearance.color.primary.setStroke()
} else {
InputFormColors.disabledTextColor.setStroke()
}
Expand Down
Loading

0 comments on commit a005391

Please sign in to comment.