mirror of
https://github.com/phranck/TUIkit.git
synced 2026-05-21 09:50:35 +00:00
5ad97132b8
- Replace custom Observable protocol and @Published with Apple's @Observable macro - Add withObservationTracking in renderToBuffer for automatic per-property dependency tracking - Add type-based @Environment(Type.self) and .environment(object) for observable objects - Add ObjectEnvironmentModifier for injecting observable objects into the environment - Add needsCacheClear flag to AppState for thread-safe cache invalidation - Add cross-platform test script (scripts/test-linux.sh) for Docker-based Linux verification - Add DemoAppHeader with system info display (OS, version, architecture) - Consolidate Example App: extract ImageDemoHelpers, KeyboardHelpSection, ValueDisplayRow - Add pre-push verification rule to CLAUDE.md - Verified on both macOS and Linux (swift:6.0 container), 1155 tests passing
92 lines
3.1 KiB
Swift
92 lines
3.1 KiB
Swift
// TUIKit - Terminal UI Kit for Swift
|
|
// StepperPage.swift
|
|
//
|
|
// Created by LAYERED.work
|
|
// License: MIT
|
|
|
|
import TUIkit
|
|
|
|
/// Stepper demo page.
|
|
///
|
|
/// Shows interactive stepper features including:
|
|
/// - Basic value stepping
|
|
/// - Range constraints
|
|
/// - Custom step sizes
|
|
/// - Custom callbacks
|
|
/// - Keyboard controls
|
|
struct StepperPage: View {
|
|
@State var quantity: Int = 1
|
|
@State var rating: Int = 3
|
|
@State var volume: Int = 50
|
|
@State var colorIndex: Int = 0
|
|
|
|
let colors = ["Red", "Green", "Blue", "Yellow", "Purple"]
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 1) {
|
|
|
|
DemoSection("Basic Stepper") {
|
|
VStack(alignment: .leading, spacing: 1) {
|
|
HStack(spacing: 1) {
|
|
Text("Quantity:").foregroundStyle(.palette.foregroundSecondary)
|
|
Stepper("Quantity", value: $quantity)
|
|
}
|
|
}
|
|
}
|
|
|
|
DemoSection("With Range Constraints") {
|
|
VStack(alignment: .leading, spacing: 1) {
|
|
HStack(spacing: 1) {
|
|
Text("Rating (1-5):").foregroundStyle(.palette.foregroundSecondary)
|
|
Stepper("Rating", value: $rating, in: 1...5)
|
|
}
|
|
HStack(spacing: 1) {
|
|
Text("Volume (0-100, step 10):").foregroundStyle(.palette.foregroundSecondary)
|
|
Stepper("Volume", value: $volume, in: 0...100, step: 10)
|
|
}
|
|
}
|
|
}
|
|
|
|
DemoSection("With Custom Callbacks") {
|
|
VStack(alignment: .leading, spacing: 1) {
|
|
HStack(spacing: 1) {
|
|
Text("Color:").foregroundStyle(.palette.foregroundSecondary)
|
|
Stepper(
|
|
"Color",
|
|
onIncrement: {
|
|
colorIndex = (colorIndex + 1) % colors.count
|
|
},
|
|
onDecrement: {
|
|
colorIndex = (colorIndex - 1 + colors.count) % colors.count
|
|
}
|
|
)
|
|
Text(colors[colorIndex]).foregroundStyle(.palette.accent)
|
|
}
|
|
}
|
|
}
|
|
|
|
DemoSection("Current Values") {
|
|
VStack(alignment: .leading, spacing: 1) {
|
|
ValueDisplayRow("Quantity:", "\(quantity)")
|
|
ValueDisplayRow("Rating:", "\(rating)")
|
|
ValueDisplayRow("Volume:", "\(volume)")
|
|
ValueDisplayRow("Color:", colors[colorIndex])
|
|
}
|
|
}
|
|
|
|
KeyboardHelpSection(shortcuts: [
|
|
"[<-] [->] Decrease/Increase by step",
|
|
"[-] [+] Decrease/Increase by step",
|
|
"[Home] Jump to minimum (if range defined)",
|
|
"[End] Jump to maximum (if range defined)",
|
|
"[Tab] Move to next stepper",
|
|
])
|
|
|
|
Spacer()
|
|
}
|
|
.appHeader {
|
|
DemoAppHeader("Stepper Demo")
|
|
}
|
|
}
|
|
}
|