space-code/flex-ui
## Description
Description
FlexUI is a lightweight Swift framework that provides an elegant, chainable API for configuring UIKit components. Write cleaner, more readable UI code with a fluent interface that makes view configuration a breeze.
Features
β¨ Chainable Configuration - Fluent API for setting up UI components π― Type-Safe - Leverages Swift's type system for compile-time safety π§ Extensible - Easy to add custom configuration methods π± UIKit Native - Works seamlessly with all UIKit components β‘ Lightweight - Minimal footprint with zero dependencies
Table of Contents
Requirements
| Platform | Minimum Version | |-----------|----------------| | iOS | 13.0+ | | macOS | 10.15+ | | watchOS | 7.0+ | | tvOS | 13+ | | visionOS | 1.0 | | Xcode | 15.3+ | | Swift | 5.10+ |
Installation
Swift Package Manager
Add the following dependency to your Package.swift:
dependencies: [
.package(url: "https://github.com/space-code/flex-ui.git", from: "1.5.0")
]Or add it through Xcode:
- File > Add Package Dependencies
- Enter package URL:
https://github.com/space-code/flex-ui.git - Select version requirements
Quick Start
import FlexUI
let label = UILabel()
.flex
.text("Hello, FlexUI!")
.textColor(.systemBlue)
.font(.systemFont(ofSize: 17.0))
.textAlignment(.center)Usage
Basic Configuration
FlexUI provides a .flex property on UIKit components that enables chainable configuration:
import FlexUI
// Configure a UILabel
let titleLabel = UILabel()
.flex
.text("Welcome")
.textColor(.black)
.font(.boldSystemFont(ofSize: 24))
.numberOfLines(0)
// Configure a UIButton
let actionButton = UIButton()
.flex
.title("Tap Me", for: .normal)
.backgroundColor(.systemBlue)
.cornerRadius(8)
.tintColor(.white)
// Configure a UIImageView
let imageView = UIImageView()
.flex
.image(UIImage(named: "logo"))
.contentMode(.scaleAspectFit)
.clipsToBounds(true)Extending FlexUI
Create custom configuration methods by extending the FlexUI interface:
import FlexUI
import UIKit
// Define custom font styles
public enum Fonts {
public enum Headings {
case h1
case h2
case h3
var font: UIFont {
switch self {
case .h1: return .boldSystemFont(ofSize: 32)
case .h2: return .boldSystemFont(ofSize: 24)
case .h3: return .boldSystemFont(ofSize: 18)
}
}
}
}
// Extend FlexUI for UILabel
public extension FlexUI where Component: UILabel {
@discardableResult
@MainActor
func heading(_ style: Fonts.Headings) -> Self {
component.font = style.font
return self
}
}
// Usage
let heading = UILabel()
.flex
.text("Article Title")
.heading(.h1)
.textColor(.black)Custom Button Styles:
public extension FlexUI where Component: UIButton {
@discardableResult
@MainActor
func primaryStyle() -> Self {
component.backgroundColor = .systemBlue
component.setTitleColor(.white, for: .normal)
component.layer.cornerRadius = 8
component.titleLabel?.font = .boldSystemFont(ofSize: 16)
return self
}
}
// Usage
let button = UIButton()
.flex
.title("Submit", for: .normal)
.primaryStyle()Common Use Cases
View Hierarchy Setup
import FlexUI
class ProfileViewController: UIViewController {
private let avatarImageView = UIImageView()
.flex
.contentMode(.scaleAspectFill)
.clipsToBounds(true)
.cornerRadius(50)
private let nameLabel = UILabel()
.flex
.font(.boldSystemFont(ofSize: 20))
.textAlignment(.center)
private let bioLabel = UILabel()
.flex
.font(.systemFont(ofSize: 14))
.textColor(.secondaryLabel)
.numberOfLines(0)
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
}Dynamic Configuration
import FlexUI
func configureCell(_ cell: UITableViewCell, isSelected: Bool) {
cell.textLabel?
.flex
.textColor(isSelected ? .systemBlue : .label)
.font(isSelected ? .boldSystemFont(ofSize: 16) : .systemFont(ofSize: 16))
}Reusable Components
import FlexUI
class CustomButton: UIButton {
convenience init(style: ButtonStyle) {
self.init(type: .system)
applyStyle(style)
}
private func applyStyle(_ style: ButtonStyle) {
switch style {
case .primary:
flex
.backgroundColor(.systemBlue)
.cornerRadius(8)
.setTitleColor(.white, for: .normal)
case .secondary:
flex
.backgroundColor(.systemGray5)
.cornerRadius(8)
.setTitleColor(.label, for: .normal)
}
}
}Communication
- π Found a bug? Open an issue
- π‘ Have a feature request? Open an issue
- β Questions? Start a discussion
- π€ Want to contribute? Submit a pull request
Contributing
We love contributions! Please feel free to help out with this project. If you see something that could be made better or want a new feature, open up an issue or send a Pull Request.
Development Setup
Bootstrap the development environment:
mise installLicense
FlexUI is released under the MIT license. See LICENSE for details.
<div align="center">
Made with β€οΈ by space-code
</div>
Package Metadata
Repository: space-code/flex-ui
Default branch: main
README: README.md