Skip to content

Commit a2d5f1d

Browse files
authored
Merge pull request #230 from surfstudio/feature/SPT-1476/componets_model_builder
Feature/spt 1476/componets model builder
2 parents 67314dc + 1536901 commit a2d5f1d

File tree

9 files changed

+430
-144
lines changed

9 files changed

+430
-144
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// BakgroundStyle.swift
3+
// ReactiveDataDisplayManager
4+
//
5+
// Created by Никита Коробейников on 14.06.2023.
6+
//
7+
8+
import UIKit
9+
10+
public enum BackgroundStyle: Equatable {
11+
12+
/// Solid background filled with single color
13+
case solid(UIColor?)
14+
15+
// TODO: - gradient, image, bezierPath, bordered
16+
17+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// BorderStyle.swift
3+
// ReactiveDataDisplayManager
4+
//
5+
// Created by Никита Коробейников on 14.06.2023.
6+
//
7+
8+
import UIKit
9+
10+
public struct BorderStyle: Equatable {
11+
12+
public let cornerRadius: CGFloat
13+
public let maskedCorners: CACornerMask
14+
public let borderWidth: CGFloat
15+
public let borderColor: CGColor
16+
17+
public init(cornerRadius: CGFloat,
18+
maskedCorners: CACornerMask,
19+
borderWidth: CGFloat = 0,
20+
borderColor: CGColor = UIColor.clear.cgColor) {
21+
self.cornerRadius = cornerRadius
22+
self.maskedCorners = maskedCorners
23+
self.borderWidth = borderWidth
24+
self.borderColor = borderColor
25+
}
26+
27+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// TextLayout.swift
3+
// ReactiveDataDisplayManager
4+
//
5+
// Created by Никита Коробейников on 14.06.2023.
6+
//
7+
8+
import UIKit
9+
10+
public struct TextLayout: Equatable {
11+
12+
public let lineBreakMode: NSLineBreakMode
13+
public let numberOfLines: Int
14+
15+
public init(lineBreakMode: NSLineBreakMode = .byWordWrapping, numberOfLines: Int = 0) {
16+
self.lineBreakMode = lineBreakMode
17+
self.numberOfLines = numberOfLines
18+
}
19+
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// TextStyle.swift
3+
// ReactiveDataDisplayManager
4+
//
5+
// Created by Никита Коробейников on 14.06.2023.
6+
//
7+
8+
import UIKit
9+
10+
public struct TextStyle: Equatable {
11+
12+
public let color: UIColor
13+
public let font: UIFont
14+
15+
public init(color: UIColor = .black, font: UIFont = .systemFont(ofSize: 16)) {
16+
self.color = color
17+
self.font = font
18+
}
19+
20+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// TextValue.swift
3+
// ReactiveDataDisplayManager
4+
//
5+
// Created by Никита Коробейников on 14.06.2023.
6+
//
7+
8+
import UIKit
9+
10+
public enum TextValue: Equatable {
11+
case string(String)
12+
/// Keep in mind that attributed string may re-configure other model's properties.
13+
case attributedString(NSAttributedString)
14+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// Editor.swift
3+
// ReactiveDataDisplayManager
4+
//
5+
// Created by Никита Коробейников on 15.06.2023.
6+
//
7+
8+
import Foundation
9+
10+
public protocol Editor {
11+
associatedtype Model
12+
13+
func edit(_ model: Model) -> Model
14+
}
15+
16+
@resultBuilder
17+
public struct EditorBuilder<T: Editor> {
18+
public static func buildExpression(_ expression: T) -> [T] {
19+
return [expression]
20+
}
21+
22+
public static func buildExpression(_ expressions: [T]) -> [T] {
23+
return expressions
24+
}
25+
26+
public static func buildExpression(_ expression: ()) -> [T] {
27+
return []
28+
}
29+
30+
public static func buildBlock(_ components: [T]...) -> [T] {
31+
return components.flatMap { $0 }
32+
}
33+
34+
public static func buildArray(_ components: [[T]]) -> [T] {
35+
return Array(components.joined())
36+
}
37+
38+
// to use like if-else
39+
40+
public static func buildEither(first component: [T]) -> [T] {
41+
return component
42+
}
43+
44+
public static func buildEither(second component: [T]) -> [T] {
45+
return component
46+
}
47+
48+
public static func buildOptional(_ component: [T]?) -> [T] {
49+
return component ?? []
50+
}
51+
}

Components/Sources/Common/Views/LabelView.swift

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,58 +25,98 @@ extension LabelView: ConfigurableItem {
2525

2626
public struct Model: AlignmentProvider {
2727

28-
// MARK: - Nested types
28+
// MARK: - Editor
2929

30-
public struct TextStyle: Equatable {
30+
public struct Property: Editor {
31+
public typealias Model = LabelView.Model
3132

32-
public let color: UIColor
33-
public let font: UIFont
33+
private let closure: (Model) -> Model
3434

35-
public init(color: UIColor = .black, font: UIFont = .systemFont(ofSize: 16)) {
36-
self.color = color
37-
self.font = font
35+
public init(closure: @escaping (Model) -> Model) {
36+
self.closure = closure
3837
}
3938

40-
}
39+
public func edit(_ model: Model) -> Model {
40+
return closure(model)
41+
}
4142

42-
public struct TextLayout: Equatable {
43+
public static func text(_ value: TextValue) -> Property {
44+
.init(closure: { model in
45+
var model = model
46+
model.set(text: value)
47+
return model
48+
})
49+
}
4350

44-
public let lineBreakMode: NSLineBreakMode
45-
public let numberOfLines: Int
51+
public static func style(_ value: TextStyle) -> Property {
52+
.init(closure: { model in
53+
var model = model
54+
model.set(style: value)
55+
return model
56+
})
57+
}
4658

47-
public init(lineBreakMode: NSLineBreakMode = .byWordWrapping, numberOfLines: Int = 0) {
48-
self.lineBreakMode = lineBreakMode
49-
self.numberOfLines = numberOfLines
59+
public static func layout(_ value: TextLayout) -> Property {
60+
.init(closure: { model in
61+
var model = model
62+
model.set(layout: value)
63+
return model
64+
})
5065
}
5166

52-
}
67+
public static func alignment(_ value: Alignment) -> Property {
68+
.init(closure: { model in
69+
var model = model
70+
model.set(alignment: value)
71+
return model
72+
})
73+
}
5374

54-
public enum TextType: Equatable {
55-
case string(String)
56-
/// Mind that attributed string may re-configure other model's properties.
57-
case attributedString(NSAttributedString)
75+
public static func textAlignment(_ value: NSTextAlignment) -> Property {
76+
.init(closure: { model in
77+
var model = model
78+
model.set(textAlignment: value)
79+
return model
80+
})
81+
}
5882
}
5983

6084
// MARK: - Public properties
6185

62-
public let text: TextType
63-
public let style: TextStyle
64-
public let layout: TextLayout
65-
public let alignment: Alignment
66-
public let textAlignment: NSTextAlignment
86+
private(set) public var text: TextValue = .string("")
87+
private(set) public var style: TextStyle = .init()
88+
private(set) public var layout: TextLayout = .init()
89+
private(set) public var alignment: Alignment = .all(.zero)
90+
private(set) public var textAlignment: NSTextAlignment = .left
6791

68-
// MARK: - Initialization
92+
// MARK: - Mutation
6993

70-
public init(text: TextType,
71-
style: TextStyle,
72-
layout: TextLayout,
73-
textAlignment: NSTextAlignment,
74-
viewAlignment: Alignment = .all(.zero)) {
94+
mutating func set(text: TextValue) {
7595
self.text = text
96+
}
97+
98+
mutating func set(style: TextStyle) {
7699
self.style = style
100+
}
101+
102+
mutating func set(layout: TextLayout) {
77103
self.layout = layout
104+
}
105+
106+
mutating func set(alignment: Alignment) {
107+
self.alignment = alignment
108+
}
109+
110+
mutating func set(textAlignment: NSTextAlignment) {
78111
self.textAlignment = textAlignment
79-
self.alignment = viewAlignment
112+
}
113+
114+
// MARK: - Builder
115+
116+
public static func build(@EditorBuilder<Property> content: (Property.Type) -> [Property]) -> Self {
117+
return content(Property.self).reduce(.init(), { model, editor in
118+
editor.edit(model)
119+
})
80120
}
81121

82122
}
@@ -110,7 +150,7 @@ private extension LabelView {
110150
wrap(subview: label, with: .zero)
111151
}
112152

113-
func configureText(with text: Model.TextType) {
153+
func configureText(with text: TextValue) {
114154
switch text {
115155
case .string(let text):
116156
label.text = text

0 commit comments

Comments
 (0)