diff --git a/Examples/UIComponentExample.xcodeproj/project.pbxproj b/Examples/UIComponentExample.xcodeproj/project.pbxproj index 49a4ffc8..4adb01a7 100644 --- a/Examples/UIComponentExample.xcodeproj/project.pbxproj +++ b/Examples/UIComponentExample.xcodeproj/project.pbxproj @@ -14,7 +14,6 @@ A304893221C347020026EDA7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A304893021C347020026EDA7 /* LaunchScreen.storyboard */; }; B10A123224F31EAA0076B038 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10A123124F31EAA0076B038 /* Helpers.swift */; }; B121A0A024F8771E00E59F78 /* UIComponent in Frameworks */ = {isa = PBXBuildFile; productRef = B121A09F24F8771E00E59F78 /* UIComponent */; }; - B1406F7F26A510ED0053E175 /* FlowViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1406F7E26A510ED0053E175 /* FlowViewController.swift */; }; B16EA6A02677E262005CFB18 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = B16EA69F2677E262005CFB18 /* Kingfisher */; }; B16EA6A22677E26F005CFB18 /* AsyncImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16EA6A12677E26F005CFB18 /* AsyncImage.swift */; }; B1B5C47B266FD2D50035CF02 /* TabBarExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B5C47A266FD2D50035CF02 /* TabBarExample.swift */; }; @@ -54,7 +53,6 @@ A304893121C347020026EDA7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; A304893321C347020026EDA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; B10A123124F31EAA0076B038 /* Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; - B1406F7E26A510ED0053E175 /* FlowViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowViewController.swift; sourceTree = ""; }; B16EA6A12677E26F005CFB18 /* AsyncImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncImage.swift; sourceTree = ""; }; B1B5C47A266FD2D50035CF02 /* TabBarExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarExample.swift; sourceTree = ""; }; B1CC3F622677FCFD005BCE8C /* CardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardViewController.swift; sourceTree = ""; }; @@ -118,14 +116,6 @@ path = UIComponentExample; sourceTree = ""; }; - B1406F7D26A510DA0053E175 /* Flow */ = { - isa = PBXGroup; - children = ( - B1406F7E26A510ED0053E175 /* FlowViewController.swift */, - ); - path = Flow; - sourceTree = ""; - }; B1CC3F682677FFCC005BCE8C /* Supporting Files */ = { isa = PBXGroup; children = ( @@ -172,7 +162,6 @@ B1CC3F6C267800B9005BCE8C /* Examples */ = { isa = PBXGroup; children = ( - B1406F7D26A510DA0053E175 /* Flow */, F88E832326A3E70C009E7720 /* Flex Layout */, B1CC3F692678008F005BCE8C /* Card */, B1CC3F6A2678009C005BCE8C /* AsyncImage */, @@ -284,7 +273,6 @@ B1CC3F7426789F3D005BCE8C /* CardData.swift in Sources */, B1CC3F7026789E1F005BCE8C /* CardViewController3.swift in Sources */, B1CC3F6E26789C55005BCE8C /* CardViewController2.swift in Sources */, - B1406F7F26A510ED0053E175 /* FlowViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Examples/UIComponentExample/Examples/Flex Layout/FlexLayoutViewController.swift b/Examples/UIComponentExample/Examples/Flex Layout/FlexLayoutViewController.swift index 1841c3f4..625e8673 100644 --- a/Examples/UIComponentExample/Examples/Flex Layout/FlexLayoutViewController.swift +++ b/Examples/UIComponentExample/Examples/Flex Layout/FlexLayoutViewController.swift @@ -10,26 +10,25 @@ import UIKit import UIComponent class Box: ComponentBuilder { - let height: CGFloat let width: CGFloat + let height: CGFloat let text: String init(_ text: String, width: CGFloat = 50, height: CGFloat = 50) { self.width = width self.height = height self.text = text } + convenience init(_ index: Int, width: CGFloat = 50, height: CGFloat = 50) { + self.init("\(index)", width: width, height: height) + } func build() -> Component { - SimpleViewComponent() - .size(width: width, height: height) - .styleColor(.systemBlue).overlay(Text(text).textColor(.white).textAlignment(.center).size(width: .fill, height: .fill)) + Space(width: width, height: height).styleColor(.systemBlue).overlay(Text(text).textColor(.white).textAlignment(.center).size(width: .fill, height: .fill)) } - - } -extension ViewComponent { - func styleColor(_ tintColor: UIColor) -> ViewUpdateComponent { - update { +extension Component { + func styleColor(_ tintColor: UIColor) -> ViewUpdateComponent> { + view().update { $0.backgroundColor = tintColor.withAlphaComponent(0.5) $0.layer.cornerRadius = 10 $0.layer.cornerCurve = .continuous @@ -42,105 +41,123 @@ extension ViewComponent { class FlexLayoutViewController: ComponentViewController { override var component: Component { - return VStack(spacing: 20) { - Text("Flex layouts", font: .systemFont(ofSize: 20, weight: .bold)).textColor(.label).textAlignment(.center).size(width: .fill) - VStack(justifyContent: .center, alignItems: .center) { - HStack { - Text("HStack wrap") - Spacer() - } - Space(height: 10) - HStack(spacing: 10, justifyContent: .spaceBetween, wrapper: .wrap) { - for index in 0...10 { - SimpleViewComponent() - .size(width: .percentage(0.90/3), height: .aspectPercentage(1)) - .styleColor(.systemBlue).overlay(Text("\(index)").textColor(.white).textAlignment(.center).size(width: .fill, height: .fill)) - } - } - }.inset(10).view().styleColor(.systemGroupedBackground).size(width: .fill) - - VStack { - Text("HStack noWrap(can scroll horizontally)").inset(10) - HStack(spacing: 10, wrapper: .noWrap) { - for index in 0...10 { - Box("\(index)") + VStack(spacing: 20) { + Text("Flex layouts", font: .boldSystemFont(ofSize: 20)).size(width: .fill) + + VStack(spacing: 10) { + Text("Horizontal layouts") + VStack(spacing: 10) { + Text("FlexRow justify=spaceBetween") + FlexRow(spacing: 10, justifyContent: .spaceBetween) { + for index in 0...10 { + Box(index) + } } - }.scrollView().showsHorizontalScrollIndicator(false).contentInset(UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)) - Space(height: 10) - }.view().styleColor(.systemGroupedBackground) + }.inset(10).styleColor(.systemGray4).size(width: .fill) + + VStack { + Text("HStack (can scroll horizontally)").inset(top: 10, left: 10, bottom: 0, right: 10) + HStack(spacing: 10) { + for index in 0...10 { + Box(index) + } + }.inset(10).scrollView().showsHorizontalScrollIndicator(false) + }.styleColor(.systemGray4) + }.inset(10).styleColor(.systemGroupedBackground) VStack(spacing: 10) { - Text("VStack layouts") + Text("Vertical layouts") HStack(justifyContent: .spaceBetween) { VStack { - Text("VStack wrap") + Text("FlexColumn") Space(height: 10) - VStack(spacing: 10, wrapper: .wrap) { + FlexColumn(spacing: 10) { for index in 0...10 { - Box("\(index)") + Box(index) } - }.size(height: 300) - }.inset(10).view().styleColor(.systemGray4) + }.size(height: 290) + }.inset(10).styleColor(.systemGray4) Spacer() VStack { Space(height: 10) - Text("VStack noWrap") - VStack(spacing: 10, wrapper: .noWrap) { + Text("VStack") + VStack(spacing: 10) { for index in 0...10 { - Box("\(index)") + Box(index) } - }.inset(v: 10).scrollView().showsVerticalScrollIndicator(false).contentInset(UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)).size(height: 320) - }.inset(h: 10).view().styleColor(.systemGray4) + }.inset(10).scrollView().showsVerticalScrollIndicator(false).size(height: 310) + }.inset(h: 10).styleColor(.systemGray4) } - }.inset(10).view().styleColor(.systemGroupedBackground) + }.inset(10).styleColor(.systemGroupedBackground) - genHStack(wrapper: .wrap, justifyContent: .start, alignItems: .end) - genHStack(wrapper: .wrap, justifyContent: .start, alignItems: .start) - genHStack(wrapper: .wrap, justifyContent: .end, alignItems: .start) - genHStack(wrapper: .wrap, justifyContent: .center, alignItems: .start) - genHStack(wrapper: .wrap, justifyContent: .spaceBetween, alignItems: .start) - genHStack(wrapper: .wrap, justifyContent: .spaceAround, alignItems: .start) - genHStack(wrapper: .wrap, justifyContent: .spaceEvenly, alignItems: .start) - - }.inset(10) - - } - - func genHStack(wrapper: Wrapper, justifyContent: MainAxisAlignment, alignItems: CrossAxisAlignment) -> Component { - VStack(spacing: 10) { - Text("HStack\njustifyContent: .\(justifyContent)\nalignItems: .\(alignItems)\nwrapper: .\(wrapper)") - HStack(spacing: 10, justifyContent: justifyContent, alignItems: alignItems, wrapper: wrapper) { - Box("0", height: 100) - for index in 1..<10 { - if index == 8 { - Box("\(index)", height: 100) - } else { - Box("\(index)") - } + VStack(spacing: 10) { + Text("Justify Content", font: .boldSystemFont(ofSize: 20)).size(width: .fill) + for justifyContent in MainAxisAlignment.allCases { + Text("\(justifyContent)").size(width: .fill) + Flow(justifyContent: justifyContent) { + for index in 0..<10 { + Box(index) + } + }.inset(10).styleColor(.systemGroupedBackground) } - Box("10", height: 100) - }.inset(10).view().styleColor(.systemTeal) - }.inset(10).view().styleColor(.systemGroupedBackground) - } - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - /* - - - */ + } + + VStack(spacing: 10) { + Text("Align Items", font: .boldSystemFont(ofSize: 20)).size(width: .fill) + for alignItems in CrossAxisAlignment.allCases { + Text("\(alignItems)").size(width: .fill) + Flow(alignItems: alignItems) { + for index in 0..<10 { + Box(index, height: 50 + CGFloat(index % 4) * 10) + } + }.inset(10).styleColor(.systemGroupedBackground) + } + } + + VStack(spacing: 10) { + Text("Align Content", font: .boldSystemFont(ofSize: 20)).size(width: .fill) + for alignContent in MainAxisAlignment.allCases { + Text("\(alignContent)").size(width: .fill) + Flow(alignContent: alignContent) { + for index in 0..<10 { + Box(index, height: 50) + } + }.size(height: 150).inset(10).styleColor(.systemGroupedBackground) + } + } + + + VStack(spacing: 10) { + Text("Flex", font: .boldSystemFont(ofSize: 20)).size(width: .fill) + Text("single flex").size(width: .fill) + Flow() { + Box(1) + Box(2).flex() + Box(3) + }.inset(10).styleColor(.systemGroupedBackground) + Text("2 flex").size(width: .fill) + Flow() { + Box(1) + Box(2).flex() + Box(3).flex() + Box(4) + }.inset(10).styleColor(.systemGroupedBackground) + Text("2 flex on 1st line").size(width: .fill) + Flow { + Box(1) + Box(2).flex() + Box(3).flex() + Box(4) + }.size(width: 190).inset(10).styleColor(.systemGroupedBackground) + Text("2 flex on 2nd line").size(width: .fill) + Flow { + Box(1) + Box(2) + Box(3) + Box(4).flex() + Box(5).flex() + }.size(width: 190).inset(10).styleColor(.systemGroupedBackground) + } + }.inset(20) } - - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ - } diff --git a/Examples/UIComponentExample/Examples/Flow/FlowViewController.swift b/Examples/UIComponentExample/Examples/Flow/FlowViewController.swift deleted file mode 100644 index 0521431e..00000000 --- a/Examples/UIComponentExample/Examples/Flow/FlowViewController.swift +++ /dev/null @@ -1,94 +0,0 @@ -// -// FlowViewController.swift -// UIComponentExample -// -// Created by Luke Zhao on 7/18/21. -// Copyright © 2021 Luke Zhao. All rights reserved. -// - -import UIComponent -import UIKit - -private struct FlowItem: ComponentBuilder { - let size: CGSize - func build() -> Component { - Space(size: size).view().backgroundColor(.systemBlue.withAlphaComponent(0.2)).with(\.layer.cornerRadius, 8).with(\.layer.borderColor, UIColor.systemBlue.cgColor).with(\.layer.borderWidth, 2) - } -} - -class FlowViewController: ComponentViewController { - override var component: Component { - VStack(spacing: 50) { - VStack(spacing: 10) { - Text("Justify Content", font: UIFont.boldSystemFont(ofSize: 20)).size(width: .fill) - for justifyContent in MainAxisAlignment.allCases { - Text("\(justifyContent)").size(width: .fill) - Flow(justifyContent: justifyContent) { - for _ in 0..<10 { - FlowItem(size: CGSize(width: 50, height: 50)) - } - } - } - } - - VStack(spacing: 10) { - Text("Align Items", font: UIFont.boldSystemFont(ofSize: 20)).size(width: .fill) - for alignItems in CrossAxisAlignment.allCases { - Text("\(alignItems)").size(width: .fill) - Flow(alignItems: alignItems) { - for i in 0..<10 { - FlowItem(size: CGSize(width: 50, height: 50 + (i % 4) * 10)) - } - } - } - } - - VStack(spacing: 10) { - Text("Align Content", font: UIFont.boldSystemFont(ofSize: 20)).size(width: .fill) - for alignContent in MainAxisAlignment.allCases { - Text("\(alignContent)").size(width: .fill) - Flow(alignContent: alignContent) { - for _ in 0..<10 { - FlowItem(size: CGSize(width: 50, height: 50)) - } - }.size(height: 150).view().backgroundColor(.systemBlue.withAlphaComponent(0.2)) - } - } - - - VStack(spacing: 10) { - Text("Flex", font: UIFont.boldSystemFont(ofSize: 20)).size(width: .fill) - Text("single flex").size(width: .fill) - Flow() { - FlowItem(size: CGSize(width: 50, height: 50)) - FlowItem(size: CGSize(width: 50, height: 50)).flex() - FlowItem(size: CGSize(width: 50, height: 50)) - } - Text("2 flex").size(width: .fill) - Flow() { - FlowItem(size: CGSize(width: 50, height: 50)) - FlowItem(size: CGSize(width: 50, height: 50)).flex() - FlowItem(size: CGSize(width: 50, height: 50)).flex() - FlowItem(size: CGSize(width: 50, height: 50)) - } - Text("2 flex on 1st line").size(width: .fill) - Flow { - FlowItem(size: CGSize(width: 50, height: 50)) - FlowItem(size: CGSize(width: 50, height: 50)).flex() - FlowItem(size: CGSize(width: 50, height: 50)).flex() - FlowItem(size: CGSize(width: 50, height: 50)) - }.size(width: 190).view().backgroundColor(.systemBlue.withAlphaComponent(0.2)) - Text("2 flex on 2nd line").size(width: .fill) - Flow { - FlowItem(size: CGSize(width: 50, height: 50)) - FlowItem(size: CGSize(width: 50, height: 50)) - FlowItem(size: CGSize(width: 50, height: 50)) - FlowItem(size: CGSize(width: 50, height: 50)).flex() - FlowItem(size: CGSize(width: 50, height: 50)).flex() - }.size(width: 190).view().backgroundColor(.systemBlue.withAlphaComponent(0.2)) - } - }.inset(20) - } -} - - diff --git a/Examples/UIComponentExample/ViewController.swift b/Examples/UIComponentExample/ViewController.swift index c20609c8..43305bce 100644 --- a/Examples/UIComponentExample/ViewController.swift +++ b/Examples/UIComponentExample/ViewController.swift @@ -18,7 +18,6 @@ class ViewController: ComponentViewController { ExampleItem(name: "Card Example 3", viewController: CardViewController3()) ExampleItem(name: "AsyncImage Example", viewController: UINavigationController(rootViewController: AsyncImageViewController())) ExampleItem(name: "Tab Bar Example", viewController: TabBarViewController()) - ExampleItem(name: "Flow Example", viewController: FlowViewController()) ExampleItem(name: "Flex Layout Example", viewController: FlexLayoutViewController()) } separator: { Separator() diff --git a/Sources/UIComponent/Components/FlexColumn.swift b/Sources/UIComponent/Components/FlexColumn.swift new file mode 100644 index 00000000..11407b1e --- /dev/null +++ b/Sources/UIComponent/Components/FlexColumn.swift @@ -0,0 +1,36 @@ +// +// FlexColumn.swift +// +// +// Created by Luke Zhao on 7/18/21. +// + +import UIKit + +public struct FlexColumn: FlexLayoutComponent, HorizontalLayoutProtocol { + public var lineSpacing: CGFloat + public var interitemSpacing: CGFloat + + public var alignContent: MainAxisAlignment + public var alignItems: CrossAxisAlignment + public var justifyContent: MainAxisAlignment + public var tailJustifyContent: MainAxisAlignment? + public var children: [Component] + + public init(lineSpacing: CGFloat = 0, + interitemSpacing: CGFloat = 0, + justifyContent: MainAxisAlignment = .start, + alignItems: CrossAxisAlignment = .start, + alignContent: MainAxisAlignment = .start, + tailJustifyContent: MainAxisAlignment? = nil, + children: [Component]) { + self.lineSpacing = lineSpacing + self.interitemSpacing = interitemSpacing + self.justifyContent = justifyContent + self.alignItems = alignItems + self.alignContent = alignContent + self.tailJustifyContent = tailJustifyContent + self.children = children + } +} + diff --git a/Sources/UIComponent/Components/Flow.swift b/Sources/UIComponent/Components/FlexLayout.swift similarity index 75% rename from Sources/UIComponent/Components/Flow.swift rename to Sources/UIComponent/Components/FlexLayout.swift index b3d18ed0..6e8ba0d6 100644 --- a/Sources/UIComponent/Components/Flow.swift +++ b/Sources/UIComponent/Components/FlexLayout.swift @@ -7,42 +7,45 @@ import UIKit -public struct Flow: Component, VerticalLayoutProtocol { - public var lineSpacing: CGFloat - public var interitemSpacing: CGFloat - - public var alignContent: MainAxisAlignment - public var alignItems: CrossAxisAlignment - public var justifyContent: MainAxisAlignment - public var children: [Component] +public protocol FlexLayoutComponent: Component, BaseLayoutProtocol { + var lineSpacing: CGFloat { get } + var interitemSpacing: CGFloat { get } + var justifyContent: MainAxisAlignment { get } + var alignItems: CrossAxisAlignment { get } + var alignContent: MainAxisAlignment { get } + var tailJustifyContent: MainAxisAlignment? { get } + var children: [Component] { get } + + init(lineSpacing: CGFloat, + interitemSpacing: CGFloat, + justifyContent: MainAxisAlignment, + alignItems: CrossAxisAlignment, + alignContent: MainAxisAlignment, + tailJustifyContent: MainAxisAlignment?, + children: [Component]) +} - public init(lineSpacing: CGFloat = 0, - interitemSpacing: CGFloat = 0, - justifyContent: MainAxisAlignment = .start, - alignItems: CrossAxisAlignment = .start, - alignContent: MainAxisAlignment = .start, - children: [Component]) { - self.lineSpacing = lineSpacing - self.interitemSpacing = interitemSpacing - self.justifyContent = justifyContent - self.alignItems = alignItems - self.alignContent = alignContent - self.children = children +public extension FlexLayoutComponent { + init(lineSpacing: CGFloat = 0, + interitemSpacing: CGFloat = 0, + justifyContent: MainAxisAlignment = .start, + alignItems: CrossAxisAlignment = .start, + alignContent: MainAxisAlignment = .start, + tailJustifyContent: MainAxisAlignment? = nil, + @ComponentArrayBuilder _ content: () -> [Component]) { + self.init(lineSpacing: lineSpacing, interitemSpacing: interitemSpacing, justifyContent: justifyContent, alignItems: alignItems, alignContent: alignContent, tailJustifyContent: tailJustifyContent, children: content()) } - - public init(spacing: CGFloat, - justifyContent: MainAxisAlignment = .start, - alignItems: CrossAxisAlignment = .start, - alignContent: MainAxisAlignment = .start, - children: [Component]) { - self.init(lineSpacing: spacing, - interitemSpacing: spacing, - justifyContent: justifyContent, - alignItems: alignItems, - alignContent: alignContent, - children: children) + init(spacing: CGFloat = 0, + justifyContent: MainAxisAlignment = .start, + alignItems: CrossAxisAlignment = .start, + alignContent: MainAxisAlignment = .start, + tailJustifyContent: MainAxisAlignment? = nil, + @ComponentArrayBuilder _ content: () -> [Component]) { + self.init(lineSpacing: spacing, interitemSpacing: spacing, justifyContent: justifyContent, alignItems: alignItems, alignContent: alignContent, tailJustifyContent: tailJustifyContent, children: content()) } - +} + +extension FlexLayoutComponent { public func layout(_ constraint: Constraint) -> Renderer { let crossMax = cross(constraint.maxSize) let childConstraint = Constraint(minSize: .zero, maxSize: size(main: .infinity, cross: crossMax)) @@ -108,7 +111,9 @@ public struct Flow: Component, VerticalLayoutProtocol { } // distribute on the cross axis - var (crossOffset, crossSpacing) = LayoutHelper.distribute(justifyContent: justifyContent, + let isLastLine = range.upperBound >= children.count + let lineJustifyContent = isLastLine ? tailJustifyContent ?? justifyContent : justifyContent + var (crossOffset, crossSpacing) = LayoutHelper.distribute(justifyContent: lineJustifyContent, maxPrimary: crossMax, totalPrimary: cross(lineSize), minimunSpacing: interitemSpacing, @@ -146,31 +151,3 @@ public struct Flow: Component, VerticalLayoutProtocol { return renderer(size: finalSize, children: renderers, positions: positions) } } - - -public extension Flow { - init(spacing: CGFloat = 0, justifyContent: MainAxisAlignment = .start, alignItems: CrossAxisAlignment = .start, @ComponentArrayBuilder _ content: () -> [Component]) { - self.init(spacing: spacing, - justifyContent: justifyContent, - alignItems: alignItems, - children: content()) - } -} - -public extension Flow { - init(lineSpacing: CGFloat = 0, - interitemSpacing: CGFloat = 0, - justifyContent: MainAxisAlignment = .start, - alignItems: CrossAxisAlignment = .start, - alignContent: MainAxisAlignment = .start, - @ComponentArrayBuilder _ content: () -> [Component]) { - self.init(lineSpacing: lineSpacing, interitemSpacing: interitemSpacing, justifyContent: justifyContent, alignItems: alignItems, alignContent: alignContent, children: content()) - } - init(spacing: CGFloat = 0, - justifyContent: MainAxisAlignment = .start, - alignItems: CrossAxisAlignment = .start, - alignContent: MainAxisAlignment = .start, - @ComponentArrayBuilder _ content: () -> [Component]) { - self.init(spacing: spacing, justifyContent: justifyContent, alignItems: alignItems, alignContent: alignContent, children: content()) - } -} diff --git a/Sources/UIComponent/Components/FlexRow.swift b/Sources/UIComponent/Components/FlexRow.swift new file mode 100644 index 00000000..7d6d0f05 --- /dev/null +++ b/Sources/UIComponent/Components/FlexRow.swift @@ -0,0 +1,36 @@ +// +// FlexRow.swift +// +// +// Created by Luke Zhao on 7/18/21. +// + +import UIKit + +public typealias Flow = FlexRow +public struct FlexRow: FlexLayoutComponent, VerticalLayoutProtocol { + public var lineSpacing: CGFloat + public var interitemSpacing: CGFloat + + public var alignContent: MainAxisAlignment + public var alignItems: CrossAxisAlignment + public var justifyContent: MainAxisAlignment + public var tailJustifyContent: MainAxisAlignment? + public var children: [Component] + + public init(lineSpacing: CGFloat = 0, + interitemSpacing: CGFloat = 0, + justifyContent: MainAxisAlignment = .start, + alignItems: CrossAxisAlignment = .start, + alignContent: MainAxisAlignment = .start, + tailJustifyContent: MainAxisAlignment? = nil, + children: [Component]) { + self.lineSpacing = lineSpacing + self.interitemSpacing = interitemSpacing + self.justifyContent = justifyContent + self.alignItems = alignItems + self.alignContent = alignContent + self.tailJustifyContent = tailJustifyContent + self.children = children + } +}