- Add ButtonRole (.cancel, .destructive) with SwiftUI-conformant API
- Alert renders buttons horizontally, sorted by role (cancel left)
- Alert max width capped at 60 characters for readability
- ESC key dismisses alerts via AlertPresentationModifier handler
- FocusManager: Left/Right arrows navigate within sections (like Up/Down)
- Move completed plans to done/ directory
- Update example pages with minor adjustments
Add @MainActor to View, ViewModifier, Renderable, App, Scene protocols and all builders (ViewBuilder, SceneBuilder, ChildInfoProvider). Update renderToBuffer(), makeChildInfo(), resolveChildInfos() for main-actor isolation. Mark generic Equatable conformances with @preconcurrency. Update all 45 test suites with @MainActor annotation.
Update IDETemplateMacros.plist and replace headers in 136 Swift files with
new format: 🖥️ TUIKit — Terminal UI Kit for Swift. Remove sdsd.swift template draft.
The FocusManager has a singleton defaultValue that persists across tests,
causing test-order dependencies. Button instances register with the global
FocusManager on render, polluting later tests that expect a fresh manager.
Changed tests to use Text instead of Button for action content, eliminating
the focus registration side-effect while still testing the presentation API.
This fixes the CI failure on macOS where 'Default FocusManager is provided
if not set' failed due to a previous test rendering buttons.
- Add AlertPresentationModifier with Binding<Bool> support
- Add ModalPresentationModifier for custom modal content
- Add View+Presentation.swift with .alert() and .modal(isPresented:) extensions
- Update OverlaysPage to demonstrate new declarative presentation API
- Add comprehensive tests for both presentation modifiers (13 tests)
- Follows SwiftUI API parity rule: same naming, parameter order, and behavior
The new API eliminates manual if/else branching for modals:
Before:
if showModal {
content.dimmed().overlay { AlertView() }
} else {
content
}
After:
content.alert("Title", isPresented: $showModal) {
Button("OK") { showModal = false }
}
This mirrors SwiftUI's .alert(isPresented:) and .sheet(isPresented:) patterns.