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
78 lines
2.6 KiB
Swift
78 lines
2.6 KiB
Swift
// 🖥️ TUIKit — Terminal UI Kit for Swift
|
||
// RadioButtonPage.swift
|
||
//
|
||
// Created by LAYERED.work
|
||
// License: MIT
|
||
|
||
import TUIkit
|
||
|
||
/// Radio button group demo page.
|
||
///
|
||
/// Shows interactive radio button features including:
|
||
/// - Vertical layout (default)
|
||
/// - Horizontal layout
|
||
/// - Single-selection with binding
|
||
/// - Disabled radio groups
|
||
/// - Focus navigation with arrow keys
|
||
/// - Live state changes demonstrating `@State` persistence across re-renders
|
||
struct RadioButtonPage: View {
|
||
@State var colorChoice: String = "blue"
|
||
@State var sizeChoice: String = "medium"
|
||
@State var layoutChoice: String = "vertical"
|
||
|
||
var body: some View {
|
||
VStack(alignment: .leading, spacing: 1) {
|
||
|
||
DemoSection("Color Selection (Vertical)") {
|
||
RadioButtonGroup(selection: $colorChoice) {
|
||
RadioButtonItem("red", "Red")
|
||
RadioButtonItem("green", "Green")
|
||
RadioButtonItem("blue", "Blue")
|
||
RadioButtonItem("yellow", "Yellow")
|
||
}
|
||
}
|
||
|
||
DemoSection("Size Selection (Vertical)") {
|
||
RadioButtonGroup(selection: $sizeChoice) {
|
||
RadioButtonItem("small", "Small")
|
||
RadioButtonItem("medium", "Medium")
|
||
RadioButtonItem("large", "Large")
|
||
}
|
||
}
|
||
|
||
DemoSection("Layout Style (Horizontal)") {
|
||
RadioButtonGroup(selection: $layoutChoice, orientation: .horizontal) {
|
||
RadioButtonItem("vertical", "Vertical")
|
||
RadioButtonItem("horizontal", "Horizontal")
|
||
}
|
||
}
|
||
|
||
DemoSection("Disabled Group") {
|
||
RadioButtonGroup(selection: Binding(get: { "disabled" }, set: { _ in })) {
|
||
RadioButtonItem("disabled", "This group is disabled")
|
||
}
|
||
.disabled()
|
||
}
|
||
|
||
DemoSection("Current Selections") {
|
||
VStack(alignment: .leading, spacing: 1) {
|
||
ValueDisplayRow("Color:", colorChoice)
|
||
ValueDisplayRow("Size:", sizeChoice)
|
||
ValueDisplayRow("Layout:", layoutChoice)
|
||
}
|
||
}
|
||
|
||
KeyboardHelpSection("Focus Navigation", shortcuts: [
|
||
"Use [↑/↓] to navigate vertically",
|
||
"Use [←/→] to navigate horizontally",
|
||
"Use [Enter] or [Space] to select",
|
||
])
|
||
|
||
Spacer()
|
||
}
|
||
.appHeader {
|
||
DemoAppHeader("Radio Buttons Demo")
|
||
}
|
||
}
|
||
}
|