A SwiftUI-inspired framework for building interactive command-line applications in Swift. This framework provides a declarative, reactive approach to creating terminal-based user interfaces with familiar SwiftUI concepts.
- SwiftUI-like Syntax: Use familiar
@State
,@Environment
, and view modifiers - Interactive Controls: Buttons, text fields, and other interactive elements
- Layout System: VStack, HStack, and other layout containers
- Styling: Colors, padding, borders, and text formatting
- Event Handling: Keyboard input and focus management
- Cross-platform: Works on macOS and Linux
- Swift 6.1+
- macOS 12.0+ or Linux
Add this package to your Package.swift
:
dependencies: [
.package(url: "https://github.com/pelagornis/swift-cli.git", from: "0.1.0")
]
import CommandLine
struct ContentView: View {
@State private var count = 0
var body: some View {
VStack(spacing: 1) {
Text("Counter: \(count)")
.foregroundColor(.green)
.bold()
HStack {
Button("Increment") {
count += 1
}
Button("Decrement") {
count -= 1
}
}
}
.padding()
.border()
}
}
Application(rootView: ContentView()).start()
Views are the building blocks of your UI. The framework provides several view types:
Text("Hello, World!")
.foregroundColor(.blue)
.bold()
.italic()
Button("Click me") {
print("Button pressed!")
}
// With custom label
Button(action: { /* action */ }) {
HStack {
Text("Custom")
Text("Button")
}
}
TextField { input in
print("User entered: \(input)")
}
VStack(spacing: 1) {
Text("First item")
Text("Second item")
Text("Third item")
}
HStack {
Text("Left")
Spacer()
Text("Right")
}
struct MyView: View {
@State private var isVisible = false
@State private var counter = 0
var body: some View {
VStack {
if isVisible {
Text("Counter: \(counter)")
}
Button("Toggle") {
isVisible.toggle()
counter += 1
}
}
}
}
struct MyView: View {
@Environment(\.foregroundColor) private var textColor
var body: some View {
Text("This text uses the environment color")
.foregroundColor(textColor)
}
}
Apply modifiers to customize the appearance and behavior of views:
Text("Styled Text")
.foregroundColor(.red)
.bold()
.italic()
.underline()
.padding(2)
.border()
.background(.blue)
- Text Formatting:
.bold()
,.italic()
,.underline()
,.strikethrough()
- Colors:
.foregroundColor()
,.background()
- Layout:
.padding()
,.border()
,.fixedFrame()
,.flexibleFrame()
- Environment:
.setEnvironment()
import CommandLine
@MainActor
class MyApp {
static func main() {
Application(rootView: ContentView()).start()
}
}
Create custom interactive controls by conforming to the Control
protocol:
struct CustomControl: View, PrimitiveView {
var body: some View {
// Your custom implementation
}
func buildNode(_ node: Node) {
// Setup your control
}
}
Handle keyboard events and focus management:
Button("Interactive") {
// Action when button is pressed
} hover: {
// Action when button is hovered
}
Use colors and styling to create rich interfaces:
VStack {
Text("Success")
.foregroundColor(.green)
Text("Warning")
.foregroundColor(.yellow)
Text("Error")
.foregroundColor(.red)
}
.padding()
.border()
.background(.blue)
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack(spacing: 1) {
Text("Count: \(count)")
.bold()
HStack {
Button("-") { count -= 1 }
Button("+") { count += 1 }
}
}
.padding()
.border()
}
}
struct FormView: View {
@State private var name = ""
@State private var email = ""
var body: some View {
VStack(spacing: 1) {
Text("Registration Form")
.bold()
.foregroundColor(.blue)
HStack {
Text("Name:")
TextField { name = $0 }
}
HStack {
Text("Email:")
TextField { email = $0 }
}
Button("Submit") {
print("Name: \(name), Email: \(email)")
}
}
.padding()
.border()
}
}
Contributions are welcome! Please feel free to submit a Pull Request.
swift-cli is under MIT license. See the LICENSE file for more info.