philiprehberger/swift-form-kit
Declarative form builder with validation rules, result builder DSL, and dynamic JSON forms
Requirements
- Swift >= 6.0
- macOS 13+ / iOS 16+ / tvOS 16+ / watchOS 9+
Installation
Add to your Package.swift:
dependencies: [
.package(url: "https://github.com/philiprehberger/swift-form-kit.git", from: "0.1.0")
]Then add "FormKit" to your target dependencies:
.target(name: "YourTarget", dependencies: [
.product(name: "FormKit", package: "swift-form-kit")
])Usage
import FormKit
// Build a form with the DSL
let section = FormSection(title: "Profile") {
FormTextField(id: "name", label: "Full Name", validation: [.required()])
FormTextField(id: "email", label: "Email", validation: [.required(), .email()])
FormNumberField(id: "age", label: "Age", validation: [.range(18...120)])
FormToggleField(id: "newsletter", label: "Subscribe to newsletter")
}
let model = FormModel(sections: [section])Validation
// Built-in rules
FormTextField(id: "password", label: "Password", validation: [
.required(),
.minLength(8),
.maxLength(100),
.pattern(".*[A-Z].*", message: "Must contain an uppercase letter")
])
// Custom rule
FormTextField(id: "username", label: "Username", validation: [
.custom(message: "Must start with a letter") { value in
guard let str = value as? String else { return false }
return str.first?.isLetter ?? false
}
])
// Validate all fields
let isValid = model.validate()
let errors = model.errors // ["password": ["Must be at least 8 characters"]]Dynamic Forms from JSON
let json = """
[{"title": "Contact", "fields": [
{"id": "name", "type": "text", "label": "Name", "required": true},
{"id": "age", "type": "number", "label": "Age"}
]}]
""".data(using: .utf8)!
let sections = try DynamicForm.from(json: json)
let model = FormModel(sections: sections)SwiftUI Rendering
struct ProfileForm: View {
@State private var model = FormModel(sections: profileSections)
var body: some View {
FormView(model: model)
Button("Submit") { if model.validate() { submit() } }
.disabled(!model.isValid)
}
}API
FormModel
| Property/Method | Description | |-----------------|-------------| | values | Current form values keyed by field ID | | errors | Validation errors keyed by field ID | | isValid | Whether all fields pass validation | | setValue(_:for:) | Set a value for a field | | validate() | Validate all fields | | validate(fieldId:) | Validate a single field | | reset() | Reset form to initial values |
ValidationRule
| Static Method | Description | |---------------|-------------| | .required() | Field must not be empty | | .minLength(:) | Minimum string length | | .maxLength(:) | Maximum string length | | .pattern(:message:) | Regex pattern match | | .email() | Valid email format | | .range(:) | Number within range | | .custom(message:_:) | Custom validation closure |
Field Types
| Type | Description | |------|-------------| | FormTextField | Text input field | | FormNumberField | Numeric input field | | FormToggleField | Boolean toggle | | FormPickerField | Selection from options | | FormDateField | Date picker |
Development
swift build
swift testSupport
💬 Bluesky · 🐦 X · 💼 LinkedIn · 🌐 Website · 📦 GitHub · ☕ Buy Me a Coffee · ❤️ GitHub Sponsors
License
Package Metadata
Repository: philiprehberger/swift-form-kit
Default branch: main
README: README.md