Skip to content

Commit 44350ca

Browse files
Merge pull request #49 from componentskit/refactor/blend-colors
Add method to blend colors
2 parents 6ae288c + bafbdb2 commit 44350ca

File tree

10 files changed

+137
-92
lines changed

10 files changed

+137
-92
lines changed

.swiftlint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ only_rules:
166166
- is_disjoint
167167

168168
# Tuples shouldn’t have too many members. Create a custom type instead
169-
- large_tuple
169+
# - large_tuple
170170

171171
# Prefer using .last(where:) over .filter { }.last in collections
172172
- last_where

Sources/ComponentsKit/Components/Card/SUCard.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ public struct SUCard<Content: View>: View {
4040
self.content()
4141
.padding(self.model.contentPaddings.edgeInsets)
4242
.background(self.model.preferredBackgroundColor.color)
43-
.background(UniversalColor.background.color)
4443
.cornerRadius(self.model.cornerRadius.value)
4544
.overlay(
4645
RoundedRectangle(cornerRadius: self.model.cornerRadius.value)

Sources/ComponentsKit/Components/Card/UKCard.swift

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ open class UKCard: UIView, UKComponent {
2525

2626
/// The primary content of the card, provided as a custom view.
2727
public let content: UIView
28-
/// The container view that holds the card's content.
29-
public let contentView = UIView()
3028

3129
// MARK: - Properties
3230

@@ -65,8 +63,7 @@ open class UKCard: UIView, UKComponent {
6563

6664
/// Sets up the card's subviews.
6765
open func setup() {
68-
self.addSubview(self.contentView)
69-
self.contentView.addSubview(self.content)
66+
self.addSubview(self.content)
7067

7168
if #available(iOS 17.0, *) {
7269
self.registerForTraitChanges([UITraitUserInterfaceStyle.self]) { (view: Self, _: UITraitCollection) in
@@ -80,15 +77,12 @@ open class UKCard: UIView, UKComponent {
8077
/// Applies styling to the card's subviews.
8178
open func style() {
8279
Self.Style.mainView(self, model: self.model)
83-
Self.Style.contentView(self.contentView, model: self.model)
8480
}
8581

8682
// MARK: - Layout
8783

8884
/// Configures the layout.
8985
open func layout() {
90-
self.contentView.allEdges()
91-
9286
self.contentConstraints = LayoutConstraints.merged {
9387
self.content.top(self.model.contentPaddings.top)
9488
self.content.bottom(self.model.contentPaddings.bottom)
@@ -138,16 +132,11 @@ open class UKCard: UIView, UKComponent {
138132
extension UKCard {
139133
fileprivate enum Style {
140134
static func mainView(_ view: UIView, model: Model) {
141-
view.backgroundColor = UniversalColor.background.uiColor
135+
view.backgroundColor = model.preferredBackgroundColor.uiColor
142136
view.layer.cornerRadius = model.cornerRadius.value
143137
view.layer.borderWidth = model.borderWidth.value
144138
view.layer.borderColor = UniversalColor.divider.cgColor
145139
view.shadow(model.shadow)
146140
}
147-
148-
static func contentView(_ view: UIView, model: Model) {
149-
view.backgroundColor = model.preferredBackgroundColor.uiColor
150-
view.layer.cornerRadius = model.cornerRadius.value
151-
}
152141
}
153142
}

Sources/ComponentsKit/Components/Modal/SwiftUI/ModalContent.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ struct ModalContent<VM: ModalVM, Header: View, Body: View, Footer: View>: View {
5959
}
6060
.frame(maxWidth: self.model.size.maxWidth, alignment: .leading)
6161
.background(self.model.preferredBackgroundColor.color)
62-
.background(UniversalColor.background.color)
6362
.clipShape(RoundedRectangle(cornerRadius: self.model.cornerRadius.value))
6463
.overlay(
6564
RoundedRectangle(cornerRadius: self.model.cornerRadius.value)

Sources/ComponentsKit/Components/Modal/SwiftUI/ModalOverlay.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ struct ModalOverlay<VM: ModalVM>: View {
2121
case .blurred:
2222
Color.clear.background(.ultraThinMaterial)
2323
case .transparent:
24-
// Note: It can't be completely transparent as it won't receive touch gestures.
25-
Color.black.opacity(0.0001)
24+
// Note: The tap gesture isn't recognized when a completely transparent
25+
// color is clicked. This can be fixed by calling contentShape, which
26+
// defines the interactive area of the underlying view.
27+
Color.clear.contentShape(.rect)
2628
}
2729
}
2830
.ignoresSafeArea(.all)

Sources/ComponentsKit/Components/Modal/UIKit/UKBottomModalController.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ public class UKBottomModalController: UKModalController<BottomModalVM> {
6666
public override func viewWillAppear(_ animated: Bool) {
6767
super.viewWillAppear(animated)
6868

69-
self.container.transform = .init(translationX: 0, y: self.view.screenBounds.height)
69+
self.contentView.transform = .init(translationX: 0, y: self.view.screenBounds.height)
7070
self.overlay.alpha = 0
7171
}
7272

7373
public override func viewDidAppear(_ animated: Bool) {
7474
super.viewDidAppear(animated)
7575

7676
UIView.animate(withDuration: self.model.transition.value) {
77-
self.container.transform = .identity
77+
self.contentView.transform = .identity
7878
self.overlay.alpha = 1
7979
}
8080
}
@@ -84,7 +84,7 @@ public class UKBottomModalController: UKModalController<BottomModalVM> {
8484
public override func setup() {
8585
super.setup()
8686

87-
self.container.addGestureRecognizer(UIPanGestureRecognizer(
87+
self.contentView.addGestureRecognizer(UIPanGestureRecognizer(
8888
target: self,
8989
action: #selector(self.handleDragGesture)
9090
))
@@ -95,7 +95,7 @@ public class UKBottomModalController: UKModalController<BottomModalVM> {
9595
public override func layout() {
9696
super.layout()
9797

98-
self.container.bottom(self.model.outerPaddings.bottom, safeArea: true)
98+
self.contentView.bottom(self.model.outerPaddings.bottom, safeArea: true)
9999
}
100100

101101
// MARK: - UIViewController Methods
@@ -105,7 +105,7 @@ public class UKBottomModalController: UKModalController<BottomModalVM> {
105105
completion: (() -> Void)? = nil
106106
) {
107107
UIView.animate(withDuration: self.model.transition.value) {
108-
self.container.transform = .init(translationX: 0, y: self.view.screenBounds.height)
108+
self.contentView.transform = .init(translationX: 0, y: self.view.screenBounds.height)
109109
self.overlay.alpha = 0
110110
} completion: { _ in
111111
super.dismiss(animated: false)
@@ -117,25 +117,25 @@ public class UKBottomModalController: UKModalController<BottomModalVM> {
117117

118118
extension UKBottomModalController {
119119
@objc private func handleDragGesture(_ gesture: UIPanGestureRecognizer) {
120-
let translation = gesture.translation(in: self.container).y
121-
let velocity = gesture.velocity(in: self.container).y
120+
let translation = gesture.translation(in: self.contentView).y
121+
let velocity = gesture.velocity(in: self.contentView).y
122122
let offset = ModalAnimation.bottomModalOffset(translation, model: self.model)
123123

124124
switch gesture.state {
125125
case .changed:
126-
self.container.transform = .init(translationX: 0, y: offset)
126+
self.contentView.transform = .init(translationX: 0, y: offset)
127127
case .ended:
128-
let viewHeight = self.container.frame.height
128+
let viewHeight = self.contentView.frame.height
129129
if ModalAnimation.shouldHideBottomModal(offset: offset, height: viewHeight, velocity: velocity, model: self.model) {
130130
self.dismiss(animated: true)
131131
} else {
132132
UIView.animate(withDuration: 0.2) {
133-
self.container.transform = .identity
133+
self.contentView.transform = .identity
134134
}
135135
}
136136
case .failed, .cancelled:
137137
UIView.animate(withDuration: 0.2) {
138-
self.container.transform = .identity
138+
self.contentView.transform = .identity
139139
}
140140
default:
141141
break

Sources/ComponentsKit/Components/Modal/UIKit/UKCenterModalController.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,15 @@ public class UKCenterModalController: UKModalController<CenterModalVM> {
7171
super.viewWillAppear(animated)
7272

7373
self.overlay.alpha = 0
74-
self.container.alpha = 0
74+
self.contentView.alpha = 0
7575
}
7676

7777
public override func viewDidAppear(_ animated: Bool) {
7878
super.viewDidAppear(animated)
7979

8080
UIView.animate(withDuration: self.model.transition.value) {
8181
self.overlay.alpha = 1
82-
self.container.alpha = 1
82+
self.contentView.alpha = 1
8383
}
8484
}
8585

@@ -88,11 +88,11 @@ public class UKCenterModalController: UKModalController<CenterModalVM> {
8888
public override func layout() {
8989
super.layout()
9090

91-
self.container.bottomAnchor.constraint(
91+
self.contentView.bottomAnchor.constraint(
9292
lessThanOrEqualTo: self.view.safeAreaLayoutGuide.bottomAnchor,
9393
constant: -self.model.outerPaddings.bottom
9494
).isActive = true
95-
self.container.centerVertically()
95+
self.contentView.centerVertically()
9696
}
9797

9898
// MARK: - UIViewController Methods
@@ -103,7 +103,7 @@ public class UKCenterModalController: UKModalController<CenterModalVM> {
103103
) {
104104
UIView.animate(withDuration: self.model.transition.value) {
105105
self.overlay.alpha = 0
106-
self.container.alpha = 0
106+
self.contentView.alpha = 0
107107
} completion: { _ in
108108
super.dismiss(animated: false)
109109
}

Sources/ComponentsKit/Components/Modal/UIKit/UKModalController.swift

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ open class UKModalController<VM: ModalVM>: UIViewController {
1414
/// A model that defines the appearance properties.
1515
public let model: VM
1616

17-
private var containerWidthConstraint: NSLayoutConstraint?
17+
private var contentViewWidthConstraint: NSLayoutConstraint?
1818

1919
// MARK: - Subviews
2020

@@ -24,10 +24,8 @@ open class UKModalController<VM: ModalVM>: UIViewController {
2424
public var body = UIView()
2525
/// The optional footer view of the modal.
2626
public var footer: UIView?
27-
/// The container view that holds the modal's content.
28-
public let container = UIView()
29-
/// The content view inside the container, holding the header, body, and footer.
30-
public let content = UIView()
27+
/// The content view, holding the header, body, and footer.
28+
public let contentView = UIView()
3129
/// A scrollable wrapper for the body content.
3230
public let bodyWrapper: UIScrollView = ContentSizedScrollView()
3331
/// The overlay view that appears behind the modal.
@@ -70,14 +68,13 @@ open class UKModalController<VM: ModalVM>: UIViewController {
7068
/// Sets up the modal's subviews and gesture recognizers.
7169
open func setup() {
7270
self.view.addSubview(self.overlay)
73-
self.view.addSubview(self.container)
74-
self.container.addSubview(self.content)
71+
self.view.addSubview(self.contentView)
7572
if let header {
76-
self.content.addSubview(header)
73+
self.contentView.addSubview(header)
7774
}
78-
self.content.addSubview(self.bodyWrapper)
75+
self.contentView.addSubview(self.bodyWrapper)
7976
if let footer {
80-
self.content.addSubview(footer)
77+
self.contentView.addSubview(footer)
8178
}
8279

8380
self.bodyWrapper.addSubview(self.body)
@@ -104,8 +101,7 @@ open class UKModalController<VM: ModalVM>: UIViewController {
104101
/// Applies styling to the modal's subviews.
105102
open func style() {
106103
Self.Style.overlay(self.overlay, model: self.model)
107-
Self.Style.container(self.container, model: self.model)
108-
Self.Style.content(self.content, model: self.model)
104+
Self.Style.contentView(self.contentView, model: self.model)
109105
Self.Style.bodyWrapper(self.bodyWrapper)
110106
}
111107

@@ -114,7 +110,6 @@ open class UKModalController<VM: ModalVM>: UIViewController {
114110
/// Configures the layout of the modal's subviews.
115111
open func layout() {
116112
self.overlay.allEdges()
117-
self.content.allEdges()
118113

119114
if let header {
120115
header.top(self.model.contentPaddings.top)
@@ -145,38 +140,38 @@ open class UKModalController<VM: ModalVM>: UIViewController {
145140
self.bodyWrapper.horizontally()
146141
self.bodyWrapper.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
147142

148-
self.body.leading(self.model.contentPaddings.leading, to: self.container)
149-
self.body.trailing(self.model.contentPaddings.trailing, to: self.container)
143+
self.body.leading(self.model.contentPaddings.leading, to: self.contentView)
144+
self.body.trailing(self.model.contentPaddings.trailing, to: self.contentView)
150145

151-
self.container.topAnchor.constraint(
146+
self.contentView.topAnchor.constraint(
152147
greaterThanOrEqualTo: self.view.safeAreaLayoutGuide.topAnchor,
153148
constant: self.model.outerPaddings.top
154149
).isActive = true
155-
self.container.leadingAnchor.constraint(
150+
self.contentView.leadingAnchor.constraint(
156151
greaterThanOrEqualTo: self.view.safeAreaLayoutGuide.leadingAnchor,
157152
constant: self.model.outerPaddings.leading
158153
).isActive = true
159-
self.container.trailingAnchor.constraint(
154+
self.contentView.trailingAnchor.constraint(
160155
lessThanOrEqualTo: self.view.safeAreaLayoutGuide.trailingAnchor,
161156
constant: -self.model.outerPaddings.trailing
162157
).isActive = true
163-
self.container.heightAnchor.constraint(
158+
self.contentView.heightAnchor.constraint(
164159
greaterThanOrEqualToConstant: 80
165160
).isActive = true
166161

167-
self.containerWidthConstraint = self.container.width(self.model.size.maxWidth).width
168-
self.containerWidthConstraint?.priority = .defaultHigh
162+
self.contentViewWidthConstraint = self.contentView.width(self.model.size.maxWidth).width
163+
self.contentViewWidthConstraint?.priority = .defaultHigh
169164

170-
self.bodyWrapper.widthAnchor.constraint(equalTo: self.container.widthAnchor).isActive = true
165+
self.bodyWrapper.widthAnchor.constraint(equalTo: self.contentView.widthAnchor).isActive = true
171166

172-
self.container.centerHorizontally()
167+
self.contentView.centerHorizontally()
173168
}
174169

175170
open override func viewWillTransition(
176171
to size: CGSize,
177172
with coordinator: any UIViewControllerTransitionCoordinator
178173
) {
179-
self.containerWidthConstraint?.isActive = false
174+
self.contentViewWidthConstraint?.isActive = false
180175
super.viewWillTransition(to: size, with: coordinator)
181176
}
182177

@@ -188,11 +183,11 @@ open class UKModalController<VM: ModalVM>: UIViewController {
188183
+ self.model.outerPaddings.leading
189184
+ self.model.outerPaddings.trailing
190185
if availableWidth > requiredWidth {
191-
self.containerWidthConstraint?.priority = .required
186+
self.contentViewWidthConstraint?.priority = .required
192187
} else {
193-
self.containerWidthConstraint?.priority = .defaultHigh
188+
self.contentViewWidthConstraint?.priority = .defaultHigh
194189
}
195-
self.containerWidthConstraint?.isActive = true
190+
self.contentViewWidthConstraint?.isActive = true
196191
}
197192

198193
// MARK: - UIViewController Methods
@@ -207,7 +202,7 @@ open class UKModalController<VM: ModalVM>: UIViewController {
207202
// MARK: - Helpers
208203

209204
@objc private func handleTraitChanges() {
210-
Self.Style.content(self.content, model: self.model)
205+
Self.Style.contentView(self.contentView, model: self.model)
211206
}
212207
}
213208

@@ -225,11 +220,7 @@ extension UKModalController {
225220
(view as? UIVisualEffectView)?.effect = UIBlurEffect(style: .systemUltraThinMaterial)
226221
}
227222
}
228-
static func container(_ view: UIView, model: VM) {
229-
view.backgroundColor = UniversalColor.background.uiColor
230-
view.layer.cornerRadius = model.cornerRadius.value
231-
}
232-
static func content(_ view: UIView, model: VM) {
223+
static func contentView(_ view: UIView, model: VM) {
233224
view.backgroundColor = model.preferredBackgroundColor.uiColor
234225
view.layer.cornerRadius = model.cornerRadius.value
235226
view.layer.borderColor = UniversalColor.divider.cgColor

Sources/ComponentsKit/Shared/Colors/ComponentColor.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ public struct ComponentColor: Hashable {
1111
public let contrast: UniversalColor
1212

1313
/// The background color for the component.
14-
public let background: UniversalColor
14+
public var background: UniversalColor {
15+
return self._background ?? self.main.withOpacity(0.15).blended(with: .background)
16+
}
17+
18+
private let _background: UniversalColor?
1519

1620
// MARK: - Initialization
1721

@@ -28,6 +32,6 @@ public struct ComponentColor: Hashable {
2832
) {
2933
self.main = main
3034
self.contrast = contrast
31-
self.background = background ?? main.withOpacity(0.15)
35+
self._background = background
3236
}
3337
}

0 commit comments

Comments
 (0)