Skip to content

Commit 088e587

Browse files
add shadow to config and card
1 parent bda0ecb commit 088e587

File tree

7 files changed

+196
-5
lines changed

7 files changed

+196
-5
lines changed

Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/CardPreview.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ struct CardPreview: View {
3131
ContainerRadiusPicker(selection: self.$model.cornerRadius) {
3232
Text("Custom 4px").tag(ContainerRadius.custom(4))
3333
}
34+
Picker("Shadow", selection: self.$model.shadow) {
35+
Text("None").tag(Shadow.none)
36+
Text("Small").tag(Shadow.small)
37+
Text("Medium").tag(Shadow.medium)
38+
Text("Large").tag(Shadow.large)
39+
Text("Custom").tag(Shadow.custom(20.0, .zero, ComponentColor.accent.background))
40+
}
3441
}
3542
}
3643
}

Sources/ComponentsKit/Components/Card/CardVM.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public struct CardVM: ComponentVM {
1414
/// Defaults to `.medium`.
1515
public var cornerRadius: ContainerRadius = .medium
1616

17+
public var shadow: Shadow = .medium
18+
1719
public init() {}
1820
}
1921

Sources/ComponentsKit/Components/Card/UKCard.swift

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@ import AutoLayout
22
import UIKit
33

44
open class UKCard: UIView, UKComponent {
5+
// MARK: - Typealiases
6+
57
public typealias Content = () -> UIView
68

9+
// MARK: - Subviews
10+
711
public let content: UIView
812
public let contentView = UIView()
913

14+
// MARK: - Properties
15+
1016
private var contentConstraints = LayoutConstraints()
1117

1218
public var model: CardVM {
@@ -15,6 +21,8 @@ open class UKCard: UIView, UKComponent {
1521
}
1622
}
1723

24+
// MARK: - Initialization
25+
1826
public init(model: CardVM, content: @escaping Content) {
1927
self.model = model
2028
self.content = content()
@@ -30,16 +38,28 @@ open class UKCard: UIView, UKComponent {
3038
fatalError("init(coder:) has not been implemented")
3139
}
3240

41+
// MARK: - Setup
42+
3343
open func setup() {
3444
self.addSubview(self.contentView)
3545
self.contentView.addSubview(self.content)
46+
47+
if #available(iOS 17.0, *) {
48+
self.registerForTraitChanges([UITraitUserInterfaceStyle.self]) { (view: Self, _: UITraitCollection) in
49+
view.handleTraitChanges()
50+
}
51+
}
3652
}
3753

54+
// MARK: - Style
55+
3856
open func style() {
3957
Self.Style.mainView(self, model: self.model)
4058
Self.Style.contentView(self.contentView, model: self.model)
4159
}
4260

61+
// MARK: - Layout
62+
4363
open func layout() {
4464
self.contentView.allEdges()
4565

@@ -71,6 +91,21 @@ open class UKCard: UIView, UKComponent {
7191

7292
self.layoutIfNeeded()
7393
}
94+
95+
// MARK: - UIView Methods
96+
97+
open override func traitCollectionDidChange(
98+
_ previousTraitCollection: UITraitCollection?
99+
) {
100+
super.traitCollectionDidChange(previousTraitCollection)
101+
self.handleTraitChanges()
102+
}
103+
104+
// MARK: - Helpers
105+
106+
@objc private func handleTraitChanges() {
107+
Self.Style.mainView(self, model: self.model)
108+
}
74109
}
75110

76111
extension UKCard {
@@ -79,11 +114,11 @@ extension UKCard {
79114
view.backgroundColor = UniversalColor.background.uiColor
80115
view.layer.cornerRadius = model.cornerRadius.value
81116
view.layer.borderWidth = 1
82-
view.layer.borderColor = UniversalColor.divider.uiColor.cgColor
83-
view.layer.shadowColor = UIColor.black.cgColor
84-
view.layer.shadowRadius = 16
85-
view.layer.shadowOpacity = 0.1
86-
view.layer.shadowOffset = .init(width: 0, height: 10)
117+
view.layer.borderColor = UniversalColor.divider.cgColor
118+
view.layer.shadowRadius = model.shadow.radius
119+
view.layer.shadowOffset = model.shadow.offset
120+
view.layer.shadowColor = model.shadow.color.cgColor
121+
view.layer.shadowOpacity = 1
87122
}
88123

89124
static func contentView(_ view: UIView, model: Model) {

Sources/ComponentsKit/Configuration/Layout.swift

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,65 @@ extension ComponentsKitConfig {
8585
}
8686
}
8787

88+
// MARK: - Shadow
89+
90+
/// A structure that defines the parameters for a shadow effect.
91+
public struct ShadowParams {
92+
/// The blur radius of the shadow.
93+
///
94+
/// A larger radius results in a more diffuse shadow.
95+
public var radius: CGFloat
96+
97+
/// The offset of the shadow, defining its position relative to the component.
98+
///
99+
/// - `width`: Moves the shadow horizontally.
100+
/// - `height`: Moves the shadow vertically.
101+
public var offset: CGSize
102+
103+
/// The color of the shadow.
104+
public var color: UniversalColor
105+
106+
// MARK: - Initialization
107+
108+
/// Initializes a new `ShadowParams` instance with the specified radius, offset, and color.
109+
///
110+
/// - Parameters:
111+
/// - radius: The blur radius of the shadow.
112+
/// - offset: The offset of the shadow as a `CGSize`.
113+
/// - color: The color of the shadow.
114+
public init(radius: CGFloat, offset: CGSize, color: UniversalColor) {
115+
self.radius = radius
116+
self.offset = offset
117+
self.color = color
118+
}
119+
}
120+
121+
/// A structure that defines shadow presets for small, medium, and large shadows.
122+
public struct Shadow {
123+
/// The shadow parameters for a small shadow.
124+
public var small: ShadowParams
125+
126+
/// The shadow parameters for a medium shadow.
127+
public var medium: ShadowParams
128+
129+
/// The shadow parameters for a large shadow.
130+
public var large: ShadowParams
131+
132+
// MARK: - Initialization
133+
134+
/// Initializes a new `Shadow` instance with the specified small, medium, and large shadow parameters.
135+
///
136+
/// - Parameters:
137+
/// - small: The parameters for a small shadow.
138+
/// - medium: The parameters for a medium shadow.
139+
/// - large: The parameters for a large shadow.
140+
public init(small: ShadowParams, medium: ShadowParams, large: ShadowParams) {
141+
self.small = small
142+
self.medium = medium
143+
self.large = large
144+
}
145+
}
146+
88147
// MARK: - Typography
89148

90149
/// A structure representing a set of fonts for different component sizes.
@@ -154,6 +213,34 @@ extension ComponentsKitConfig {
154213
large: 26.0
155214
)
156215

216+
/// The shadow configuration for components.
217+
public var shadow: Shadow = .init(
218+
small: .init(
219+
radius: 10.0,
220+
offset: .init(width: 0, height: 6),
221+
color: .themed(
222+
light: .rgba(r: 0, g: 0, b: 0, a: 0.1),
223+
dark: .rgba(r: 255, g: 255, b: 255, a: 0.1)
224+
)
225+
),
226+
medium: .init(
227+
radius: 16.0,
228+
offset: .init(width: 0, height: 10),
229+
color: .themed(
230+
light: .rgba(r: 0, g: 0, b: 0, a: 0.15),
231+
dark: .rgba(r: 255, g: 255, b: 255, a: 0.15)
232+
)
233+
),
234+
large: .init(
235+
radius: 20.0,
236+
offset: .init(width: 0, height: 12),
237+
color: .themed(
238+
light: .rgba(r: 0, g: 0, b: 0, a: 0.2),
239+
dark: .rgba(r: 255, g: 255, b: 255, a: 0.2)
240+
)
241+
)
242+
)
243+
157244
/// The border width configuration for components.
158245
public var borderWidth: BorderWidth = .init(
159246
small: 1.0,

Sources/ComponentsKit/Configuration/Palette.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ extension UniversalColor {
151151
public static var white: Self {
152152
return .universal(.hex("#FFFFFF"))
153153
}
154+
public static var clear: Self {
155+
return .universal(.uiColor(.clear))
156+
}
154157
}
155158

156159
// MARK: - UniversalColor + Palette Colors

Sources/ComponentsKit/Shared/Colors/UniversalColor.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,9 @@ public struct UniversalColor: Hashable {
162162
public var color: Color {
163163
return Color(self.uiColor)
164164
}
165+
166+
/// Returns the `CGColor` representation of the color.
167+
public var cgColor: CGColor {
168+
return self.uiColor.cgColor
169+
}
165170
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import Foundation
2+
3+
/// Defines shadow options for components.
4+
public enum Shadow: Hashable {
5+
/// No shadow is applied.
6+
case none
7+
/// A small shadow, using a predefined configuration.
8+
case small
9+
/// A medium shadow, using a predefined configuration.
10+
case medium
11+
/// A large shadow, using a predefined configuration.
12+
case large
13+
/// A custom shadow with specific parameters.
14+
///
15+
/// - Parameters:
16+
/// - radius: The blur radius of the shadow.
17+
/// - offset: The offset of the shadow.
18+
/// - color: The color of the shadow.
19+
case custom(_ radius: CGFloat, _ offset: CGSize, _ color: UniversalColor)
20+
}
21+
22+
extension Shadow {
23+
var radius: CGFloat {
24+
return switch self {
25+
case .none: CGFloat(0)
26+
case .small: ComponentsKitConfig.shared.layout.shadow.small.radius
27+
case .medium: ComponentsKitConfig.shared.layout.shadow.medium.radius
28+
case .large: ComponentsKitConfig.shared.layout.shadow.large.radius
29+
case .custom(let radius, _, _): radius
30+
}
31+
}
32+
33+
var offset: CGSize {
34+
return switch self {
35+
case .none: .zero
36+
case .small: ComponentsKitConfig.shared.layout.shadow.small.offset
37+
case .medium: ComponentsKitConfig.shared.layout.shadow.medium.offset
38+
case .large: ComponentsKitConfig.shared.layout.shadow.large.offset
39+
case .custom(_, let offset, _): offset
40+
}
41+
}
42+
43+
var color: UniversalColor {
44+
return switch self {
45+
case .none: .clear
46+
case .small: ComponentsKitConfig.shared.layout.shadow.small.color
47+
case .medium: ComponentsKitConfig.shared.layout.shadow.medium.color
48+
case .large: ComponentsKitConfig.shared.layout.shadow.large.color
49+
case .custom(_, _, let color): color
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)