Skip to content

Commit d3c89ac

Browse files
Merge pull request #39 from componentskit/dev
v1.3.0
2 parents 5580d87 + 0f7fd23 commit d3c89ac

File tree

133 files changed

+5959
-1470
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

133 files changed

+5959
-1470
lines changed

.github/workflows/swiftlint.yml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: SwiftLint
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '.github/workflows/swiftlint.yml'
7+
- '.swiftlint.yml'
8+
- '**/*.swift'
9+
10+
jobs:
11+
SwiftLint:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v1
15+
- name: Run SwiftLint
16+
uses: norio-nomura/action-swiftlint@3.2.1
17+
with:
18+
args: --strict

.swiftlint.yml

+1-2
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
@@ -409,7 +409,6 @@ function_body_length:
409409

410410
included:
411411
- Sources
412-
- Examples
413412

414413
excluded:
415414
- .swiftpm

ComponentsKit.xcworkspace/xcshareddata/swiftpm/Package.resolved

-9
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,6 @@
88
"revision" : "78e39facca2cc459a135655cae0e9feb5a587892",
99
"version" : "1.0.0"
1010
}
11-
},
12-
{
13-
"identity" : "swiftlintplugins",
14-
"kind" : "remoteSourceControl",
15-
"location" : "https://github.com/SimplyDanny/SwiftLintPlugins",
16-
"state" : {
17-
"revision" : "7c80ce6f142164b0201871e580b021d1b2c69804",
18-
"version" : "0.57.0"
19-
}
2011
}
2112
],
2213
"version" : 2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
import ComponentsKit
2+
import SwiftUI
3+
import UIKit
4+
5+
struct ModalPreviewHelpers {
6+
// MARK: - Enums
7+
8+
enum ContentBody {
9+
case shortText
10+
case longText
11+
}
12+
enum ContentFooter {
13+
case button
14+
case buttonAndCheckbox
15+
}
16+
17+
// MARK: - Preview Sections
18+
19+
struct ContentSection<VM: ModalVM>: View {
20+
@Binding var model: VM
21+
@Binding var hasHeader: Bool
22+
@Binding var contentBody: ContentBody
23+
@Binding var contentFooter: ContentFooter?
24+
25+
var body: some View {
26+
Section("Content") {
27+
Picker("Header", selection: self.$hasHeader) {
28+
Text("Text").tag(true)
29+
Text("None").tag(false)
30+
}
31+
Picker("Body", selection: self.$contentBody) {
32+
Text("Short Text").tag(ContentBody.shortText)
33+
Text("Long Text").tag(ContentBody.longText)
34+
}
35+
Picker("Footer", selection: .init(
36+
get: {
37+
return self.contentFooter
38+
},
39+
set: { newValue in
40+
if newValue == nil {
41+
self.model.closesOnOverlayTap = true
42+
}
43+
self.contentFooter = newValue
44+
}
45+
)) {
46+
Text("Button").tag(ContentFooter.button)
47+
Text("Button and Checkbox").tag(ContentFooter.buttonAndCheckbox)
48+
Text("None").tag(Optional<ContentFooter>.none)
49+
}
50+
}
51+
}
52+
}
53+
54+
struct PropertiesSection<VM: ModalVM, Pickers: View>: View {
55+
@Binding var model: VM
56+
@Binding var footer: ContentFooter?
57+
@ViewBuilder var additionalPickers: () -> Pickers
58+
59+
var body: some View {
60+
Section("Properties") {
61+
Picker("Background Color", selection: self.$model.backgroundColor) {
62+
Text("Default").tag(Optional<UniversalColor>.none)
63+
Text("Accent Background").tag(ComponentColor.accent.background)
64+
Text("Success Background").tag(ComponentColor.success.background)
65+
Text("Warning Background").tag(ComponentColor.warning.background)
66+
Text("Danger Background").tag(ComponentColor.danger.background)
67+
}
68+
BorderWidthPicker(selection: self.$model.borderWidth)
69+
Toggle("Closes On Overlay Tap", isOn: self.$model.closesOnOverlayTap)
70+
.disabled(self.footer == nil)
71+
Picker("Outer Paddings", selection: self.$model.outerPaddings) {
72+
Text("12px").tag(Paddings(padding: 12))
73+
Text("16px").tag(Paddings(padding: 16))
74+
Text("20px").tag(Paddings(padding: 20))
75+
}
76+
Picker("Content Spacing", selection: self.$model.contentSpacing) {
77+
Text("8px").tag(CGFloat(8))
78+
Text("12px").tag(CGFloat(12))
79+
Text("16px").tag(CGFloat(16))
80+
}
81+
Picker("Content Paddings", selection: self.$model.contentPaddings) {
82+
Text("12px").tag(Paddings(padding: 12))
83+
Text("16px").tag(Paddings(padding: 16))
84+
Text("20px").tag(Paddings(padding: 20))
85+
}
86+
ContainerRadiusPicker(selection: self.$model.cornerRadius) {
87+
Text("Custom 30px").tag(ContainerRadius.custom(30))
88+
}
89+
OverlayStylePicker(selection: self.$model.overlayStyle)
90+
Picker("Size", selection: self.$model.size) {
91+
Text("Small").tag(ModalSize.small)
92+
Text("Medium").tag(ModalSize.medium)
93+
Text("Large").tag(ModalSize.large)
94+
Text("Full").tag(ModalSize.full)
95+
}
96+
TransitionPicker(selection: self.$model.transition)
97+
self.additionalPickers()
98+
}
99+
}
100+
}
101+
102+
// MARK: - Shared UI
103+
104+
private static let headerTitle = "Header"
105+
private static let headerFont: UniversalFont = .system(size: 20, weight: .bold)
106+
107+
private static let bodyShortText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
108+
private static let bodyLongText = """
109+
Lorem ipsum odor amet, consectetuer adipiscing elit. Vitae vehicula pellentesque lectus orci fames. Cras suscipit dui tortor penatibus turpis ultrices. Laoreet montes adipiscing ante dapibus facilisis. Lorem per fames nec duis quis eleifend imperdiet. Tincidunt id interdum adipiscing eros dis quis platea varius. Potenti eleifend eu molestie laoreet varius sapien. Adipiscing nascetur platea penatibus curabitur tempus nibh laoreet porttitor. Augue et curabitur cras sed semper inceptos nunc montes mollis.
110+
111+
Lectus arcu pellentesque inceptos tempor fringilla nascetur. Erat curae convallis integer mi, quis facilisi tortor. Phasellus aliquam molestie vehicula odio in dis maximus diam elit. Rutrum gravida amet euismod feugiat fusce. Est egestas velit vulputate senectus sociosqu fringilla eget nibh. Nam pellentesque aenean mi platea tincidunt quam sem purus. Himenaeos suspendisse nec sapien habitasse ultricies maecenas libero odio. Rutrum senectus maximus ultrices, ad nam ultricies placerat.
112+
113+
Enim habitant laoreet inceptos scelerisque senectus, tellus molestie ut. Eros risus nibh morbi eu aenean. Velit ligula magnis aliquet at luctus. Dapibus vestibulum consectetur euismod vitae per ultrices litora quis. Aptent eleifend dapibus urna lacinia felis nisl. Sit amet fusce nullam feugiat posuere. Urna amet curae velit fermentum interdum vestibulum penatibus. Penatibus vivamus sem ultricies pellentesque congue id mattis diam. Aliquam efficitur mi gravida sollicitudin; amet imperdiet. Rutrum mollis risus justo tortor in duis cursus.
114+
"""
115+
private static let bodyFont: UniversalFont = .system(size: 18, weight: .regular)
116+
117+
private static let footerButtonVM = ButtonVM {
118+
$0.title = "Close"
119+
$0.isFullWidth = true
120+
$0.color = .primary
121+
}
122+
private static let footerCheckboxVM = CheckboxVM {
123+
$0.title = "Agree and continue"
124+
}
125+
126+
// MARK: - UIKit
127+
128+
static func ukHeader(hasHeader: Bool) -> UKModalController.Content? {
129+
guard hasHeader else {
130+
return nil
131+
}
132+
133+
return { _ in
134+
let title = UILabel()
135+
title.text = self.headerTitle
136+
title.font = self.headerFont.uiFont
137+
return title
138+
}
139+
}
140+
141+
static func ukBody(body: ContentBody) -> UKModalController.Content {
142+
return { _ in
143+
let subtitle = UILabel()
144+
switch body {
145+
case .shortText:
146+
subtitle.text = self.bodyShortText
147+
case .longText:
148+
subtitle.text = self.bodyLongText
149+
}
150+
subtitle.numberOfLines = 0
151+
subtitle.font = self.bodyFont.uiFont
152+
return subtitle
153+
}
154+
}
155+
156+
static func ukFooter(footer: ContentFooter?) -> UKModalController.Content? {
157+
return footer.map { footer in
158+
return { dismiss in
159+
let stackView = UIStackView()
160+
stackView.axis = .vertical
161+
stackView.spacing = 16
162+
163+
let button = UKButton(
164+
model: self.footerButtonVM,
165+
action: { dismiss(true) }
166+
)
167+
stackView.addArrangedSubview(button)
168+
169+
switch footer {
170+
case .button:
171+
button.model.isEnabled = true
172+
case .buttonAndCheckbox:
173+
button.model.isEnabled = false
174+
let checkbox = UKCheckbox(
175+
initialValue: false,
176+
model: self.footerCheckboxVM,
177+
onValueChange: { isSelected in
178+
button.model.isEnabled = isSelected
179+
}
180+
)
181+
stackView.insertArrangedSubview(checkbox, at: 0)
182+
}
183+
184+
return stackView
185+
}
186+
}
187+
}
188+
189+
// MARK: - SwiftUI
190+
191+
static func suHeader(hasHeader: Bool) -> some View {
192+
Group {
193+
if hasHeader {
194+
HStack {
195+
Text(self.headerTitle)
196+
.font(self.headerFont.font)
197+
Spacer()
198+
}
199+
} else {
200+
EmptyView()
201+
}
202+
}
203+
}
204+
205+
static func suBody(body: ContentBody) -> some View {
206+
Group {
207+
switch body {
208+
case .shortText:
209+
Text(self.bodyShortText)
210+
case .longText:
211+
Text(self.bodyLongText)
212+
}
213+
}
214+
.font(self.bodyFont.font)
215+
.multilineTextAlignment(.leading)
216+
}
217+
218+
static func suFooter(
219+
isPresented: Binding<Bool>,
220+
isCheckboxSelected: Binding<Bool>,
221+
footer: ContentFooter?
222+
) -> some View {
223+
Group {
224+
switch footer {
225+
case .none:
226+
EmptyView()
227+
case .button:
228+
SUButton(model: self.footerButtonVM) {
229+
isPresented.wrappedValue = false
230+
}
231+
case .buttonAndCheckbox:
232+
VStack(alignment: .leading, spacing: 16) {
233+
SUCheckbox(
234+
isSelected: isCheckboxSelected,
235+
model: self.footerCheckboxVM
236+
)
237+
SUButton(model: self.footerButtonVM.updating {
238+
$0.isEnabled = isCheckboxSelected.wrappedValue
239+
}) {
240+
isPresented.wrappedValue = false
241+
}
242+
}
243+
}
244+
}
245+
}
246+
}

0 commit comments

Comments
 (0)