From a53c1a07fd96dcd351b4ff81c8ca345e4bf9b6a8 Mon Sep 17 00:00:00 2001 From: phranck Date: Wed, 28 Jan 2026 19:08:50 +0100 Subject: [PATCH] refactor: Remove T prefix from all public types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename TView → View, TApp → App, TScene → Scene - Rename TState → State, TViewBuilder → ViewBuilder - Rename TViewModifier → ViewModifier, TViewArray → ViewArray - Rename TStatusBar* → StatusBar* (Item, Style, Alignment, Protocol) - Add Theme system with 8 predefined themes (Phosphor, ncurses, Dark, Light) - Add Color extensions: hex string, HSL, lighter/darker/opacity - Update all files, example app, and tests for new names --- .../SwiftTUI/App/{TApp.swift => App.swift} | 62 +- .../App/{TScene.swift => Scene.swift} | 10 +- Sources/SwiftTUI/Core/AppStorage.swift | 8 +- Sources/SwiftTUI/Core/Color.swift | 118 ++++ Sources/SwiftTUI/Core/Environment.swift | 16 +- Sources/SwiftTUI/Core/Preferences.swift | 16 +- Sources/SwiftTUI/Core/PrimitiveViews.swift | 30 +- Sources/SwiftTUI/Core/State.swift | 18 +- Sources/SwiftTUI/Core/Theme.swift | 574 ++++++++++++++++++ Sources/SwiftTUI/Core/TupleViews.swift | 18 +- .../SwiftTUI/Core/{TView.swift => View.swift} | 18 +- .../{TViewBuilder.swift => ViewBuilder.swift} | 44 +- Sources/SwiftTUI/Core/ViewModifier.swift | 14 +- .../Modifiers/BackgroundModifier.swift | 6 +- .../SwiftTUI/Modifiers/BorderModifier.swift | 12 +- .../SwiftTUI/Modifiers/DimmedModifier.swift | 8 +- .../SwiftTUI/Modifiers/FrameModifier.swift | 10 +- .../SwiftTUI/Modifiers/KeyPressModifier.swift | 8 +- .../Modifiers/LifecycleModifier.swift | 28 +- .../SwiftTUI/Modifiers/OverlayModifier.swift | 12 +- .../SwiftTUI/Modifiers/PaddingModifier.swift | 6 +- .../Modifiers/StatusBarItemsModifier.swift | 54 +- Sources/SwiftTUI/Rendering/Renderable.swift | 4 +- Sources/SwiftTUI/Rendering/ViewRenderer.swift | 16 +- Sources/SwiftTUI/SwiftTUI.swift | 4 +- Sources/SwiftTUI/Views/Alert.swift | 22 +- Sources/SwiftTUI/Views/Box.swift | 6 +- Sources/SwiftTUI/Views/Button.swift | 4 +- Sources/SwiftTUI/Views/Card.swift | 6 +- Sources/SwiftTUI/Views/Dialog.swift | 22 +- Sources/SwiftTUI/Views/ForEach.swift | 8 +- Sources/SwiftTUI/Views/Menu.swift | 14 +- Sources/SwiftTUI/Views/Panel.swift | 4 +- Sources/SwiftTUI/Views/Spacer.swift | 4 +- Sources/SwiftTUI/Views/Stacks.swift | 12 +- Sources/SwiftTUI/Views/StatusBar.swift | 72 +-- Sources/SwiftTUI/Views/Text.swift | 2 +- .../Components/DemoSection.swift | 6 +- .../Components/HeaderView.swift | 4 +- Sources/SwiftTUIExample/ContentView.swift | 24 +- .../SwiftTUIExample/Pages/ButtonsPage.swift | 4 +- .../SwiftTUIExample/Pages/ColorsPage.swift | 4 +- .../Pages/ContainersPage.swift | 4 +- .../SwiftTUIExample/Pages/LayoutPage.swift | 4 +- .../SwiftTUIExample/Pages/MainMenuPage.swift | 6 +- .../SwiftTUIExample/Pages/OverlaysPage.swift | 6 +- .../Pages/TextStylesPage.swift | 4 +- Sources/SwiftTUIExample/main.swift | 4 +- Tests/SwiftTUITests/RenderingTests.swift | 4 +- Tests/SwiftTUITests/StatusBarTests.swift | 256 ++++---- Tests/SwiftTUITests/TViewTests.swift | 20 +- 51 files changed, 1166 insertions(+), 474 deletions(-) rename Sources/SwiftTUI/App/{TApp.swift => App.swift} (89%) rename Sources/SwiftTUI/App/{TScene.swift => Scene.swift} (78%) create mode 100644 Sources/SwiftTUI/Core/Theme.swift rename Sources/SwiftTUI/Core/{TView.swift => View.swift} (63%) rename Sources/SwiftTUI/Core/{TViewBuilder.swift => ViewBuilder.swift} (66%) diff --git a/Sources/SwiftTUI/App/TApp.swift b/Sources/SwiftTUI/App/App.swift similarity index 89% rename from Sources/SwiftTUI/App/TApp.swift rename to Sources/SwiftTUI/App/App.swift index 88e8896..cc563fc 100644 --- a/Sources/SwiftTUI/App/TApp.swift +++ b/Sources/SwiftTUI/App/App.swift @@ -1,5 +1,5 @@ // -// TApp.swift +// App.swift // SwiftTUI // // The base protocol for SwiftTUI applications. @@ -7,28 +7,28 @@ import Foundation -// MARK: - TApp Protocol +// MARK: - App Protocol /// The base protocol for SwiftTUI applications. /// -/// `TApp` is the entry point for every SwiftTUI application, +/// `App` is the entry point for every SwiftTUI application, /// similar to `App` in SwiftUI. /// /// # Example /// /// ```swift /// @main -/// struct MyApp: TApp { -/// var body: some TScene { +/// struct MyApp: App { +/// var body: some Scene { /// WindowGroup { /// ContentView() /// } /// } /// } /// ``` -public protocol TApp { +public protocol App { /// The type of the main scene. - associatedtype Body: TScene + associatedtype Body: Scene /// The main scene of the app. @SceneBuilder @@ -38,14 +38,14 @@ public protocol TApp { init() } -extension TApp { +extension App { /// Starts the app. /// /// This method is called by the `@main` attribute and starts /// the main run loop of the application. public static func main() { let app = Self() - let runner = AppRunner(app: app) + let runner = AppRunner(app: app) runner.run() } } @@ -60,13 +60,13 @@ extension TApp { /// # Usage /// /// ```swift -/// struct MyView: TView { +/// struct MyView: View { /// @Environment(\.statusBar) var statusBar /// -/// var body: some TView { +/// var body: some View { /// Button("Action") { /// statusBar.setItems([ -/// TStatusBarItem(shortcut: "⎋", label: "cancel") +/// StatusBarItem(shortcut: "⎋", label: "cancel") /// ]) /// } /// } @@ -74,16 +74,16 @@ extension TApp { /// ``` public final class StatusBarState: @unchecked Sendable { /// Stack of contexts with their items. - private var contextStack: [(context: String, items: [any TStatusBarItemProtocol])] = [] + private var contextStack: [(context: String, items: [any StatusBarItemProtocol])] = [] /// Global items that are always shown (lowest priority). - private var globalItems: [any TStatusBarItemProtocol] = [] + private var globalItems: [any StatusBarItemProtocol] = [] /// The current status bar style. - public var style: TStatusBarStyle = .compact + public var style: StatusBarStyle = .compact /// The horizontal alignment of items. - public var alignment: TStatusBarAlignment = .justified + public var alignment: StatusBarAlignment = .justified /// The highlight color for shortcut keys. public var highlightColor: Color = .cyan @@ -102,7 +102,7 @@ public final class StatusBarState: @unchecked Sendable { /// Triggers a re-render. /// /// - Parameter items: The items to display. - public func setItems(_ items: [any TStatusBarItemProtocol]) { + public func setItems(_ items: [any StatusBarItemProtocol]) { globalItems = items AppState.shared.setNeedsRender() } @@ -112,7 +112,7 @@ public final class StatusBarState: @unchecked Sendable { /// Triggers a re-render. /// /// - Parameter builder: A closure that returns items. - public func setItems(@StatusBarItemBuilder _ builder: () -> [any TStatusBarItemProtocol]) { + public func setItems(@StatusBarItemBuilder _ builder: () -> [any StatusBarItemProtocol]) { globalItems = builder() AppState.shared.setNeedsRender() } @@ -122,7 +122,7 @@ public final class StatusBarState: @unchecked Sendable { /// Use this during rendering (e.g., from modifiers) to avoid render loops. /// /// - Parameter items: The items to display. - internal func setItemsSilently(_ items: [any TStatusBarItemProtocol]) { + internal func setItemsSilently(_ items: [any StatusBarItemProtocol]) { globalItems = items } @@ -136,7 +136,7 @@ public final class StatusBarState: @unchecked Sendable { /// - Parameters: /// - context: A unique identifier for this context. /// - items: The items to display for this context. - public func push(context: String, items: [any TStatusBarItemProtocol]) { + public func push(context: String, items: [any StatusBarItemProtocol]) { contextStack.removeAll { $0.context == context } contextStack.append((context, items)) AppState.shared.setNeedsRender() @@ -149,7 +149,7 @@ public final class StatusBarState: @unchecked Sendable { /// - Parameters: /// - context: A unique identifier for this context. /// - items: The items to display for this context. - internal func pushSilently(context: String, items: [any TStatusBarItemProtocol]) { + internal func pushSilently(context: String, items: [any StatusBarItemProtocol]) { contextStack.removeAll { $0.context == context } contextStack.append((context, items)) } @@ -161,7 +161,7 @@ public final class StatusBarState: @unchecked Sendable { /// - Parameters: /// - context: A unique identifier for this context. /// - builder: A closure that returns items. - public func push(context: String, @StatusBarItemBuilder _ builder: () -> [any TStatusBarItemProtocol]) { + public func push(context: String, @StatusBarItemBuilder _ builder: () -> [any StatusBarItemProtocol]) { push(context: context, items: builder()) } @@ -192,7 +192,7 @@ public final class StatusBarState: @unchecked Sendable { // MARK: - Current State /// The currently active items (topmost context or global). - public var currentItems: [any TStatusBarItemProtocol] { + public var currentItems: [any StatusBarItemProtocol] { if let topContext = contextStack.last { return topContext.items } @@ -227,7 +227,7 @@ public final class StatusBarState: @unchecked Sendable { public func handleKeyEvent(_ event: KeyEvent) -> Bool { for item in currentItems { if item.matches(event) { - if let statusBarItem = item as? TStatusBarItem { + if let statusBarItem = item as? StatusBarItem { // Only consume the event if the item has an action if statusBarItem.hasAction { statusBarItem.execute() @@ -256,7 +256,7 @@ extension EnvironmentValues { /// @Environment(\.statusBar) var statusBar /// /// statusBar.setItems([ - /// TStatusBarItem(shortcut: "q", label: "quit") + /// StatusBarItem(shortcut: "q", label: "quit") /// ]) /// ``` public var statusBar: StatusBarState { @@ -273,14 +273,14 @@ private nonisolated(unsafe) var needsRerender = false // MARK: - App Runner -/// Runs a TApp. -internal final class AppRunner { - let app: App +/// Runs an App. +internal final class AppRunner { + let app: A let terminal: Terminal let statusBar: StatusBarState private var isRunning = false - init(app: App) { + init(app: A) { self.app = app self.terminal = Terminal.shared self.statusBar = StatusBarState() @@ -369,7 +369,7 @@ internal final class AppRunner { } } - private func renderScene(_ scene: S, context: RenderContext) { + private func renderScene(_ scene: S, context: RenderContext) { if let renderable = scene as? SceneRenderable { renderable.renderScene(context: context) } @@ -377,7 +377,7 @@ internal final class AppRunner { /// Renders the status bar at the specified row. private func renderStatusBar(atRow row: Int) { - let statusBarView = TStatusBar( + let statusBarView = StatusBar( items: statusBar.currentItems, style: statusBar.style, alignment: statusBar.alignment, diff --git a/Sources/SwiftTUI/App/TScene.swift b/Sources/SwiftTUI/App/Scene.swift similarity index 78% rename from Sources/SwiftTUI/App/TScene.swift rename to Sources/SwiftTUI/App/Scene.swift index 4e8605f..4cc88ca 100644 --- a/Sources/SwiftTUI/App/TScene.swift +++ b/Sources/SwiftTUI/App/Scene.swift @@ -1,5 +1,5 @@ // -// TScene.swift +// Scene.swift // SwiftTUI // // Scene types for SwiftTUI applications. @@ -9,7 +9,7 @@ /// /// A scene represents a part of the app structure, /// typically a window or a group of views. -public protocol TScene {} +public protocol Scene {} // MARK: - WindowGroup @@ -24,14 +24,14 @@ public protocol TScene {} /// ContentView() /// } /// ``` -public struct WindowGroup: TScene { +public struct WindowGroup: Scene { /// The content of the window. public let content: Content /// Creates a WindowGroup with the specified content. /// /// - Parameter content: A ViewBuilder that defines the content. - public init(@TViewBuilder content: () -> Content) { + public init(@ViewBuilder content: () -> Content) { self.content = content() } } @@ -42,7 +42,7 @@ public struct WindowGroup: TScene { @resultBuilder public struct SceneBuilder { /// Builds a single scene. - public static func buildBlock(_ content: Content) -> Content { + public static func buildBlock(_ content: Content) -> Content { content } } diff --git a/Sources/SwiftTUI/Core/AppStorage.swift b/Sources/SwiftTUI/Core/AppStorage.swift index 5698505..6ac8280 100644 --- a/Sources/SwiftTUI/Core/AppStorage.swift +++ b/Sources/SwiftTUI/Core/AppStorage.swift @@ -176,12 +176,12 @@ public final class StorageManager: @unchecked Sendable { /// # Example /// /// ```swift -/// struct SettingsView: TView { +/// struct SettingsView: View { /// @AppStorage("username") var username = "Guest" /// @AppStorage("darkMode") var darkMode = false /// @AppStorage("fontSize") var fontSize = 14 /// -/// var body: some TView { +/// var body: some View { /// VStack { /// Text("User: \(username)") /// Text("Dark Mode: \(darkMode ? "On" : "Off")") @@ -306,11 +306,11 @@ extension AppStorage where Value: ExpressibleByNilLiteral { /// # Example /// /// ```swift -/// struct ContentView: TView { +/// struct ContentView: View { /// @SceneStorage("selectedTab") var selectedTab = 0 /// @SceneStorage("scrollOffset") var scrollOffset = 0 /// -/// var body: some TView { +/// var body: some View { /// TabView(selection: $selectedTab) { /// // ... /// } diff --git a/Sources/SwiftTUI/Core/Color.swift b/Sources/SwiftTUI/Core/Color.swift index 7abb70f..07b26ae 100644 --- a/Sources/SwiftTUI/Core/Color.swift +++ b/Sources/SwiftTUI/Core/Color.swift @@ -141,6 +141,124 @@ public struct Color: Sendable, Equatable { let blue = UInt8(hex & 0xFF) return .rgb(red, green, blue) } + + /// Creates a color from a hex string. + /// + /// Supports formats: "#RGB", "#RRGGBB", "RGB", "RRGGBB" + /// + /// - Parameter hex: The hex string (e.g., "#FF5500", "F50", "#abc"). + /// - Returns: The corresponding RGB color, or nil if invalid. + public static func hex(_ hex: String) -> Color? { + var hexString = hex.trimmingCharacters(in: .whitespacesAndNewlines) + + // Remove # prefix if present + if hexString.hasPrefix("#") { + hexString.removeFirst() + } + + // Handle shorthand format (RGB -> RRGGBB) + if hexString.count == 3 { + let chars = Array(hexString) + hexString = String([chars[0], chars[0], chars[1], chars[1], chars[2], chars[2]]) + } + + // Must be 6 characters now + guard hexString.count == 6 else { return nil } + + // Parse hex value + guard let hexValue = UInt32(hexString, radix: 16) else { return nil } + + return .hex(hexValue) + } + + /// Creates a color from HSL values. + /// + /// - Parameters: + /// - hue: The hue component (0-360). + /// - saturation: The saturation component (0-100). + /// - lightness: The lightness component (0-100). + /// - Returns: The corresponding RGB color. + public static func hsl(_ hue: Double, _ saturation: Double, _ lightness: Double) -> Color { + let h = hue / 360.0 + let s = saturation / 100.0 + let l = lightness / 100.0 + + if s == 0 { + // Achromatic (gray) + let gray = UInt8(l * 255) + return .rgb(gray, gray, gray) + } + + let q = l < 0.5 ? l * (1 + s) : l + s - l * s + let p = 2 * l - q + + func hueToRGB(_ p: Double, _ q: Double, _ t: Double) -> Double { + var t = t + if t < 0 { t += 1 } + if t > 1 { t -= 1 } + if t < 1/6 { return p + (q - p) * 6 * t } + if t < 1/2 { return q } + if t < 2/3 { return p + (q - p) * (2/3 - t) * 6 } + return p + } + + let red = UInt8(hueToRGB(p, q, h + 1/3) * 255) + let green = UInt8(hueToRGB(p, q, h) * 255) + let blue = UInt8(hueToRGB(p, q, h - 1/3) * 255) + + return .rgb(red, green, blue) + } + + /// Returns a lighter version of this color. + /// + /// - Parameter amount: The amount to lighten (0-1, default 0.2). + /// - Returns: A lighter color. + public func lighter(by amount: Double = 0.2) -> Color { + guard case .rgb(let red, let green, let blue) = value else { + return self + } + + let newRed = UInt8(min(255, Double(red) + 255 * amount)) + let newGreen = UInt8(min(255, Double(green) + 255 * amount)) + let newBlue = UInt8(min(255, Double(blue) + 255 * amount)) + + return .rgb(newRed, newGreen, newBlue) + } + + /// Returns a darker version of this color. + /// + /// - Parameter amount: The amount to darken (0-1, default 0.2). + /// - Returns: A darker color. + public func darker(by amount: Double = 0.2) -> Color { + guard case .rgb(let red, let green, let blue) = value else { + return self + } + + let newRed = UInt8(max(0, Double(red) - 255 * amount)) + let newGreen = UInt8(max(0, Double(green) - 255 * amount)) + let newBlue = UInt8(max(0, Double(blue) - 255 * amount)) + + return .rgb(newRed, newGreen, newBlue) + } + + /// Returns a color with adjusted opacity (simulated via color mixing). + /// + /// Since terminals don't support true transparency, this mixes + /// the color with black to simulate opacity. + /// + /// - Parameter opacity: The opacity (0-1). + /// - Returns: A color simulating the given opacity. + public func opacity(_ opacity: Double) -> Color { + guard case .rgb(let red, let green, let blue) = value else { + return self + } + + let newRed = UInt8(Double(red) * opacity) + let newGreen = UInt8(Double(green) * opacity) + let newBlue = UInt8(Double(blue) * opacity) + + return .rgb(newRed, newGreen, newBlue) + } } // MARK: - ANSIColor diff --git a/Sources/SwiftTUI/Core/Environment.swift b/Sources/SwiftTUI/Core/Environment.swift index f5bc5b5..2a67598 100644 --- a/Sources/SwiftTUI/Core/Environment.swift +++ b/Sources/SwiftTUI/Core/Environment.swift @@ -146,13 +146,13 @@ public final class EnvironmentStorage: @unchecked Sendable { /// # Example /// /// ```swift -/// struct MyView: TView { +/// struct MyView: View { /// @Environment(\.statusBar) var statusBar /// -/// var body: some TView { +/// var body: some View { /// Button("Add Item") { /// statusBar.push(context: "action") { -/// TStatusBarItem(shortcut: "⎋", label: "cancel") +/// StatusBarItem(shortcut: "⎋", label: "cancel") /// } /// } /// } @@ -179,7 +179,7 @@ public struct Environment: @unchecked Sendable { // MARK: - Environment Modifier /// A modifier that injects a value into the environment for child views. -public struct EnvironmentModifier: TView { +public struct EnvironmentModifier: View { /// The content view. let content: Content @@ -189,7 +189,7 @@ public struct EnvironmentModifier: TView { /// The value to inject. let value: V - public var body: some TView { + public var body: some View { content } } @@ -210,7 +210,7 @@ extension EnvironmentModifier: Renderable { // MARK: - Internal Rendering Helper /// Internal helper to render a view (avoids name collision with Renderable.renderToBuffer). -private func renderView(_ view: V, context: RenderContext) -> FrameBuffer { +private func renderView(_ view: V, context: RenderContext) -> FrameBuffer { if let renderable = view as? Renderable { return renderable.renderToBuffer(context: context) } @@ -224,7 +224,7 @@ private func renderView(_ view: V, context: RenderContext) -> FrameBuf // MARK: - View Extension for Environment -extension TView { +extension View { /// Sets an environment value for this view and its children. /// /// - Parameters: @@ -234,7 +234,7 @@ extension TView { public func environment( _ keyPath: WritableKeyPath, _ value: V - ) -> some TView { + ) -> some View { EnvironmentModifier(content: self, keyPath: keyPath, value: value) } } diff --git a/Sources/SwiftTUI/Core/Preferences.swift b/Sources/SwiftTUI/Core/Preferences.swift index babc038..174829d 100644 --- a/Sources/SwiftTUI/Core/Preferences.swift +++ b/Sources/SwiftTUI/Core/Preferences.swift @@ -187,7 +187,7 @@ public final class PreferenceStorage: @unchecked Sendable { // MARK: - Preference Modifier /// A modifier that sets a preference value. -public struct PreferenceModifier: TView { +public struct PreferenceModifier: View { /// The content view. let content: Content @@ -212,7 +212,7 @@ extension PreferenceModifier: Renderable { // MARK: - OnPreferenceChange Modifier /// A modifier that reacts to preference changes. -public struct OnPreferenceChangeModifier: TView +public struct OnPreferenceChangeModifier: View where K.Value: Equatable { /// The content view. let content: Content @@ -246,9 +246,9 @@ extension OnPreferenceChangeModifier: Renderable { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Sets a preference value for this view. /// /// Preferences propagate up the view hierarchy, allowing child views @@ -265,7 +265,7 @@ extension TView { /// - key: The preference key type. /// - value: The value to set. /// - Returns: A view that sets the preference. - public func preference(key: K.Type, value: K.Value) -> some TView { + public func preference(key: K.Type, value: K.Value) -> some View { PreferenceModifier(content: self, value: value) } @@ -289,7 +289,7 @@ extension TView { public func onPreferenceChange( _ key: K.Type, perform action: @escaping (K.Value) -> Void - ) -> some TView where K.Value: Equatable { + ) -> some View where K.Value: Equatable { OnPreferenceChangeModifier(content: self, action: action) } } @@ -321,7 +321,7 @@ public struct AnchorPreferenceKey: PreferenceKey { // MARK: - Convenience Extensions -extension TView { +extension View { /// Sets the navigation title for this view. /// /// # Example @@ -335,7 +335,7 @@ extension TView { /// /// - Parameter title: The navigation title. /// - Returns: A view with the navigation title preference set. - public func navigationTitle(_ title: String) -> some TView { + public func navigationTitle(_ title: String) -> some View { preference(key: NavigationTitleKey.self, value: title) } } diff --git a/Sources/SwiftTUI/Core/PrimitiveViews.swift b/Sources/SwiftTUI/Core/PrimitiveViews.swift index 5409537..920f3e6 100644 --- a/Sources/SwiftTUI/Core/PrimitiveViews.swift +++ b/Sources/SwiftTUI/Core/PrimitiveViews.swift @@ -5,14 +5,14 @@ // Primitive view types that serve as leaves in the view tree. // -// MARK: - Never as TView +// MARK: - Never as View -/// `Never` conforms to TView for views that have no body. +/// `Never` conforms to View for views that have no body. /// /// Primitive views like `Text` or containers like `TupleView` have no /// body of their own - they are rendered directly. This extension allows /// using `Never` as the body type. -extension Never: TView { +extension Never: View { public var body: Never { fatalError("Never.body should never be called") } @@ -32,7 +32,7 @@ extension Never: TView { /// EmptyView() /// } /// ``` -public struct EmptyView: TView { +public struct EmptyView: View { /// Creates an empty view. public init() {} @@ -45,8 +45,8 @@ public struct EmptyView: TView { /// A view that represents either the true or false branch of a conditional. /// -/// This type is used internally by `TViewBuilder` for if-else statements. -public enum ConditionalView: TView { +/// This type is used internally by `ViewBuilder` for if-else statements. +public enum ConditionalView: View { /// The true branch was executed. case trueContent(TrueContent) @@ -58,22 +58,22 @@ public enum ConditionalView: TView { } } -// MARK: - TViewArray +// MARK: - ViewArray /// A view that contains an array of identical views. /// -/// This type is used internally by `TViewBuilder` for for-in loops. +/// This type is used internally by `ViewBuilder` for for-in loops. /// /// ```swift /// ForEach(items) { item in /// Text(item.name) /// } /// ``` -public struct TViewArray: TView { +public struct ViewArray: View { /// The contained views. public let elements: [Element] - /// Creates a TViewArray from an array of views. + /// Creates a ViewArray from an array of views. /// /// - Parameter elements: The views this container holds. public init(_ elements: [Element]) { @@ -81,15 +81,15 @@ public struct TViewArray: TView { } public var body: Never { - fatalError("TViewArray renders its children directly") + fatalError("ViewArray renders its children directly") } } -// MARK: - Optional TView Conformance +// MARK: - Optional View Conformance -/// Optional views conform to TView when their Wrapped type does. -extension Optional: TView where Wrapped: TView { - public var body: some TView { +/// Optional views conform to View when their Wrapped type does. +extension Optional: View where Wrapped: View { + public var body: some View { switch self { case .some(let view): view diff --git a/Sources/SwiftTUI/Core/State.swift b/Sources/SwiftTUI/Core/State.swift index fa756b0..c12a2ad 100644 --- a/Sources/SwiftTUI/Core/State.swift +++ b/Sources/SwiftTUI/Core/State.swift @@ -62,10 +62,10 @@ public final class AppState: @unchecked Sendable { /// # Example /// /// ```swift -/// struct ContentView: TView { -/// @TState var selectedIndex = 0 +/// struct ContentView: View { +/// @State var selectedIndex = 0 /// -/// var body: some TView { +/// var body: some View { /// Menu(items: menuItems, selection: $selectedIndex) /// } /// } @@ -108,20 +108,20 @@ public struct Binding { } } -// MARK: - TState Property Wrapper +// MARK: - State Property Wrapper /// A property wrapper that stores mutable state for a view. /// /// When the value changes, the view hierarchy is re-rendered. -/// Use `@TState` for simple value types owned by a single view. +/// Use `@State` for simple value types owned by a single view. /// /// # Example /// /// ```swift -/// struct CounterView: TView { -/// @TState var count = 0 +/// struct CounterView: View { +/// @State var count = 0 /// -/// var body: some TView { +/// var body: some View { /// VStack { /// Text("Count: \(count)") /// // When count changes, view re-renders @@ -138,7 +138,7 @@ public struct Binding { /// Menu(selection: $selectedIndex) /// ``` @propertyWrapper -public struct TState { +public struct State { /// The storage for the state value. private final class Storage { var value: Value { diff --git a/Sources/SwiftTUI/Core/Theme.swift b/Sources/SwiftTUI/Core/Theme.swift new file mode 100644 index 0000000..78eabe5 --- /dev/null +++ b/Sources/SwiftTUI/Core/Theme.swift @@ -0,0 +1,574 @@ +// +// Theme.swift +// SwiftTUI +// +// Theming system with full 16M color support and predefined terminal themes. +// + +import Foundation + +// MARK: - Theme Protocol + +/// A theme defines the color palette for a SwiftTUI application. +/// +/// Themes provide semantic colors that views use for consistent styling. +/// SwiftTUI includes several predefined themes inspired by classic terminals. +/// +/// # Usage +/// +/// ```swift +/// // Set the app theme +/// ThemeManager.shared.current = .amber +/// +/// // Use theme colors in views +/// Text("Hello").foregroundColor(.theme.primary) +/// ``` +public protocol Theme: Sendable { + /// The theme's unique identifier. + var id: String { get } + + /// The theme's display name. + var name: String { get } + + // MARK: - Background Colors + + /// The primary background color. + var background: Color { get } + + /// Secondary background for cards, panels, etc. + var backgroundSecondary: Color { get } + + /// Tertiary background for nested elements. + var backgroundTertiary: Color { get } + + // MARK: - Foreground Colors + + /// Primary text/foreground color. + var foreground: Color { get } + + /// Secondary text color (less prominent). + var foregroundSecondary: Color { get } + + /// Tertiary text color (even less prominent). + var foregroundTertiary: Color { get } + + // MARK: - Accent Colors + + /// Primary accent color for interactive elements. + var accent: Color { get } + + /// Secondary accent color. + var accentSecondary: Color { get } + + // MARK: - Semantic Colors + + /// Color for success states. + var success: Color { get } + + /// Color for warning states. + var warning: Color { get } + + /// Color for error states. + var error: Color { get } + + /// Color for informational states. + var info: Color { get } + + // MARK: - UI Element Colors + + /// Border color for boxes, cards, etc. + var border: Color { get } + + /// Border color for focused elements. + var borderFocused: Color { get } + + /// Separator/divider color. + var separator: Color { get } + + /// Selection highlight color. + var selection: Color { get } + + /// Color for disabled elements. + var disabled: Color { get } + + // MARK: - Status Bar Colors + + /// Status bar background. + var statusBarBackground: Color { get } + + /// Status bar text color. + var statusBarForeground: Color { get } + + /// Status bar shortcut highlight color. + var statusBarHighlight: Color { get } +} + +// MARK: - Default Theme Implementation + +extension Theme { + // Default implementations using the primary colors + + public var backgroundSecondary: Color { background } + public var backgroundTertiary: Color { background } + public var foregroundSecondary: Color { foreground } + public var foregroundTertiary: Color { foreground } + public var accentSecondary: Color { accent } + public var borderFocused: Color { accent } + public var separator: Color { border } + public var selection: Color { accent } + public var disabled: Color { foregroundTertiary } + public var statusBarBackground: Color { backgroundSecondary } + public var statusBarForeground: Color { foreground } + public var statusBarHighlight: Color { accent } +} + +// MARK: - Theme Environment Key + +/// Environment key for the current theme. +private struct ThemeKey: EnvironmentKey { + static let defaultValue: Theme = DefaultTheme() +} + +extension EnvironmentValues { + /// The current theme. + /// + /// Set a theme at the app level and it propagates to all child views: + /// + /// ```swift + /// WindowGroup { + /// ContentView() + /// } + /// .environment(\.theme, GreenPhosphorTheme()) + /// ``` + /// + /// Access the theme in views: + /// + /// ```swift + /// struct MyView: View { + /// @Environment(\.theme) var theme + /// + /// var body: some View { + /// Text("Hello") + /// .foregroundColor(theme.foreground) + /// } + /// } + /// ``` + public var theme: Theme { + get { self[ThemeKey.self] } + set { self[ThemeKey.self] = newValue } + } +} + +// MARK: - Color Theme Extension + +extension Color { + /// Access theme colors from the current environment. + /// + /// These colors read from `EnvironmentStorage.shared` during rendering. + /// + /// # Example + /// + /// ```swift + /// Text("Hello").foregroundColor(.theme.foreground) + /// ``` + public static var theme: ThemeColors.Type { + ThemeColors.self + } +} + +/// Namespace for theme-aware colors. +/// +/// These properties read the current theme from the environment storage +/// that is set during rendering. +public enum ThemeColors { + /// Gets the current theme from environment storage. + private static var current: Theme { + EnvironmentStorage.shared.environment.theme + } + + /// Primary background color. + public static var background: Color { current.background } + + /// Secondary background color. + public static var backgroundSecondary: Color { current.backgroundSecondary } + + /// Tertiary background color. + public static var backgroundTertiary: Color { current.backgroundTertiary } + + /// Primary foreground color. + public static var foreground: Color { current.foreground } + + /// Secondary foreground color. + public static var foregroundSecondary: Color { current.foregroundSecondary } + + /// Tertiary foreground color. + public static var foregroundTertiary: Color { current.foregroundTertiary } + + /// Primary accent color. + public static var accent: Color { current.accent } + + /// Secondary accent color. + public static var accentSecondary: Color { current.accentSecondary } + + /// Success color. + public static var success: Color { current.success } + + /// Warning color. + public static var warning: Color { current.warning } + + /// Error color. + public static var error: Color { current.error } + + /// Info color. + public static var info: Color { current.info } + + /// Border color. + public static var border: Color { current.border } + + /// Focused border color. + public static var borderFocused: Color { current.borderFocused } + + /// Separator color. + public static var separator: Color { current.separator } + + /// Selection color. + public static var selection: Color { current.selection } + + /// Disabled color. + public static var disabled: Color { current.disabled } + + /// Status bar background. + public static var statusBarBackground: Color { current.statusBarBackground } + + /// Status bar foreground. + public static var statusBarForeground: Color { current.statusBarForeground } + + /// Status bar highlight. + public static var statusBarHighlight: Color { current.statusBarHighlight } +} + +// MARK: - Theme Modifier + +extension View { + /// Sets the theme for this view and its descendants. + /// + /// # Example + /// + /// ```swift + /// ContentView() + /// .theme(GreenPhosphorTheme()) + /// ``` + /// + /// - Parameter theme: The theme to apply. + /// - Returns: A view with the theme applied. + public func theme(_ theme: Theme) -> some View { + environment(\.theme, theme) + } +} + +// MARK: - Predefined Themes + +/// The default theme using standard ANSI colors. +public struct DefaultTheme: Theme { + public let id = "default" + public let name = "Default" + + public let background = Color.default + public let backgroundSecondary = Color.brightBlack + public let foreground = Color.white + public let foregroundSecondary = Color.brightWhite + public let foregroundTertiary = Color.brightBlack + public let accent = Color.cyan + public let accentSecondary = Color.blue + public let success = Color.green + public let warning = Color.yellow + public let error = Color.red + public let info = Color.cyan + public let border = Color.brightBlack + public let statusBarHighlight = Color.cyan + + public init() {} +} + +/// Classic green phosphor terminal theme (P1 phosphor). +/// +/// Inspired by early CRT monitors like the IBM 5151 and Apple II. +public struct GreenPhosphorTheme: Theme { + public let id = "green-phosphor" + public let name = "Green (Phosphor)" + + // Dark background with green phosphor glow + public let background = Color.hex(0x0D1F0D) + public let backgroundSecondary = Color.hex(0x0A1A0A) + public let backgroundTertiary = Color.hex(0x071407) + public let foreground = Color.hex(0x33FF33) + public let foregroundSecondary = Color.hex(0x29CC29) + public let foregroundTertiary = Color.hex(0x1F991F) + public let accent = Color.hex(0x66FF66) + public let accentSecondary = Color.hex(0x00CC00) + public let success = Color.hex(0x33FF33) + public let warning = Color.hex(0xCCFF33) + public let error = Color.hex(0xFF6633) + public let info = Color.hex(0x33FFCC) + public let border = Color.hex(0x1F661F) + public let borderFocused = Color.hex(0x33FF33) + public let selection = Color.hex(0x1F4D1F) + public let statusBarBackground = Color.hex(0x0A1A0A) + public let statusBarForeground = Color.hex(0x33FF33) + public let statusBarHighlight = Color.hex(0x66FF66) + + public init() {} +} + +/// Classic amber phosphor terminal theme (P3 phosphor). +/// +/// Inspired by terminals like the IBM 3278 and Wyse 50. +public struct AmberPhosphorTheme: Theme { + public let id = "amber-phosphor" + public let name = "Amber (Phosphor)" + + // Dark background with amber phosphor glow + public let background = Color.hex(0x1F1400) + public let backgroundSecondary = Color.hex(0x1A1100) + public let backgroundTertiary = Color.hex(0x140D00) + public let foreground = Color.hex(0xFFB000) + public let foregroundSecondary = Color.hex(0xCC8C00) + public let foregroundTertiary = Color.hex(0x996900) + public let accent = Color.hex(0xFFCC33) + public let accentSecondary = Color.hex(0xCC9900) + public let success = Color.hex(0xFFCC00) + public let warning = Color.hex(0xFFE066) + public let error = Color.hex(0xFF6633) + public let info = Color.hex(0xFFD966) + public let border = Color.hex(0x664D00) + public let borderFocused = Color.hex(0xFFB000) + public let selection = Color.hex(0x4D3A00) + public let statusBarBackground = Color.hex(0x1A1100) + public let statusBarForeground = Color.hex(0xFFB000) + public let statusBarHighlight = Color.hex(0xFFCC33) + + public init() {} +} + +/// Classic white phosphor terminal theme (P4 phosphor). +/// +/// Inspired by terminals like the DEC VT100 and VT220. +public struct WhitePhosphorTheme: Theme { + public let id = "white-phosphor" + public let name = "White (Phosphor)" + + // Dark background with white/cool phosphor glow + public let background = Color.hex(0x0A0A0F) + public let backgroundSecondary = Color.hex(0x12121A) + public let backgroundTertiary = Color.hex(0x080810) + public let foreground = Color.hex(0xE0E0E8) + public let foregroundSecondary = Color.hex(0xB0B0B8) + public let foregroundTertiary = Color.hex(0x808088) + public let accent = Color.hex(0xF0F0FF) + public let accentSecondary = Color.hex(0xC0C0D0) + public let success = Color.hex(0xC0FFC0) + public let warning = Color.hex(0xFFE0A0) + public let error = Color.hex(0xFFA0A0) + public let info = Color.hex(0xA0E0FF) + public let border = Color.hex(0x404050) + public let borderFocused = Color.hex(0xE0E0E8) + public let selection = Color.hex(0x303040) + public let statusBarBackground = Color.hex(0x12121A) + public let statusBarForeground = Color.hex(0xE0E0E8) + public let statusBarHighlight = Color.hex(0xF0F0FF) + + public init() {} +} + +/// Red phosphor terminal theme. +/// +/// Less common but used in some military and specialized applications. +public struct RedPhosphorTheme: Theme { + public let id = "red-phosphor" + public let name = "Red (Phosphor)" + + // Dark background with red phosphor glow + public let background = Color.hex(0x1A0A0A) + public let backgroundSecondary = Color.hex(0x140808) + public let backgroundTertiary = Color.hex(0x100606) + public let foreground = Color.hex(0xFF4040) + public let foregroundSecondary = Color.hex(0xCC3333) + public let foregroundTertiary = Color.hex(0x992626) + public let accent = Color.hex(0xFF6666) + public let accentSecondary = Color.hex(0xCC4040) + public let success = Color.hex(0xFF8080) + public let warning = Color.hex(0xFFB366) + public let error = Color.hex(0xFFFFFF) + public let info = Color.hex(0xFF9999) + public let border = Color.hex(0x661A1A) + public let borderFocused = Color.hex(0xFF4040) + public let selection = Color.hex(0x4D1414) + public let statusBarBackground = Color.hex(0x140808) + public let statusBarForeground = Color.hex(0xFF4040) + public let statusBarHighlight = Color.hex(0xFF6666) + + public init() {} +} + +/// Classic ncurses-style theme. +/// +/// Traditional terminal colors as used in ncurses applications +/// like htop, mc (Midnight Commander), and vim. +public struct NCursesTheme: Theme { + public let id = "ncurses" + public let name = "ncurses" + + // Standard terminal black background + public let background = Color.black + public let backgroundSecondary = Color.blue + public let backgroundTertiary = Color.brightBlack + public let foreground = Color.white + public let foregroundSecondary = Color.brightWhite + public let foregroundTertiary = Color.brightBlack + public let accent = Color.cyan + public let accentSecondary = Color.brightCyan + public let success = Color.green + public let warning = Color.yellow + public let error = Color.red + public let info = Color.cyan + public let border = Color.white + public let borderFocused = Color.brightCyan + public let selection = Color.blue + public let disabled = Color.brightBlack + public let statusBarBackground = Color.blue + public let statusBarForeground = Color.white + public let statusBarHighlight = Color.yellow + + public init() {} +} + +/// Dark mode theme with modern colors. +public struct DarkTheme: Theme { + public let id = "dark" + public let name = "Dark" + + public let background = Color.hex(0x1E1E2E) + public let backgroundSecondary = Color.hex(0x313244) + public let backgroundTertiary = Color.hex(0x45475A) + public let foreground = Color.hex(0xCDD6F4) + public let foregroundSecondary = Color.hex(0xBAC2DE) + public let foregroundTertiary = Color.hex(0xA6ADC8) + public let accent = Color.hex(0x89B4FA) + public let accentSecondary = Color.hex(0x74C7EC) + public let success = Color.hex(0xA6E3A1) + public let warning = Color.hex(0xF9E2AF) + public let error = Color.hex(0xF38BA8) + public let info = Color.hex(0x89DCEB) + public let border = Color.hex(0x585B70) + public let borderFocused = Color.hex(0x89B4FA) + public let selection = Color.hex(0x45475A) + public let statusBarBackground = Color.hex(0x313244) + public let statusBarForeground = Color.hex(0xCDD6F4) + public let statusBarHighlight = Color.hex(0x89B4FA) + + public init() {} +} + +/// Light mode theme. +public struct LightTheme: Theme { + public let id = "light" + public let name = "Light" + + public let background = Color.hex(0xEFF1F5) + public let backgroundSecondary = Color.hex(0xE6E9EF) + public let backgroundTertiary = Color.hex(0xDCE0E8) + public let foreground = Color.hex(0x4C4F69) + public let foregroundSecondary = Color.hex(0x5C5F77) + public let foregroundTertiary = Color.hex(0x6C6F85) + public let accent = Color.hex(0x1E66F5) + public let accentSecondary = Color.hex(0x209FB5) + public let success = Color.hex(0x40A02B) + public let warning = Color.hex(0xDF8E1D) + public let error = Color.hex(0xD20F39) + public let info = Color.hex(0x04A5E5) + public let border = Color.hex(0x9CA0B0) + public let borderFocused = Color.hex(0x1E66F5) + public let selection = Color.hex(0xDCE0E8) + public let statusBarBackground = Color.hex(0xE6E9EF) + public let statusBarForeground = Color.hex(0x4C4F69) + public let statusBarHighlight = Color.hex(0x1E66F5) + + public init() {} +} + +// MARK: - Theme Registry + +/// Registry of available themes. +public struct ThemeRegistry { + /// All available themes. + public static let all: [Theme] = [ + DefaultTheme(), + GreenPhosphorTheme(), + AmberPhosphorTheme(), + WhitePhosphorTheme(), + RedPhosphorTheme(), + NCursesTheme(), + DarkTheme(), + LightTheme() + ] + + /// Finds a theme by ID. + public static func theme(withId id: String) -> Theme? { + all.first { $0.id == id } + } + + /// Finds a theme by name. + public static func theme(withName name: String) -> Theme? { + all.first { $0.name == name } + } +} + +// MARK: - Convenience Theme Accessors + +extension Theme where Self == DefaultTheme { + /// The default theme. + public static var `default`: DefaultTheme { DefaultTheme() } +} + +extension Theme where Self == GreenPhosphorTheme { + /// Green phosphor terminal theme. + public static var green: GreenPhosphorTheme { GreenPhosphorTheme() } + /// Green phosphor terminal theme (alias). + public static var greenPhosphor: GreenPhosphorTheme { GreenPhosphorTheme() } +} + +extension Theme where Self == AmberPhosphorTheme { + /// Amber phosphor terminal theme. + public static var amber: AmberPhosphorTheme { AmberPhosphorTheme() } + /// Amber phosphor terminal theme (alias). + public static var amberPhosphor: AmberPhosphorTheme { AmberPhosphorTheme() } +} + +extension Theme where Self == WhitePhosphorTheme { + /// White phosphor terminal theme. + public static var white: WhitePhosphorTheme { WhitePhosphorTheme() } + /// White phosphor terminal theme (alias). + public static var whitePhosphor: WhitePhosphorTheme { WhitePhosphorTheme() } +} + +extension Theme where Self == RedPhosphorTheme { + /// Red phosphor terminal theme. + public static var red: RedPhosphorTheme { RedPhosphorTheme() } + /// Red phosphor terminal theme (alias). + public static var redPhosphor: RedPhosphorTheme { RedPhosphorTheme() } +} + +extension Theme where Self == NCursesTheme { + /// Classic ncurses theme. + public static var ncurses: NCursesTheme { NCursesTheme() } +} + +extension Theme where Self == DarkTheme { + /// Modern dark theme. + public static var dark: DarkTheme { DarkTheme() } +} + +extension Theme where Self == LightTheme { + /// Modern light theme. + public static var light: LightTheme { LightTheme() } +} diff --git a/Sources/SwiftTUI/Core/TupleViews.swift b/Sources/SwiftTUI/Core/TupleViews.swift index 9e2cb4b..c4b1c87 100644 --- a/Sources/SwiftTUI/Core/TupleViews.swift +++ b/Sources/SwiftTUI/Core/TupleViews.swift @@ -8,7 +8,7 @@ // MARK: - TupleView2 /// A view that contains two child views. -public struct TupleView2: TView { +public struct TupleView2: View { public let value: (V0, V1) public init(_ v0: V0, _ v1: V1) { @@ -23,7 +23,7 @@ public struct TupleView2: TView { // MARK: - TupleView3 /// A view that contains three child views. -public struct TupleView3: TView { +public struct TupleView3: View { public let value: (V0, V1, V2) public init(_ v0: V0, _ v1: V1, _ v2: V2) { @@ -38,7 +38,7 @@ public struct TupleView3: TView { // MARK: - TupleView4 /// A view that contains four child views. -public struct TupleView4: TView { +public struct TupleView4: View { public let value: (V0, V1, V2, V3) public init(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3) { @@ -53,7 +53,7 @@ public struct TupleView4: TView { // MARK: - TupleView5 /// A view that contains five child views. -public struct TupleView5: TView { +public struct TupleView5: View { public let value: (V0, V1, V2, V3, V4) public init(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4) { @@ -68,7 +68,7 @@ public struct TupleView5: // MARK: - TupleView6 /// A view that contains six child views. -public struct TupleView6: TView { +public struct TupleView6: View { public let value: (V0, V1, V2, V3, V4, V5) public init(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5) { @@ -83,7 +83,7 @@ public struct TupleView6: TView { +public struct TupleView7: View { public let value: (V0, V1, V2, V3, V4, V5, V6) public init(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5, _ v6: V6) { @@ -98,7 +98,7 @@ public struct TupleView7: TView { +public struct TupleView8: View { public let value: (V0, V1, V2, V3, V4, V5, V6, V7) public init(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5, _ v6: V6, _ v7: V7) { @@ -113,7 +113,7 @@ public struct TupleView8: TView { +public struct TupleView9: View { public let value: (V0, V1, V2, V3, V4, V5, V6, V7, V8) public init(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5, _ v6: V6, _ v7: V7, _ v8: V8) { @@ -128,7 +128,7 @@ public struct TupleView9: TView { +public struct TupleView10: View { public let value: (V0, V1, V2, V3, V4, V5, V6, V7, V8, V9) public init(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5, _ v6: V6, _ v7: V7, _ v8: V8, _ v9: V9) { diff --git a/Sources/SwiftTUI/Core/TView.swift b/Sources/SwiftTUI/Core/View.swift similarity index 63% rename from Sources/SwiftTUI/Core/TView.swift rename to Sources/SwiftTUI/Core/View.swift index 6d9a25d..f6c5662 100644 --- a/Sources/SwiftTUI/Core/TView.swift +++ b/Sources/SwiftTUI/Core/View.swift @@ -1,5 +1,5 @@ // -// TView.swift +// View.swift // SwiftTUI // // The base protocol for all SwiftTUI views. @@ -7,31 +7,31 @@ /// The base protocol for all SwiftTUI views. /// -/// `TView` is the central protocol in SwiftTUI and works similarly to `View` in SwiftUI. +/// `View` is the central protocol in SwiftTUI and works similarly to `View` in SwiftUI. /// It defines how components declare their structure and content. /// -/// Every TView defines a `body` composed of other TViews. +/// Every View defines a `body` composed of other Views. /// This enables a hierarchical, declarative UI description. /// /// # Example /// /// ```swift -/// struct MyView: TView { -/// var body: some TView { +/// struct MyView: View { +/// var body: some View { /// Text("Hello, SwiftTUI!") /// } /// } /// ``` -public protocol TView { +public protocol View { /// The type of the body view. /// /// Swift automatically infers this type from the `body` implementation. - associatedtype Body: TView + associatedtype Body: View /// The content and behavior of this view. /// /// Implement this property to define the structure of your view. - /// The body consists of other TViews that together form the UI. - @TViewBuilder + /// The body consists of other Views that together form the UI. + @ViewBuilder var body: Body { get } } diff --git a/Sources/SwiftTUI/Core/TViewBuilder.swift b/Sources/SwiftTUI/Core/ViewBuilder.swift similarity index 66% rename from Sources/SwiftTUI/Core/TViewBuilder.swift rename to Sources/SwiftTUI/Core/ViewBuilder.swift index 0b20517..4f8161a 100644 --- a/Sources/SwiftTUI/Core/TViewBuilder.swift +++ b/Sources/SwiftTUI/Core/ViewBuilder.swift @@ -1,13 +1,13 @@ // -// TViewBuilder.swift +// ViewBuilder.swift // SwiftTUI // // Result builder for declarative view composition. // -/// A result builder for TView hierarchies. +/// A result builder for View hierarchies. /// -/// The `@TViewBuilder` enables a declarative syntax similar to SwiftUI: +/// The `@ViewBuilder` enables a declarative syntax similar to SwiftUI: /// /// ```swift /// VStack { @@ -26,19 +26,19 @@ /// - Optional views (`if let`) /// - Arrays of views (`for-in`) @resultBuilder -public struct TViewBuilder { +public struct ViewBuilder { // MARK: - Single View /// Builds a single view. - public static func buildBlock(_ content: Content) -> Content { + public static func buildBlock(_ content: Content) -> Content { content } // MARK: - Multiple Views (Tuple Views) /// Builds two views into a TupleView. - public static func buildBlock( + public static func buildBlock( _ c0: C0, _ c1: C1 ) -> TupleView2 { @@ -46,7 +46,7 @@ public struct TViewBuilder { } /// Builds three views into a TupleView. - public static func buildBlock( + public static func buildBlock( _ c0: C0, _ c1: C1, _ c2: C2 @@ -55,7 +55,7 @@ public struct TViewBuilder { } /// Builds four views into a TupleView. - public static func buildBlock( + public static func buildBlock( _ c0: C0, _ c1: C1, _ c2: C2, @@ -65,7 +65,7 @@ public struct TViewBuilder { } /// Builds five views into a TupleView. - public static func buildBlock( + public static func buildBlock( _ c0: C0, _ c1: C1, _ c2: C2, @@ -76,7 +76,7 @@ public struct TViewBuilder { } /// Builds six views into a TupleView. - public static func buildBlock( + public static func buildBlock( _ c0: C0, _ c1: C1, _ c2: C2, @@ -88,7 +88,7 @@ public struct TViewBuilder { } /// Builds seven views into a TupleView. - public static func buildBlock( + public static func buildBlock( _ c0: C0, _ c1: C1, _ c2: C2, @@ -101,7 +101,7 @@ public struct TViewBuilder { } /// Builds eight views into a TupleView. - public static func buildBlock( + public static func buildBlock( _ c0: C0, _ c1: C1, _ c2: C2, @@ -115,7 +115,7 @@ public struct TViewBuilder { } /// Builds nine views into a TupleView. - public static func buildBlock( + public static func buildBlock( _ c0: C0, _ c1: C1, _ c2: C2, @@ -130,7 +130,7 @@ public struct TViewBuilder { } /// Builds ten views into a TupleView. - public static func buildBlock( + public static func buildBlock( _ c0: C0, _ c1: C1, _ c2: C2, @@ -148,45 +148,45 @@ public struct TViewBuilder { // MARK: - Conditionals /// Supports the true branch of an if-else. - public static func buildEither( + public static func buildEither( first content: TrueContent ) -> ConditionalView { .trueContent(content) } /// Supports the false branch of an if-else. - public static func buildEither( + public static func buildEither( second content: FalseContent ) -> ConditionalView { .falseContent(content) } /// Supports optional views (if let, if without else). - public static func buildOptional(_ content: Content?) -> Content? { + public static func buildOptional(_ content: Content?) -> Content? { content } /// Supports availability limiting. - public static func buildLimitedAvailability(_ content: Content) -> Content { + public static func buildLimitedAvailability(_ content: Content) -> Content { content } // MARK: - Arrays /// Supports for-in loops. - public static func buildArray(_ components: [Content]) -> TViewArray { - TViewArray(components) + public static func buildArray(_ components: [Content]) -> ViewArray { + ViewArray(components) } // MARK: - Expression /// Converts a single expression into a view. - public static func buildExpression(_ expression: Content) -> Content { + public static func buildExpression(_ expression: Content) -> Content { expression } /// Supports optional expressions. - public static func buildExpression(_ expression: Content?) -> Content? { + public static func buildExpression(_ expression: Content?) -> Content? { expression } } diff --git a/Sources/SwiftTUI/Core/ViewModifier.swift b/Sources/SwiftTUI/Core/ViewModifier.swift index d7d9fbc..ea527f7 100644 --- a/Sources/SwiftTUI/Core/ViewModifier.swift +++ b/Sources/SwiftTUI/Core/ViewModifier.swift @@ -7,21 +7,21 @@ /// A modifier that transforms a view's rendered output. /// -/// `TViewModifier` works on the `FrameBuffer` level: it takes a rendered +/// `ViewModifier` works on the `FrameBuffer` level: it takes a rendered /// buffer and returns a transformed buffer. This allows modifiers like /// `.padding()` and `.frame()` to manipulate layout after rendering. /// /// # Example /// /// ```swift -/// struct MyModifier: TViewModifier { +/// struct MyModifier: ViewModifier { /// func modify(buffer: FrameBuffer, context: RenderContext) -> FrameBuffer { /// // transform the buffer /// return buffer /// } /// } /// ``` -public protocol TViewModifier { +public protocol ViewModifier { /// Transforms a rendered buffer. /// /// - Parameters: @@ -37,7 +37,7 @@ public protocol TViewModifier { /// /// This is the return type of modifier methods like `.frame()` and `.padding()`. /// It is created automatically — users don't instantiate this directly. -public struct ModifiedView: TView { +public struct ModifiedView: View { /// The original view. public let content: Content @@ -58,14 +58,14 @@ extension ModifiedView: Renderable { } } -// MARK: - TView Modifier Extension +// MARK: - View Modifier Extension -extension TView { +extension View { /// Applies a modifier to this view. /// /// - Parameter modifier: The modifier to apply. /// - Returns: A modified view. - public func modifier(_ modifier: M) -> ModifiedView { + public func modifier(_ modifier: M) -> ModifiedView { ModifiedView(content: self, modifier: modifier) } } diff --git a/Sources/SwiftTUI/Modifiers/BackgroundModifier.swift b/Sources/SwiftTUI/Modifiers/BackgroundModifier.swift index 4cc9439..38d79ed 100644 --- a/Sources/SwiftTUI/Modifiers/BackgroundModifier.swift +++ b/Sources/SwiftTUI/Modifiers/BackgroundModifier.swift @@ -6,7 +6,7 @@ // /// A modifier that fills the background of a view with a color. -public struct BackgroundModifier: TViewModifier { +public struct BackgroundModifier: ViewModifier { /// The background color. public let color: Color @@ -55,9 +55,9 @@ public struct BackgroundModifier: TViewModifier { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Adds a background color to this view. /// /// # Example diff --git a/Sources/SwiftTUI/Modifiers/BorderModifier.swift b/Sources/SwiftTUI/Modifiers/BorderModifier.swift index 64053e5..2f9a217 100644 --- a/Sources/SwiftTUI/Modifiers/BorderModifier.swift +++ b/Sources/SwiftTUI/Modifiers/BorderModifier.swift @@ -9,7 +9,7 @@ /// /// This modifier reduces the available width for content by 2 characters /// (for the left and right border) to ensure the total width stays within bounds. -public struct BorderedView: TView { +public struct BorderedView: View { /// The content to wrap with a border. let content: Content @@ -99,9 +99,9 @@ extension BorderedView: Renderable { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Adds a border around this view. /// /// The border reserves 2 characters of width (left and right), @@ -127,18 +127,18 @@ extension TView { public func border( _ style: BorderStyle = .line, color: Color? = nil - ) -> some TView { + ) -> some View { BorderedView(content: self, style: style, color: color) } } -// MARK: - Legacy TViewModifier (kept for compatibility) +// MARK: - Legacy ViewModifier (kept for compatibility) /// A modifier that adds a border around a view. /// /// Note: This is the legacy implementation. The new `BorderedView` /// correctly handles available width constraints. -public struct BorderModifier: TViewModifier { +public struct BorderModifier: ViewModifier { /// The border style to use. public let style: BorderStyle diff --git a/Sources/SwiftTUI/Modifiers/DimmedModifier.swift b/Sources/SwiftTUI/Modifiers/DimmedModifier.swift index 0161610..2d371e1 100644 --- a/Sources/SwiftTUI/Modifiers/DimmedModifier.swift +++ b/Sources/SwiftTUI/Modifiers/DimmedModifier.swift @@ -9,7 +9,7 @@ /// /// This is useful for de-emphasizing background content when showing /// overlays, alerts, or dialogs. -public struct DimmedModifier: TView { +public struct DimmedModifier: View { /// The content to dim. let content: Content @@ -62,9 +62,9 @@ extension DimmedModifier: Renderable { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Applies a dimming effect to the view content. /// /// This reduces the visual intensity of the content using the ANSI dim @@ -81,7 +81,7 @@ extension TView { /// ``` /// /// - Returns: A view with the dimming effect applied. - public func dimmed() -> some TView { + public func dimmed() -> some View { DimmedModifier(content: self) } } diff --git a/Sources/SwiftTUI/Modifiers/FrameModifier.swift b/Sources/SwiftTUI/Modifiers/FrameModifier.swift index dd0a02a..4c3207a 100644 --- a/Sources/SwiftTUI/Modifiers/FrameModifier.swift +++ b/Sources/SwiftTUI/Modifiers/FrameModifier.swift @@ -25,7 +25,7 @@ public enum FrameDimension: Equatable, Sendable { /// /// This view handles min/max constraints and renders content with /// the appropriate available space. -public struct FlexibleFrameView: TView { +public struct FlexibleFrameView: View { let content: Content let minWidth: Int? let idealWidth: Int? @@ -171,7 +171,7 @@ extension FlexibleFrameView: Renderable { /// A modifier that constrains a view to a specific width and/or height. /// /// Content is aligned within the frame according to the specified alignment. -public struct FrameModifier: TViewModifier { +public struct FrameModifier: ViewModifier { /// The desired width (nil means intrinsic width). public let width: Int? @@ -246,9 +246,9 @@ public struct FrameModifier: TViewModifier { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Sets an explicit frame size for this view. /// /// The content is aligned within the frame according to the specified alignment. @@ -310,7 +310,7 @@ extension TView { idealHeight: Int? = nil, maxHeight: FrameDimension? = nil, alignment: Alignment = .center - ) -> some TView { + ) -> some View { FlexibleFrameView( content: self, minWidth: minWidth, diff --git a/Sources/SwiftTUI/Modifiers/KeyPressModifier.swift b/Sources/SwiftTUI/Modifiers/KeyPressModifier.swift index 5c38ce9..8a0d238 100644 --- a/Sources/SwiftTUI/Modifiers/KeyPressModifier.swift +++ b/Sources/SwiftTUI/Modifiers/KeyPressModifier.swift @@ -9,7 +9,7 @@ /// /// The handler returns a Bool indicating whether the event was consumed. /// If false is returned, the event continues to propagate to other handlers. -public struct KeyPressModifier: TView { +public struct KeyPressModifier: View { /// The content view. let content: Content @@ -47,9 +47,9 @@ extension KeyPressModifier: Renderable { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Adds a handler for key press events. /// /// The handler is called when any key is pressed while this view @@ -71,7 +71,7 @@ extension TView { /// /// - Parameter handler: The handler to call on key press. Returns true if handled. /// - Returns: A view that handles key presses. - public func onKeyPress(_ handler: @escaping (KeyEvent) -> Bool) -> some TView { + public func onKeyPress(_ handler: @escaping (KeyEvent) -> Bool) -> some View { KeyPressModifier(content: self, keys: nil, handler: handler) } diff --git a/Sources/SwiftTUI/Modifiers/LifecycleModifier.swift b/Sources/SwiftTUI/Modifiers/LifecycleModifier.swift index 30c3f21..af74cc6 100644 --- a/Sources/SwiftTUI/Modifiers/LifecycleModifier.swift +++ b/Sources/SwiftTUI/Modifiers/LifecycleModifier.swift @@ -80,7 +80,7 @@ public final class LifecycleTracker: @unchecked Sendable { // MARK: - OnAppear Modifier /// A modifier that executes an action when a view first appears. -public struct OnAppearModifier: TView { +public struct OnAppearModifier: View { /// The content view. let content: Content @@ -133,7 +133,7 @@ public final class DisappearCallbackStorage: @unchecked Sendable { } /// A modifier that executes an action when a view disappears. -public struct OnDisappearModifier: TView { +public struct OnDisappearModifier: View { /// The content view. let content: Content @@ -166,7 +166,7 @@ extension OnDisappearModifier: Renderable { /// A modifier that starts an async task when a view appears. /// /// The task is cancelled when the view disappears. -public struct TaskModifier: TView { +public struct TaskModifier: View { /// The content view. let content: Content @@ -255,9 +255,9 @@ private final class TokenGenerator: @unchecked Sendable { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Executes an action when this view first appears. /// /// The action is only executed once per view appearance. If the view @@ -266,8 +266,8 @@ extension TView { /// # Example /// /// ```swift - /// struct ContentView: TView { - /// var body: some TView { + /// struct ContentView: View { + /// var body: some View { /// Text("Hello") /// .onAppear { /// loadData() @@ -278,7 +278,7 @@ extension TView { /// /// - Parameter action: The action to execute. /// - Returns: A view that executes the action on appearance. - public func onAppear(perform action: @escaping () -> Void) -> some TView { + public func onAppear(perform action: @escaping () -> Void) -> some View { OnAppearModifier( content: self, token: TokenGenerator.shared.next(), @@ -293,8 +293,8 @@ extension TView { /// # Example /// /// ```swift - /// struct ContentView: TView { - /// var body: some TView { + /// struct ContentView: View { + /// var body: some View { /// Text("Hello") /// .onDisappear { /// cleanup() @@ -305,7 +305,7 @@ extension TView { /// /// - Parameter action: The action to execute. /// - Returns: A view that executes the action on disappearance. - public func onDisappear(perform action: @escaping () -> Void) -> some TView { + public func onDisappear(perform action: @escaping () -> Void) -> some View { OnDisappearModifier( content: self, token: TokenGenerator.shared.next(), @@ -320,8 +320,8 @@ extension TView { /// # Example /// /// ```swift - /// struct ContentView: TView { - /// var body: some TView { + /// struct ContentView: View { + /// var body: some View { /// Text("Loading...") /// .task { /// await fetchData() @@ -337,7 +337,7 @@ extension TView { public func task( priority: TaskPriority = .userInitiated, _ action: @escaping @Sendable () async -> Void - ) -> some TView { + ) -> some View { TaskModifier( content: self, token: TokenGenerator.shared.next(), diff --git a/Sources/SwiftTUI/Modifiers/OverlayModifier.swift b/Sources/SwiftTUI/Modifiers/OverlayModifier.swift index 551d6a3..84bf074 100644 --- a/Sources/SwiftTUI/Modifiers/OverlayModifier.swift +++ b/Sources/SwiftTUI/Modifiers/OverlayModifier.swift @@ -10,7 +10,7 @@ /// The overlay is rendered on top of the base content. Both views are rendered /// to their natural size, and the overlay is positioned according to the /// specified alignment within the base content's bounds. -public struct OverlayModifier: TView { +public struct OverlayModifier: View { /// The base content. let base: Base @@ -74,9 +74,9 @@ extension OverlayModifier: Renderable { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Layers the specified view on top of this view. /// /// The overlay is positioned according to the specified alignment @@ -95,10 +95,10 @@ extension TView { /// - alignment: The alignment of the overlay (default: .center). /// - content: The overlay content. /// - Returns: A view with the overlay applied. - public func overlay( + public func overlay( alignment: Alignment = .center, - @TViewBuilder content: () -> Overlay - ) -> some TView { + @ViewBuilder content: () -> Overlay + ) -> some View { OverlayModifier(base: self, overlay: content(), alignment: alignment) } } diff --git a/Sources/SwiftTUI/Modifiers/PaddingModifier.swift b/Sources/SwiftTUI/Modifiers/PaddingModifier.swift index 07cc886..ab89f58 100644 --- a/Sources/SwiftTUI/Modifiers/PaddingModifier.swift +++ b/Sources/SwiftTUI/Modifiers/PaddingModifier.swift @@ -81,7 +81,7 @@ public struct Edge: OptionSet, Sendable { } /// A modifier that adds padding around a view. -public struct PaddingModifier: TViewModifier { +public struct PaddingModifier: ViewModifier { /// The padding insets. public let insets: EdgeInsets @@ -112,9 +112,9 @@ public struct PaddingModifier: TViewModifier { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Adds padding on all sides. /// /// ```swift diff --git a/Sources/SwiftTUI/Modifiers/StatusBarItemsModifier.swift b/Sources/SwiftTUI/Modifiers/StatusBarItemsModifier.swift index 65e009c..edccb24 100644 --- a/Sources/SwiftTUI/Modifiers/StatusBarItemsModifier.swift +++ b/Sources/SwiftTUI/Modifiers/StatusBarItemsModifier.swift @@ -18,24 +18,24 @@ import Foundation /// # Example /// /// ```swift -/// struct MyView: TView { -/// var body: some TView { +/// struct MyView: View { +/// var body: some View { /// VStack { /// Text("Content") /// } /// .statusBarItems { -/// TStatusBarItem(shortcut: "n", label: "new") { addItem() } -/// TStatusBarItem(shortcut: Shortcut.escape, label: "back") { goBack() } +/// StatusBarItem(shortcut: "n", label: "new") { addItem() } +/// StatusBarItem(shortcut: Shortcut.escape, label: "back") { goBack() } /// } /// } /// } /// ``` -public struct StatusBarItemsModifier: TView { +public struct StatusBarItemsModifier: View { /// The content view. let content: Content /// The status bar items to display. - let items: [any TStatusBarItemProtocol] + let items: [any StatusBarItemProtocol] /// Optional context identifier for this view's items. /// If nil, items are set as global items. @@ -68,9 +68,9 @@ extension StatusBarItemsModifier: Renderable { } } -// MARK: - TView Extension +// MARK: - View Extension -extension TView { +extension View { /// Sets the status bar items for this view. /// /// When this view is rendered, the specified items will be displayed @@ -79,14 +79,14 @@ extension TView { /// # Example /// /// ```swift - /// struct MainView: TView { - /// var body: some TView { + /// struct MainView: View { + /// var body: some View { /// VStack { /// Text("Main Content") /// } /// .statusBarItems([ - /// TStatusBarItem(shortcut: "q", label: "quit"), - /// TStatusBarItem(shortcut: "h", label: "help") { showHelp() } + /// StatusBarItem(shortcut: "q", label: "quit"), + /// StatusBarItem(shortcut: "h", label: "help") { showHelp() } /// ]) /// } /// } @@ -94,7 +94,7 @@ extension TView { /// /// - Parameter items: The status bar items to display. /// - Returns: A view that sets the specified status bar items. - public func statusBarItems(_ items: [any TStatusBarItemProtocol]) -> some TView { + public func statusBarItems(_ items: [any StatusBarItemProtocol]) -> some View { StatusBarItemsModifier(content: self, items: items, context: nil) } @@ -103,14 +103,14 @@ extension TView { /// # Example /// /// ```swift - /// struct MainView: TView { - /// var body: some TView { + /// struct MainView: View { + /// var body: some View { /// VStack { /// Text("Main Content") /// } /// .statusBarItems { - /// TStatusBarItem(shortcut: "q", label: "quit") - /// TStatusBarItem(shortcut: "h", label: "help") { showHelp() } + /// StatusBarItem(shortcut: "q", label: "quit") + /// StatusBarItem(shortcut: "h", label: "help") { showHelp() } /// } /// } /// } @@ -119,8 +119,8 @@ extension TView { /// - Parameter builder: A closure that returns the status bar items. /// - Returns: A view that sets the specified status bar items. public func statusBarItems( - @StatusBarItemBuilder _ builder: () -> [any TStatusBarItemProtocol] - ) -> some TView { + @StatusBarItemBuilder _ builder: () -> [any StatusBarItemProtocol] + ) -> some View { StatusBarItemsModifier(content: self, items: builder(), context: nil) } @@ -133,14 +133,14 @@ extension TView { /// # Example /// /// ```swift - /// struct DialogView: TView { - /// var body: some TView { + /// struct DialogView: View { + /// var body: some View { /// Card { /// Text("Are you sure?") /// } /// .statusBarItems(context: "confirm-dialog") { - /// TStatusBarItem(shortcut: "y", label: "yes") { confirm() } - /// TStatusBarItem(shortcut: "n", label: "no") { cancel() } + /// StatusBarItem(shortcut: "y", label: "yes") { confirm() } + /// StatusBarItem(shortcut: "n", label: "no") { cancel() } /// } /// } /// } @@ -152,8 +152,8 @@ extension TView { /// - Returns: A view that pushes status bar items to the context stack. public func statusBarItems( context: String, - @StatusBarItemBuilder _ builder: () -> [any TStatusBarItemProtocol] - ) -> some TView { + @StatusBarItemBuilder _ builder: () -> [any StatusBarItemProtocol] + ) -> some View { StatusBarItemsModifier(content: self, items: builder(), context: context) } @@ -165,8 +165,8 @@ extension TView { /// - Returns: A view that pushes status bar items to the context stack. public func statusBarItems( context: String, - items: [any TStatusBarItemProtocol] - ) -> some TView { + items: [any StatusBarItemProtocol] + ) -> some View { StatusBarItemsModifier(content: self, items: items, context: context) } } diff --git a/Sources/SwiftTUI/Rendering/Renderable.swift b/Sources/SwiftTUI/Rendering/Renderable.swift index 22681d2..4ee3e28 100644 --- a/Sources/SwiftTUI/Rendering/Renderable.swift +++ b/Sources/SwiftTUI/Rendering/Renderable.swift @@ -70,14 +70,14 @@ public struct RenderContext { // MARK: - Rendering Helper -/// Renders any TView into a FrameBuffer by checking for Renderable conformance +/// Renders any View into a FrameBuffer by checking for Renderable conformance /// or recursively rendering the body. /// /// - Parameters: /// - view: The view to render. /// - context: The rendering context. /// - Returns: A FrameBuffer with the rendered content. -public func renderToBuffer(_ view: V, context: RenderContext) -> FrameBuffer { +public func renderToBuffer(_ view: V, context: RenderContext) -> FrameBuffer { if let renderable = view as? Renderable { return renderable.renderToBuffer(context: context) } diff --git a/Sources/SwiftTUI/Rendering/ViewRenderer.swift b/Sources/SwiftTUI/Rendering/ViewRenderer.swift index 35fffb7..3ab54c7 100644 --- a/Sources/SwiftTUI/Rendering/ViewRenderer.swift +++ b/Sources/SwiftTUI/Rendering/ViewRenderer.swift @@ -2,12 +2,12 @@ // ViewRenderer.swift // SwiftTUI // -// Renders TViews to terminal output via FrameBuffer. +// Renders Views to terminal output via FrameBuffer. // import Foundation -/// Renders TViews to terminal output. +/// Renders Views to terminal output. /// /// The `ViewRenderer` uses a two-pass approach: /// 1. Render the entire view tree into a `FrameBuffer` @@ -29,7 +29,7 @@ public final class ViewRenderer { /// - view: The view to render. /// - row: The starting row (1-based, default: 1). /// - column: The starting column (1-based, default: 1). - public func render(_ view: V, atRow row: Int = 1, column: Int = 1) { + public func render(_ view: V, atRow row: Int = 1, column: Int = 1) { let context = RenderContext(terminal: terminal) let buffer = renderToBuffer(view, context: context) flush(buffer, atRow: row, column: column) @@ -68,7 +68,7 @@ protocol ChildInfoProvider { } /// Creates a ChildInfo for a single view. -func makeChildInfo(for view: V, context: RenderContext) -> ChildInfo { +func makeChildInfo(for view: V, context: RenderContext) -> ChildInfo { if let spacer = view as? Spacer { return ChildInfo(buffer: nil, isSpacer: true, spacerMinLength: spacer.minLength) } @@ -358,9 +358,9 @@ extension ConditionalView: Renderable { } } -// MARK: - TViewArray Rendering +// MARK: - ViewArray Rendering -extension TViewArray: Renderable, ChildInfoProvider { +extension ViewArray: Renderable, ChildInfoProvider { public func renderToBuffer(context: RenderContext) -> FrameBuffer { FrameBuffer(verticallyStacking: childInfos(context: context).compactMap(\.buffer)) } @@ -372,7 +372,7 @@ extension TViewArray: Renderable, ChildInfoProvider { // MARK: - Optional Rendering -extension Optional: Renderable where Wrapped: TView { +extension Optional: Renderable where Wrapped: View { public func renderToBuffer(context: RenderContext) -> FrameBuffer { switch self { case .some(let view): @@ -395,7 +395,7 @@ extension Optional: Renderable where Wrapped: TView { /// - content: The content view. /// - context: The rendering context. /// - Returns: An array of ChildInfo. -func resolveChildInfos(from content: V, context: RenderContext) -> [ChildInfo] { +func resolveChildInfos(from content: V, context: RenderContext) -> [ChildInfo] { if let provider = content as? ChildInfoProvider { return provider.childInfos(context: context) } diff --git a/Sources/SwiftTUI/SwiftTUI.swift b/Sources/SwiftTUI/SwiftTUI.swift index e98ba6d..585adb4 100644 --- a/Sources/SwiftTUI/SwiftTUI.swift +++ b/Sources/SwiftTUI/SwiftTUI.swift @@ -13,7 +13,7 @@ public let swiftTUIVersion = "0.1.0" /// Executes a view closure and renders it once. /// -/// This is useful for simple CLI tools that don't need a full TApp. +/// This is useful for simple CLI tools that don't need a full App. /// /// # Example /// @@ -32,7 +32,7 @@ public let swiftTUIVersion = "0.1.0" /// /// - Parameter content: A ViewBuilder closure that defines the view to render. @discardableResult -public func renderOnce(@TViewBuilder content: () -> Content) -> Int { +public func renderOnce(@ViewBuilder content: () -> Content) -> Int { let view = content() let renderer = ViewRenderer() renderer.render(view) diff --git a/Sources/SwiftTUI/Views/Alert.swift b/Sources/SwiftTUI/Views/Alert.swift index 7c49e57..1e5e2d9 100644 --- a/Sources/SwiftTUI/Views/Alert.swift +++ b/Sources/SwiftTUI/Views/Alert.swift @@ -29,7 +29,7 @@ /// Alert(title: "Notice", message: "Operation complete!") /// } /// ``` -public struct Alert: TView { +public struct Alert: View { /// The alert title. public let title: String @@ -63,7 +63,7 @@ public struct Alert: TView { borderStyle: BorderStyle = .rounded, borderColor: Color? = nil, titleColor: Color? = nil, - @TViewBuilder actions: () -> Actions + @ViewBuilder actions: () -> Actions ) { self.title = title self.message = message @@ -73,7 +73,7 @@ public struct Alert: TView { self.actions = actions() } - public var body: some TView { + public var body: some View { VStack(spacing: 1) { // Title if let color = titleColor { @@ -136,10 +136,10 @@ extension Alert { /// - message: The alert message. /// - actions: The action views. /// - Returns: A warning-styled alert. - public static func warning( + public static func warning( title: String = "Warning", message: String, - @TViewBuilder actions: () -> A + @ViewBuilder actions: () -> A ) -> Alert { Alert( title: title, @@ -158,10 +158,10 @@ extension Alert { /// - message: The alert message. /// - actions: The action views. /// - Returns: An error-styled alert. - public static func error( + public static func error( title: String = "Error", message: String, - @TViewBuilder actions: () -> A + @ViewBuilder actions: () -> A ) -> Alert { Alert( title: title, @@ -180,10 +180,10 @@ extension Alert { /// - message: The alert message. /// - actions: The action views. /// - Returns: An info-styled alert. - public static func info( + public static func info( title: String = "Info", message: String, - @TViewBuilder actions: () -> A + @ViewBuilder actions: () -> A ) -> Alert { Alert( title: title, @@ -202,10 +202,10 @@ extension Alert { /// - message: The alert message. /// - actions: The action views. /// - Returns: A success-styled alert. - public static func success( + public static func success( title: String = "Success", message: String, - @TViewBuilder actions: () -> A + @ViewBuilder actions: () -> A ) -> Alert { Alert( title: title, diff --git a/Sources/SwiftTUI/Views/Box.swift b/Sources/SwiftTUI/Views/Box.swift index 6bf5c3b..55c5b31 100644 --- a/Sources/SwiftTUI/Views/Box.swift +++ b/Sources/SwiftTUI/Views/Box.swift @@ -24,7 +24,7 @@ /// } /// } /// ``` -public struct Box: TView { +public struct Box: View { /// The content of the box. public let content: Content @@ -43,14 +43,14 @@ public struct Box: TView { public init( _ borderStyle: BorderStyle = .line, color: Color? = nil, - @TViewBuilder content: () -> Content + @ViewBuilder content: () -> Content ) { self.content = content() self.borderStyle = borderStyle self.borderColor = color } - public var body: some TView { + public var body: some View { content.border(borderStyle, color: borderColor) } } diff --git a/Sources/SwiftTUI/Views/Button.swift b/Sources/SwiftTUI/Views/Button.swift index 3ca6461..854a66c 100644 --- a/Sources/SwiftTUI/Views/Button.swift +++ b/Sources/SwiftTUI/Views/Button.swift @@ -115,7 +115,7 @@ public struct ButtonStyle: Sendable { /// dismiss() /// } /// ``` -public struct Button: TView { +public struct Button: View { /// The button's label text. public let label: String @@ -352,7 +352,7 @@ extension Button { /// Button("OK", style: .primary) { confirm() } /// } /// ``` -public struct ButtonRow: TView { +public struct ButtonRow: View { private let buttons: [Button] private let spacing: Int diff --git a/Sources/SwiftTUI/Views/Card.swift b/Sources/SwiftTUI/Views/Card.swift index 94c716e..871b050 100644 --- a/Sources/SwiftTUI/Views/Card.swift +++ b/Sources/SwiftTUI/Views/Card.swift @@ -23,7 +23,7 @@ /// Text("Styled Card") /// } /// ``` -public struct Card: TView { +public struct Card: View { /// The content of the card. public let content: Content @@ -52,7 +52,7 @@ public struct Card: TView { borderColor: Color? = nil, backgroundColor: Color? = nil, padding: EdgeInsets = EdgeInsets(all: 1), - @TViewBuilder content: () -> Content + @ViewBuilder content: () -> Content ) { self.content = content() self.borderStyle = borderStyle @@ -61,7 +61,7 @@ public struct Card: TView { self.padding = padding } - public var body: some TView { + public var body: some View { // Build the card by composing modifiers if let bgColor = backgroundColor { content diff --git a/Sources/SwiftTUI/Views/Dialog.swift b/Sources/SwiftTUI/Views/Dialog.swift index 07a8fdc..ff91f46 100644 --- a/Sources/SwiftTUI/Views/Dialog.swift +++ b/Sources/SwiftTUI/Views/Dialog.swift @@ -41,7 +41,7 @@ /// } /// } /// ``` -public struct Dialog: TView { +public struct Dialog: View { /// The dialog title. public let title: String @@ -75,7 +75,7 @@ public struct Dialog: TView { borderColor: Color? = nil, titleColor: Color? = nil, padding: EdgeInsets = EdgeInsets(horizontal: 2, vertical: 1), - @TViewBuilder content: () -> Content + @ViewBuilder content: () -> Content ) { self.title = title self.borderStyle = borderStyle @@ -85,7 +85,7 @@ public struct Dialog: TView { self.content = content() } - public var body: some TView { + public var body: some View { Panel( title, borderStyle: borderStyle, @@ -109,11 +109,11 @@ extension Dialog { /// - titleColor: The title color (default: nil). /// - content: The dialog content. /// - Returns: A dialog with double-line borders. - public static func doubleLine( + public static func doubleLine( title: String, borderColor: Color? = nil, titleColor: Color? = nil, - @TViewBuilder content: () -> C + @ViewBuilder content: () -> C ) -> Dialog { Dialog( title: title, @@ -132,11 +132,11 @@ extension Dialog { /// - titleColor: The title color (default: nil). /// - content: The dialog content. /// - Returns: A dialog with heavy borders. - public static func heavy( + public static func heavy( title: String, borderColor: Color? = nil, titleColor: Color? = nil, - @TViewBuilder content: () -> C + @ViewBuilder content: () -> C ) -> Dialog { Dialog( title: title, @@ -150,7 +150,7 @@ extension Dialog { // MARK: - Modal Presentation Helper -extension TView { +extension View { /// Presents this view as a modal dialog over dimmed content. /// /// This is a convenience method that combines `.dimmed()` and `.overlay()` @@ -169,9 +169,9 @@ extension TView { /// /// - Parameter content: The modal content to display. /// - Returns: A view with the modal overlay. - public func modal( - @TViewBuilder content: () -> Modal - ) -> some TView { + public func modal( + @ViewBuilder content: () -> Modal + ) -> some View { self.dimmed() .overlay(alignment: .center, content: content) } diff --git a/Sources/SwiftTUI/Views/ForEach.swift b/Sources/SwiftTUI/Views/ForEach.swift index 3186250..bfa5a80 100644 --- a/Sources/SwiftTUI/Views/ForEach.swift +++ b/Sources/SwiftTUI/Views/ForEach.swift @@ -39,7 +39,7 @@ /// } /// } /// ``` -public struct ForEach: TView { +public struct ForEach: View { /// The underlying data collection. public let data: Data @@ -58,7 +58,7 @@ public struct ForEach, - @TViewBuilder content: @escaping (Data.Element) -> Content + @ViewBuilder content: @escaping (Data.Element) -> Content ) { self.data = data self.idKeyPath = id @@ -80,7 +80,7 @@ extension ForEach where Data.Element: Identifiable, ID == Data.Element.ID { /// - content: The closure that creates the view for each element. public init( _ data: Data, - @TViewBuilder content: @escaping (Data.Element) -> Content + @ViewBuilder content: @escaping (Data.Element) -> Content ) { self.data = data self.idKeyPath = \Data.Element.id @@ -98,7 +98,7 @@ extension ForEach where Data == Range, ID == Int { /// - content: The closure that creates the view for each index. public init( _ data: Range, - @TViewBuilder content: @escaping (Int) -> Content + @ViewBuilder content: @escaping (Int) -> Content ) { self.data = data self.idKeyPath = \.self diff --git a/Sources/SwiftTUI/Views/Menu.swift b/Sources/SwiftTUI/Views/Menu.swift index 510b933..31939d0 100644 --- a/Sources/SwiftTUI/Views/Menu.swift +++ b/Sources/SwiftTUI/Views/Menu.swift @@ -51,10 +51,10 @@ public struct MenuItem: Identifiable { /// # Interactive Example (with Binding) /// /// ```swift -/// struct ContentView: TView { -/// @TState var selection = 0 +/// struct ContentView: View { +/// @State var selection = 0 /// -/// var body: some TView { +/// var body: some View { /// Menu( /// title: "Main Menu", /// items: menuItems, @@ -66,7 +66,7 @@ public struct MenuItem: Identifiable { /// } /// } /// ``` -public struct Menu: TView { +public struct Menu: View { /// The menu title (optional). public let title: String? @@ -347,11 +347,11 @@ extension Menu: Renderable { /// /// This is a temporary solution until we have proper `@ViewBuilder` /// support for complex conditionals. -public struct AnyView: TView { +public struct AnyView: View { private let _render: (RenderContext) -> FrameBuffer /// Creates an AnyView wrapping the given view. - public init(_ view: V) { + public init(_ view: V) { self._render = { context in SwiftTUI.renderToBuffer(view, context: context) } @@ -368,7 +368,7 @@ extension AnyView: Renderable { } } -extension TView { +extension View { /// Wraps this view in an AnyView for type erasure. /// /// Use this when you need to return different view types from diff --git a/Sources/SwiftTUI/Views/Panel.swift b/Sources/SwiftTUI/Views/Panel.swift index 1ad3f5a..ca7ef4e 100644 --- a/Sources/SwiftTUI/Views/Panel.swift +++ b/Sources/SwiftTUI/Views/Panel.swift @@ -23,7 +23,7 @@ /// Text("Age: 30") /// } /// ``` -public struct Panel: TView { +public struct Panel: View { /// The title displayed in the top border. public let title: String @@ -57,7 +57,7 @@ public struct Panel: TView { borderColor: Color? = nil, titleColor: Color? = nil, padding: EdgeInsets = EdgeInsets(horizontal: 1, vertical: 0), - @TViewBuilder content: () -> Content + @ViewBuilder content: () -> Content ) { self.title = title self.content = content() diff --git a/Sources/SwiftTUI/Views/Spacer.swift b/Sources/SwiftTUI/Views/Spacer.swift index eeb04a8..6a62307 100644 --- a/Sources/SwiftTUI/Views/Spacer.swift +++ b/Sources/SwiftTUI/Views/Spacer.swift @@ -30,7 +30,7 @@ /// Text("Bottom") /// } /// ``` -public struct Spacer: TView { +public struct Spacer: View { /// The minimum length of the spacer (in characters/lines). public let minLength: Int? @@ -67,7 +67,7 @@ public struct Spacer: TView { /// // ───────────── /// // Section 2 /// ``` -public struct Divider: TView { +public struct Divider: View { /// The character used for the line. public var character: Character diff --git a/Sources/SwiftTUI/Views/Stacks.swift b/Sources/SwiftTUI/Views/Stacks.swift index 80a49e3..0dc0b87 100644 --- a/Sources/SwiftTUI/Views/Stacks.swift +++ b/Sources/SwiftTUI/Views/Stacks.swift @@ -30,7 +30,7 @@ /// Text("Longer text") /// } /// ``` -public struct VStack: TView { +public struct VStack: View { /// The horizontal alignment of the children. public let alignment: HorizontalAlignment @@ -49,7 +49,7 @@ public struct VStack: TView { public init( alignment: HorizontalAlignment = .leading, spacing: Int = 0, - @TViewBuilder content: () -> Content + @ViewBuilder content: () -> Content ) { self.alignment = alignment self.spacing = spacing @@ -84,7 +84,7 @@ public struct VStack: TView { /// Text("Right") /// } /// ``` -public struct HStack: TView { +public struct HStack: View { /// The vertical alignment of the children. public let alignment: VerticalAlignment @@ -103,7 +103,7 @@ public struct HStack: TView { public init( alignment: VerticalAlignment = .center, spacing: Int = 1, - @TViewBuilder content: () -> Content + @ViewBuilder content: () -> Content ) { self.alignment = alignment self.spacing = spacing @@ -130,7 +130,7 @@ public struct HStack: TView { /// Text(" Overlay ") /// } /// ``` -public struct ZStack: TView { +public struct ZStack: View { /// The alignment of the children. public let alignment: Alignment @@ -144,7 +144,7 @@ public struct ZStack: TView { /// - content: A ViewBuilder that defines the children. public init( alignment: Alignment = .center, - @TViewBuilder content: () -> Content + @ViewBuilder content: () -> Content ) { self.alignment = alignment self.content = content() diff --git a/Sources/SwiftTUI/Views/StatusBar.swift b/Sources/SwiftTUI/Views/StatusBar.swift index 64e71a9..849da44 100644 --- a/Sources/SwiftTUI/Views/StatusBar.swift +++ b/Sources/SwiftTUI/Views/StatusBar.swift @@ -11,7 +11,7 @@ import Foundation // MARK: - Status Bar Style /// The visual style of the status bar. -public enum TStatusBarStyle: Sendable { +public enum StatusBarStyle: Sendable { /// A single line with horizontal padding. case compact @@ -22,7 +22,7 @@ public enum TStatusBarStyle: Sendable { // MARK: - Status Bar Alignment /// The horizontal alignment of items within the status bar. -public enum TStatusBarAlignment: Sendable { +public enum StatusBarAlignment: Sendable { /// Items are aligned to the left (leading edge). case leading @@ -46,9 +46,9 @@ public enum TStatusBarAlignment: Sendable { /// # Example /// /// ```swift -/// TStatusBarItem(shortcut: .escape, label: "close") { dismiss() } -/// TStatusBarItem(shortcut: .arrowsUpDown, label: "nav") -/// TStatusBarItem(shortcut: .enter, label: "select", key: .enter) +/// StatusBarItem(shortcut: .escape, label: "close") { dismiss() } +/// StatusBarItem(shortcut: .arrowsUpDown, label: "nav") +/// StatusBarItem(shortcut: .enter, label: "select", key: .enter) /// ``` public enum Shortcut { // MARK: - Special Keys @@ -241,8 +241,8 @@ public enum Shortcut { /// A protocol for items that can be displayed in a status bar. /// /// Implement this protocol to create custom status bar items. -/// The default `TStatusBarItem` already conforms to this protocol. -public protocol TStatusBarItemProtocol: Sendable { +/// The default `StatusBarItem` already conforms to this protocol. +public protocol StatusBarItemProtocol: Sendable { /// The unique identifier for this item. var id: String { get } @@ -264,7 +264,7 @@ public protocol TStatusBarItemProtocol: Sendable { } // Default implementation for triggerKey matching -public extension TStatusBarItemProtocol { +public extension StatusBarItemProtocol { func matches(_ event: KeyEvent) -> Bool { guard let trigger = triggerKey else { return false } return event.key == trigger @@ -278,13 +278,13 @@ public extension TStatusBarItemProtocol { /// # Example /// /// ```swift -/// TStatusBarItem(shortcut: "q", label: "quit") { +/// StatusBarItem(shortcut: "q", label: "quit") { /// app.quit() /// } /// -/// TStatusBarItem(shortcut: "↑↓", label: "nav", key: .up) // Info only, no action +/// StatusBarItem(shortcut: "↑↓", label: "nav", key: .up) // Info only, no action /// ``` -public struct TStatusBarItem: TStatusBarItemProtocol, Identifiable { +public struct StatusBarItem: StatusBarItemProtocol, Identifiable { public let id: String public let shortcut: String public let label: String @@ -395,32 +395,32 @@ public struct TStatusBarItem: TStatusBarItemProtocol, Identifiable { /// Result builder for creating status bar items. @resultBuilder public struct StatusBarItemBuilder { - public static func buildBlock(_ components: [any TStatusBarItemProtocol]...) -> [any TStatusBarItemProtocol] { + public static func buildBlock(_ components: [any StatusBarItemProtocol]...) -> [any StatusBarItemProtocol] { components.flatMap { $0 } } - public static func buildArray(_ components: [[any TStatusBarItemProtocol]]) -> [any TStatusBarItemProtocol] { + public static func buildArray(_ components: [[any StatusBarItemProtocol]]) -> [any StatusBarItemProtocol] { components.flatMap { $0 } } - public static func buildOptional(_ component: [any TStatusBarItemProtocol]?) -> [any TStatusBarItemProtocol] { + public static func buildOptional(_ component: [any StatusBarItemProtocol]?) -> [any StatusBarItemProtocol] { component ?? [] } - public static func buildEither(first component: [any TStatusBarItemProtocol]) -> [any TStatusBarItemProtocol] { + public static func buildEither(first component: [any StatusBarItemProtocol]) -> [any StatusBarItemProtocol] { component } - public static func buildEither(second component: [any TStatusBarItemProtocol]) -> [any TStatusBarItemProtocol] { + public static func buildEither(second component: [any StatusBarItemProtocol]) -> [any StatusBarItemProtocol] { component } - public static func buildExpression(_ expression: any TStatusBarItemProtocol) -> [any TStatusBarItemProtocol] { + public static func buildExpression(_ expression: any StatusBarItemProtocol) -> [any StatusBarItemProtocol] { [expression] } } -// MARK: - TStatusBar View +// MARK: - StatusBar View /// A status bar that displays at the bottom of the terminal. /// @@ -433,31 +433,31 @@ public struct StatusBarItemBuilder { /// To set status bar items, use the environment: /// /// ```swift -/// struct MyView: TView { +/// struct MyView: View { /// @Environment(\.statusBar) var statusBar /// -/// var body: some TView { +/// var body: some View { /// VStack { /// Text("Hello") /// } /// .onAppear { /// statusBar.setItems([ -/// TStatusBarItem(shortcut: "q", label: "quit"), -/// TStatusBarItem(shortcut: "↑↓", label: "nav"), +/// StatusBarItem(shortcut: "q", label: "quit"), +/// StatusBarItem(shortcut: "↑↓", label: "nav"), /// ]) /// } /// } /// } /// ``` -public struct TStatusBar: TView { +public struct StatusBar: View { /// The items to display. - public let items: [any TStatusBarItemProtocol] + public let items: [any StatusBarItemProtocol] /// The visual style. - public let style: TStatusBarStyle + public let style: StatusBarStyle /// The horizontal alignment of items. - public let alignment: TStatusBarAlignment + public let alignment: StatusBarAlignment /// The highlight color for shortcut keys. public let highlightColor: Color @@ -474,9 +474,9 @@ public struct TStatusBar: TView { /// - highlightColor: The color for shortcut keys (default: `.cyan`). /// - labelColor: The color for labels (default: nil, terminal default). public init( - items: [any TStatusBarItemProtocol], - style: TStatusBarStyle = .compact, - alignment: TStatusBarAlignment = .justified, + items: [any StatusBarItemProtocol], + style: StatusBarStyle = .compact, + alignment: StatusBarAlignment = .justified, highlightColor: Color = .cyan, labelColor: Color? = nil ) { @@ -496,11 +496,11 @@ public struct TStatusBar: TView { /// - labelColor: The color for labels. /// - builder: A closure that returns items. public init( - style: TStatusBarStyle = .compact, - alignment: TStatusBarAlignment = .justified, + style: StatusBarStyle = .compact, + alignment: StatusBarAlignment = .justified, highlightColor: Color = .cyan, labelColor: Color? = nil, - @StatusBarItemBuilder _ builder: () -> [any TStatusBarItemProtocol] + @StatusBarItemBuilder _ builder: () -> [any StatusBarItemProtocol] ) { self.items = builder() self.style = style @@ -510,13 +510,13 @@ public struct TStatusBar: TView { } public var body: Never { - fatalError("TStatusBar renders via Renderable") + fatalError("StatusBar renders via Renderable") } } -// MARK: - TStatusBar Rendering +// MARK: - StatusBar Rendering -extension TStatusBar: Renderable { +extension StatusBar: Renderable { public func renderToBuffer(context: RenderContext) -> FrameBuffer { guard !items.isEmpty else { return FrameBuffer() @@ -683,7 +683,7 @@ extension TStatusBar: Renderable { // MARK: - Status Bar Height Helper -extension TStatusBar { +extension StatusBar { /// The height of the status bar in lines. public var height: Int { switch style { diff --git a/Sources/SwiftTUI/Views/Text.swift b/Sources/SwiftTUI/Views/Text.swift index f5986b4..95c85ba 100644 --- a/Sources/SwiftTUI/Views/Text.swift +++ b/Sources/SwiftTUI/Views/Text.swift @@ -21,7 +21,7 @@ /// Text("Colored") /// .foregroundColor(.red) /// ``` -public struct Text: TView { +public struct Text: View { /// The text to display. public let content: String diff --git a/Sources/SwiftTUIExample/Components/DemoSection.swift b/Sources/SwiftTUIExample/Components/DemoSection.swift index df3cbc5..fac655e 100644 --- a/Sources/SwiftTUIExample/Components/DemoSection.swift +++ b/Sources/SwiftTUIExample/Components/DemoSection.swift @@ -19,16 +19,16 @@ import SwiftTUI /// Text("Feature 2") /// } /// ``` -struct DemoSection: TView { +struct DemoSection: View { let title: String let content: Content - init(_ title: String, @TViewBuilder content: () -> Content) { + init(_ title: String, @ViewBuilder content: () -> Content) { self.title = title self.content = content() } - var body: some TView { + var body: some View { VStack(alignment: .leading) { Text(title) .bold() diff --git a/Sources/SwiftTUIExample/Components/HeaderView.swift b/Sources/SwiftTUIExample/Components/HeaderView.swift index bbaf129..d24e9ee 100644 --- a/Sources/SwiftTUIExample/Components/HeaderView.swift +++ b/Sources/SwiftTUIExample/Components/HeaderView.swift @@ -20,7 +20,7 @@ import SwiftTUI /// subtitle: "An optional description" /// ) /// ``` -struct HeaderView: TView { +struct HeaderView: View { let title: String let subtitle: String? @@ -29,7 +29,7 @@ struct HeaderView: TView { self.subtitle = subtitle } - var body: some TView { + var body: some View { VStack { HStack { Text(title) diff --git a/Sources/SwiftTUIExample/ContentView.swift b/Sources/SwiftTUIExample/ContentView.swift index 0ff1257..c9619c0 100644 --- a/Sources/SwiftTUIExample/ContentView.swift +++ b/Sources/SwiftTUIExample/ContentView.swift @@ -14,8 +14,8 @@ import SwiftTUI /// This view acts as a router, displaying the appropriate demo page /// based on the current state. It uses the `.statusBarItems()` modifier /// to declaratively set context-sensitive status bar items. -struct ContentView: TView { - var body: some TView { +struct ContentView: View { + var body: some View { let state = ExampleAppState.shared // Show current page based on state @@ -36,16 +36,16 @@ struct ContentView: TView { } } - @TViewBuilder - private func pageContent(for page: DemoPage) -> some TView { + @ViewBuilder + private func pageContent(for page: DemoPage) -> some View { switch page { case .menu: MainMenuPage() .statusBarItems { - TStatusBarItem(shortcut: Shortcut.arrowsUpDown, label: "nav") - TStatusBarItem(shortcut: Shortcut.enter, label: "select", key: .enter) - TStatusBarItem(shortcut: Shortcut.range("1", "6"), label: "jump") - TStatusBarItem(shortcut: Shortcut.quit, label: "quit") + StatusBarItem(shortcut: Shortcut.arrowsUpDown, label: "nav") + StatusBarItem(shortcut: Shortcut.enter, label: "select", key: .enter) + StatusBarItem(shortcut: Shortcut.range("1", "6"), label: "jump") + StatusBarItem(shortcut: Shortcut.quit, label: "quit") } case .textStyles: TextStylesPage() @@ -69,13 +69,13 @@ struct ContentView: TView { } /// Common status bar items for sub-pages. - private var subPageItems: [any TStatusBarItemProtocol] { + private var subPageItems: [any StatusBarItemProtocol] { [ - TStatusBarItem(shortcut: Shortcut.escape, label: "back") { + StatusBarItem(shortcut: Shortcut.escape, label: "back") { ExampleAppState.shared.currentPage = .menu }, - TStatusBarItem(shortcut: Shortcut.arrowsUpDown, label: "scroll"), - TStatusBarItem(shortcut: Shortcut.quit, label: "quit") + StatusBarItem(shortcut: Shortcut.arrowsUpDown, label: "scroll"), + StatusBarItem(shortcut: Shortcut.quit, label: "quit") ] } } diff --git a/Sources/SwiftTUIExample/Pages/ButtonsPage.swift b/Sources/SwiftTUIExample/Pages/ButtonsPage.swift index 87e7c9f..fe0fb68 100644 --- a/Sources/SwiftTUIExample/Pages/ButtonsPage.swift +++ b/Sources/SwiftTUIExample/Pages/ButtonsPage.swift @@ -15,8 +15,8 @@ import SwiftTUI /// - Plain style (no border) /// - ButtonRow for horizontal groups /// - Focus navigation with Tab -struct ButtonsPage: TView { - var body: some TView { +struct ButtonsPage: View { + var body: some View { VStack(spacing: 1) { HeaderView(title: "Buttons & Focus Demo") diff --git a/Sources/SwiftTUIExample/Pages/ColorsPage.swift b/Sources/SwiftTUIExample/Pages/ColorsPage.swift index a4533f9..0e5cbf7 100644 --- a/Sources/SwiftTUIExample/Pages/ColorsPage.swift +++ b/Sources/SwiftTUIExample/Pages/ColorsPage.swift @@ -14,8 +14,8 @@ import SwiftTUI /// - Bright colors (8 colors) /// - RGB colors (24-bit true color) /// - Semantic colors (primary, success, warning, error) -struct ColorsPage: TView { - var body: some TView { +struct ColorsPage: View { + var body: some View { VStack(spacing: 1) { HeaderView(title: "Colors Demo") diff --git a/Sources/SwiftTUIExample/Pages/ContainersPage.swift b/Sources/SwiftTUIExample/Pages/ContainersPage.swift index 5733396..abb9e3c 100644 --- a/Sources/SwiftTUIExample/Pages/ContainersPage.swift +++ b/Sources/SwiftTUIExample/Pages/ContainersPage.swift @@ -14,8 +14,8 @@ import SwiftTUI /// - Box (simple bordered container) /// - Panel (container with title in border) /// - All available border styles -struct ContainersPage: TView { - var body: some TView { +struct ContainersPage: View { + var body: some View { VStack(spacing: 1) { HeaderView(title: "Container Views Demo") diff --git a/Sources/SwiftTUIExample/Pages/LayoutPage.swift b/Sources/SwiftTUIExample/Pages/LayoutPage.swift index dd4a71c..dc585be 100644 --- a/Sources/SwiftTUIExample/Pages/LayoutPage.swift +++ b/Sources/SwiftTUIExample/Pages/LayoutPage.swift @@ -14,8 +14,8 @@ import SwiftTUI /// - HStack (horizontal stacking) /// - Spacer (flexible space) /// - Padding and frame modifiers -struct LayoutPage: TView { - var body: some TView { +struct LayoutPage: View { + var body: some View { VStack(spacing: 1) { HeaderView(title: "Layout System Demo") diff --git a/Sources/SwiftTUIExample/Pages/MainMenuPage.swift b/Sources/SwiftTUIExample/Pages/MainMenuPage.swift index 8721a74..456f397 100644 --- a/Sources/SwiftTUIExample/Pages/MainMenuPage.swift +++ b/Sources/SwiftTUIExample/Pages/MainMenuPage.swift @@ -11,8 +11,8 @@ import SwiftTUI /// /// Displays a centered menu with all available demos and /// feature highlight boxes at the bottom. -struct MainMenuPage: TView { - var body: some TView { +struct MainMenuPage: View { + var body: some View { let state = ExampleAppState.shared VStack(spacing: 1) { @@ -67,7 +67,7 @@ struct MainMenuPage: TView { } /// Creates a small feature highlight box. - private func featureBox(_ title: String, _ subtitle: String) -> some TView { + private func featureBox(_ title: String, _ subtitle: String) -> some View { VStack { Text(title) .bold() diff --git a/Sources/SwiftTUIExample/Pages/OverlaysPage.swift b/Sources/SwiftTUIExample/Pages/OverlaysPage.swift index b087fa9..a79862a 100644 --- a/Sources/SwiftTUIExample/Pages/OverlaysPage.swift +++ b/Sources/SwiftTUIExample/Pages/OverlaysPage.swift @@ -14,8 +14,8 @@ import SwiftTUI /// - `.dimmed()` modifier /// - `.modal()` helper /// - Note: The status bar is NOT dimmed by modals! -struct OverlaysPage: TView { - var body: some TView { +struct OverlaysPage: View { + var body: some View { // Background content with modal overlay backgroundContent .modal { @@ -34,7 +34,7 @@ struct OverlaysPage: TView { } } - var backgroundContent: some TView { + var backgroundContent: some View { VStack(spacing: 1) { HeaderView(title: "Overlays & Modals Demo") diff --git a/Sources/SwiftTUIExample/Pages/TextStylesPage.swift b/Sources/SwiftTUIExample/Pages/TextStylesPage.swift index 15fe7ae..fdb0fde 100644 --- a/Sources/SwiftTUIExample/Pages/TextStylesPage.swift +++ b/Sources/SwiftTUIExample/Pages/TextStylesPage.swift @@ -13,8 +13,8 @@ import SwiftTUI /// - Basic styles (bold, italic, underline, etc.) /// - Combined styles /// - Special effects (blink, inverted) -struct TextStylesPage: TView { - var body: some TView { +struct TextStylesPage: View { + var body: some View { VStack(spacing: 1) { HeaderView(title: "Text Styles Demo") diff --git a/Sources/SwiftTUIExample/main.swift b/Sources/SwiftTUIExample/main.swift index 6c28713..0c9b525 100644 --- a/Sources/SwiftTUIExample/main.swift +++ b/Sources/SwiftTUIExample/main.swift @@ -13,8 +13,8 @@ import SwiftTUI // MARK: - Main App /// The main example application. -struct ExampleApp: TApp { - var body: some TScene { +struct ExampleApp: App { + var body: some Scene { WindowGroup { ContentView() } diff --git a/Tests/SwiftTUITests/RenderingTests.swift b/Tests/SwiftTUITests/RenderingTests.swift index dfeb053..7ee592e 100644 --- a/Tests/SwiftTUITests/RenderingTests.swift +++ b/Tests/SwiftTUITests/RenderingTests.swift @@ -93,8 +93,8 @@ struct RenderingTests { @Test("Composite view renders through body") func compositeView() { - struct MyView: TView { - var body: some TView { + struct MyView: View { + var body: some View { VStack { Text("Hello") Text("World") diff --git a/Tests/SwiftTUITests/StatusBarTests.swift b/Tests/SwiftTUITests/StatusBarTests.swift index c1a8602..22774da 100644 --- a/Tests/SwiftTUITests/StatusBarTests.swift +++ b/Tests/SwiftTUITests/StatusBarTests.swift @@ -2,7 +2,7 @@ // StatusBarTests.swift // SwiftTUI // -// Tests for Shortcut constants, TStatusBarItem, StatusBarManager, and TStatusBar. +// Tests for Shortcut constants, StatusBarItem, StatusBarManager, and StatusBar. // import Testing @@ -120,16 +120,16 @@ struct ShortcutTests { @Suite("Status Bar Item Tests") struct StatusBarItemTests { - @Test("TStatusBarItem can be created") + @Test("StatusBarItem can be created") func itemCreation() { - let item = TStatusBarItem(shortcut: "q", label: "quit") + let item = StatusBarItem(shortcut: "q", label: "quit") #expect(item.shortcut == "q") #expect(item.label == "quit") #expect(item.id == "q-quit") } - @Test("TStatusBarItem with action") + @Test("StatusBarItem with action") func itemWithAction() { // Use a class to track execution since the closure is @Sendable final class ExecutionTracker: @unchecked Sendable { @@ -137,7 +137,7 @@ struct StatusBarItemTests { } let tracker = ExecutionTracker() - let item = TStatusBarItem(shortcut: "x", label: "execute") { + let item = StatusBarItem(shortcut: "x", label: "execute") { tracker.wasExecuted = true } @@ -145,30 +145,30 @@ struct StatusBarItemTests { #expect(tracker.wasExecuted == true) } - @Test("TStatusBarItem derives key from single character") + @Test("StatusBarItem derives key from single character") func deriveKeyFromCharacter() { - let item = TStatusBarItem(shortcut: "q", label: "quit") + let item = StatusBarItem(shortcut: "q", label: "quit") #expect(item.triggerKey == .character("q")) } - @Test("TStatusBarItem derives key from escape symbol") + @Test("StatusBarItem derives key from escape symbol") func deriveKeyFromEscape() { - let item = TStatusBarItem(shortcut: Shortcut.escape, label: "close") + let item = StatusBarItem(shortcut: Shortcut.escape, label: "close") #expect(item.triggerKey == .escape) } - @Test("TStatusBarItem derives key from enter symbol") + @Test("StatusBarItem derives key from enter symbol") func deriveKeyFromEnter() { - let item = TStatusBarItem(shortcut: Shortcut.enter, label: "confirm") + let item = StatusBarItem(shortcut: Shortcut.enter, label: "confirm") #expect(item.triggerKey == .enter) } - @Test("TStatusBarItem with explicit key") + @Test("StatusBarItem with explicit key") func itemWithExplicitKey() { - let item = TStatusBarItem( + let item = StatusBarItem( shortcut: "navigate", label: "nav", key: .up @@ -177,19 +177,19 @@ struct StatusBarItemTests { #expect(item.triggerKey == .up) } - @Test("TStatusBarItem informational has no trigger key") + @Test("StatusBarItem informational has no trigger key") func informationalItem() { // Multi-character shortcut without explicit key - let item = TStatusBarItem(shortcut: "↑↓", label: "nav") + let item = StatusBarItem(shortcut: "↑↓", label: "nav") // Arrow combinations don't have a single trigger key // but matches() handles them specially #expect(item.triggerKey == nil) } - @Test("TStatusBarItem matches character key") + @Test("StatusBarItem matches character key") func matchesCharacterKey() { - let item = TStatusBarItem(shortcut: "q", label: "quit") + let item = StatusBarItem(shortcut: "q", label: "quit") let event = KeyEvent(key: .character("q")) #expect(item.matches(event) == true) @@ -198,10 +198,10 @@ struct StatusBarItemTests { #expect(item.matches(wrongEvent) == false) } - @Test("TStatusBarItem case sensitive matching") + @Test("StatusBarItem case sensitive matching") func caseSensitiveMatching() { - let lowerItem = TStatusBarItem(shortcut: "n", label: "new") - let upperItem = TStatusBarItem(shortcut: "N", label: "New") + let lowerItem = StatusBarItem(shortcut: "n", label: "new") + let upperItem = StatusBarItem(shortcut: "N", label: "New") let lowerEvent = KeyEvent(key: .character("n")) let upperEvent = KeyEvent(key: .character("N")) @@ -213,9 +213,9 @@ struct StatusBarItemTests { #expect(upperItem.matches(lowerEvent) == false) } - @Test("TStatusBarItem matches arrow combinations") + @Test("StatusBarItem matches arrow combinations") func matchesArrowCombinations() { - let item = TStatusBarItem(shortcut: "↑↓", label: "nav") + let item = StatusBarItem(shortcut: "↑↓", label: "nav") let upEvent = KeyEvent(key: .up) let downEvent = KeyEvent(key: .down) @@ -226,9 +226,9 @@ struct StatusBarItemTests { #expect(item.matches(leftEvent) == false) } - @Test("TStatusBarItem matches all arrows") + @Test("StatusBarItem matches all arrows") func matchesAllArrows() { - let item = TStatusBarItem(shortcut: Shortcut.arrowsAll, label: "move") + let item = StatusBarItem(shortcut: Shortcut.arrowsAll, label: "move") #expect(item.matches(KeyEvent(key: .up)) == true) #expect(item.matches(KeyEvent(key: .down)) == true) @@ -254,8 +254,8 @@ struct StatusBarStateTests { let state = StatusBarState() state.setItems([ - TStatusBarItem(shortcut: "q", label: "quit"), - TStatusBarItem(shortcut: "h", label: "help") + StatusBarItem(shortcut: "q", label: "quit"), + StatusBarItem(shortcut: "h", label: "help") ]) #expect(state.currentItems.count == 2) @@ -267,8 +267,8 @@ struct StatusBarStateTests { let state = StatusBarState() state.setItems { - TStatusBarItem(shortcut: "q", label: "quit") - TStatusBarItem(shortcut: "h", label: "help") + StatusBarItem(shortcut: "q", label: "quit") + StatusBarItem(shortcut: "h", label: "help") } #expect(state.currentItems.count == 2) @@ -279,12 +279,12 @@ struct StatusBarStateTests { let state = StatusBarState() state.setItems([ - TStatusBarItem(shortcut: "q", label: "quit") + StatusBarItem(shortcut: "q", label: "quit") ]) state.push(context: "dialog", items: [ - TStatusBarItem(shortcut: Shortcut.escape, label: "close"), - TStatusBarItem(shortcut: Shortcut.enter, label: "confirm") + StatusBarItem(shortcut: Shortcut.escape, label: "close"), + StatusBarItem(shortcut: Shortcut.enter, label: "confirm") ]) #expect(state.currentItems.count == 2) @@ -296,7 +296,7 @@ struct StatusBarStateTests { let state = StatusBarState() state.push(context: "test") { - TStatusBarItem(shortcut: "a", label: "action") + StatusBarItem(shortcut: "a", label: "action") } #expect(state.currentItems.count == 1) @@ -308,11 +308,11 @@ struct StatusBarStateTests { let state = StatusBarState() state.setItems([ - TStatusBarItem(shortcut: "g", label: "global") + StatusBarItem(shortcut: "g", label: "global") ]) state.push(context: "temp", items: [ - TStatusBarItem(shortcut: "t", label: "temp") + StatusBarItem(shortcut: "t", label: "temp") ]) state.pop(context: "temp") @@ -326,11 +326,11 @@ struct StatusBarStateTests { let state = StatusBarState() state.push(context: "first", items: [ - TStatusBarItem(shortcut: "1", label: "first") + StatusBarItem(shortcut: "1", label: "first") ]) state.push(context: "second", items: [ - TStatusBarItem(shortcut: "2", label: "second") + StatusBarItem(shortcut: "2", label: "second") ]) // Top of stack is shown @@ -345,11 +345,11 @@ struct StatusBarStateTests { let state = StatusBarState() state.push(context: "same", items: [ - TStatusBarItem(shortcut: "a", label: "original") + StatusBarItem(shortcut: "a", label: "original") ]) state.push(context: "same", items: [ - TStatusBarItem(shortcut: "b", label: "replaced") + StatusBarItem(shortcut: "b", label: "replaced") ]) #expect(state.currentItems.count == 1) @@ -361,11 +361,11 @@ struct StatusBarStateTests { let state = StatusBarState() state.setItems([ - TStatusBarItem(shortcut: "g", label: "global") + StatusBarItem(shortcut: "g", label: "global") ]) state.push(context: "ctx", items: [ - TStatusBarItem(shortcut: "c", label: "context") + StatusBarItem(shortcut: "c", label: "context") ]) state.clearContexts() @@ -379,11 +379,11 @@ struct StatusBarStateTests { let state = StatusBarState() state.setItems([ - TStatusBarItem(shortcut: "g", label: "global") + StatusBarItem(shortcut: "g", label: "global") ]) state.push(context: "ctx", items: [ - TStatusBarItem(shortcut: "c", label: "context") + StatusBarItem(shortcut: "c", label: "context") ]) state.clear() @@ -403,7 +403,7 @@ struct StatusBarStateTests { let tracker = TriggerTracker() state.setItems([ - TStatusBarItem(shortcut: "t", label: "trigger") { + StatusBarItem(shortcut: "t", label: "trigger") { tracker.wasTriggered = true } ]) @@ -420,7 +420,7 @@ struct StatusBarStateTests { let state = StatusBarState() state.setItems([ - TStatusBarItem(shortcut: "a", label: "action") {} + StatusBarItem(shortcut: "a", label: "action") {} ]) let event = KeyEvent(key: .character("x")) @@ -478,7 +478,7 @@ struct StatusBarStateTests { func heightCompact() { let state = StatusBarState() state.style = .compact - state.setItems([TStatusBarItem(shortcut: "x", label: "test")]) + state.setItems([StatusBarItem(shortcut: "x", label: "test")]) #expect(state.height == 1) } @@ -486,21 +486,21 @@ struct StatusBarStateTests { func heightBordered() { let state = StatusBarState() state.style = .bordered - state.setItems([TStatusBarItem(shortcut: "x", label: "test")]) + state.setItems([StatusBarItem(shortcut: "x", label: "test")]) #expect(state.height == 3) } } -// MARK: - TStatusBar Tests +// MARK: - StatusBar Tests -@Suite("TStatusBar Tests") -struct TStatusBarTests { +@Suite("StatusBar Tests") +struct StatusBarTests { - @Test("TStatusBar can be created with items") + @Test("StatusBar can be created with items") func statusBarCreation() { - let statusBar = TStatusBar(items: [ - TStatusBarItem(shortcut: "q", label: "quit"), - TStatusBarItem(shortcut: "h", label: "help") + let statusBar = StatusBar(items: [ + StatusBarItem(shortcut: "q", label: "quit"), + StatusBarItem(shortcut: "h", label: "help") ]) #expect(statusBar.items.count == 2) @@ -509,19 +509,19 @@ struct TStatusBarTests { #expect(statusBar.highlightColor == .cyan) } - @Test("TStatusBar with style") + @Test("StatusBar with style") func statusBarWithStyle() { - let statusBar = TStatusBar( - items: [TStatusBarItem(shortcut: "x", label: "test")], + let statusBar = StatusBar( + items: [StatusBarItem(shortcut: "x", label: "test")], style: .bordered ) #expect(statusBar.style == .bordered) } - @Test("TStatusBar with custom colors") + @Test("StatusBar with custom colors") func statusBarWithColors() { - let statusBar = TStatusBar( + let statusBar = StatusBar( items: [], highlightColor: .yellow, labelColor: .green @@ -531,32 +531,32 @@ struct TStatusBarTests { #expect(statusBar.labelColor == .green) } - @Test("TStatusBar with builder") + @Test("StatusBar with builder") func statusBarWithBuilder() { - let statusBar = TStatusBar { - TStatusBarItem(shortcut: "a", label: "alpha") - TStatusBarItem(shortcut: "b", label: "beta") + let statusBar = StatusBar { + StatusBarItem(shortcut: "a", label: "alpha") + StatusBarItem(shortcut: "b", label: "beta") } #expect(statusBar.items.count == 2) } - @Test("TStatusBar compact height") + @Test("StatusBar compact height") func compactHeight() { - let statusBar = TStatusBar(items: [], style: .compact) + let statusBar = StatusBar(items: [], style: .compact) #expect(statusBar.height == 1) } - @Test("TStatusBar bordered height") + @Test("StatusBar bordered height") func borderedHeight() { - let statusBar = TStatusBar(items: [], style: .bordered) + let statusBar = StatusBar(items: [], style: .bordered) #expect(statusBar.height == 3) } - @Test("TStatusBar renders compact style") + @Test("StatusBar renders compact style") func rendersCompact() { - let statusBar = TStatusBar(items: [ - TStatusBarItem(shortcut: "q", label: "quit") + let statusBar = StatusBar(items: [ + StatusBarItem(shortcut: "q", label: "quit") ], style: .compact) let context = RenderContext(availableWidth: 80, availableHeight: 24) @@ -568,10 +568,10 @@ struct TStatusBarTests { #expect(content.contains("quit")) } - @Test("TStatusBar renders bordered style") + @Test("StatusBar renders bordered style") func rendersBordered() { - let statusBar = TStatusBar(items: [ - TStatusBarItem(shortcut: "h", label: "help") + let statusBar = StatusBar(items: [ + StatusBarItem(shortcut: "h", label: "help") ], style: .bordered) let context = RenderContext(availableWidth: 80, availableHeight: 24) @@ -583,9 +583,9 @@ struct TStatusBarTests { #expect(allContent.contains("▄") || allContent.contains("█") || allContent.contains("▀")) } - @Test("Empty TStatusBar returns empty buffer") + @Test("Empty StatusBar returns empty buffer") func emptyStatusBar() { - let statusBar = TStatusBar(items: []) + let statusBar = StatusBar(items: []) let context = RenderContext(availableWidth: 80, availableHeight: 24) let buffer = renderToBuffer(statusBar, context: context) @@ -593,11 +593,11 @@ struct TStatusBarTests { #expect(buffer.isEmpty) } - @Test("TStatusBar renders multiple items with separator") + @Test("StatusBar renders multiple items with separator") func multipleItemsWithSeparator() { - let statusBar = TStatusBar(items: [ - TStatusBarItem(shortcut: "a", label: "alpha"), - TStatusBarItem(shortcut: "b", label: "beta") + let statusBar = StatusBar(items: [ + StatusBarItem(shortcut: "a", label: "alpha"), + StatusBarItem(shortcut: "b", label: "beta") ]) let context = RenderContext(availableWidth: 80, availableHeight: 24) @@ -608,21 +608,21 @@ struct TStatusBarTests { #expect(content.contains("beta")) } - @Test("TStatusBar default alignment is justified") + @Test("StatusBar default alignment is justified") func defaultAlignmentIsJustified() { - let statusBar = TStatusBar(items: [ - TStatusBarItem(shortcut: "q", label: "quit") + let statusBar = StatusBar(items: [ + StatusBarItem(shortcut: "q", label: "quit") ]) #expect(statusBar.alignment == .justified) } - @Test("TStatusBar with leading alignment") + @Test("StatusBar with leading alignment") func leadingAlignment() { - let statusBar = TStatusBar( + let statusBar = StatusBar( items: [ - TStatusBarItem(shortcut: "a", label: "alpha"), - TStatusBarItem(shortcut: "b", label: "beta") + StatusBarItem(shortcut: "a", label: "alpha"), + StatusBarItem(shortcut: "b", label: "beta") ], alignment: .leading ) @@ -638,12 +638,12 @@ struct TStatusBarTests { #expect(!strippedLine.isEmpty) } - @Test("TStatusBar with trailing alignment") + @Test("StatusBar with trailing alignment") func trailingAlignment() { - let statusBar = TStatusBar( + let statusBar = StatusBar( items: [ - TStatusBarItem(shortcut: "a", label: "alpha"), - TStatusBarItem(shortcut: "b", label: "beta") + StatusBarItem(shortcut: "a", label: "alpha"), + StatusBarItem(shortcut: "b", label: "beta") ], alignment: .trailing ) @@ -657,12 +657,12 @@ struct TStatusBarTests { #expect(!buffer.isEmpty) } - @Test("TStatusBar with center alignment") + @Test("StatusBar with center alignment") func centerAlignment() { - let statusBar = TStatusBar( + let statusBar = StatusBar( items: [ - TStatusBarItem(shortcut: "a", label: "alpha"), - TStatusBarItem(shortcut: "b", label: "beta") + StatusBarItem(shortcut: "a", label: "alpha"), + StatusBarItem(shortcut: "b", label: "beta") ], alignment: .center ) @@ -676,13 +676,13 @@ struct TStatusBarTests { #expect(!buffer.isEmpty) } - @Test("TStatusBar with justified alignment distributes items") + @Test("StatusBar with justified alignment distributes items") func justifiedAlignment() { - let statusBar = TStatusBar( + let statusBar = StatusBar( items: [ - TStatusBarItem(shortcut: "a", label: "first"), - TStatusBarItem(shortcut: "b", label: "second"), - TStatusBarItem(shortcut: "c", label: "third") + StatusBarItem(shortcut: "a", label: "first"), + StatusBarItem(shortcut: "b", label: "second"), + StatusBarItem(shortcut: "c", label: "third") ], alignment: .justified ) @@ -699,12 +699,12 @@ struct TStatusBarTests { #expect(content.contains("third")) } - @Test("TStatusBar bordered with alignment") + @Test("StatusBar bordered with alignment") func borderedWithAlignment() { - let statusBar = TStatusBar( + let statusBar = StatusBar( items: [ - TStatusBarItem(shortcut: "a", label: "alpha"), - TStatusBarItem(shortcut: "b", label: "beta") + StatusBarItem(shortcut: "a", label: "alpha"), + StatusBarItem(shortcut: "b", label: "beta") ], style: .bordered, alignment: .center @@ -725,12 +725,12 @@ struct TStatusBarTests { @Suite("Status Bar Alignment Tests") struct StatusBarAlignmentTests { - @Test("TStatusBarAlignment enum values exist") + @Test("StatusBarAlignment enum values exist") func alignmentEnumValues() { - let leading: TStatusBarAlignment = .leading - let trailing: TStatusBarAlignment = .trailing - let center: TStatusBarAlignment = .center - let justified: TStatusBarAlignment = .justified + let leading: StatusBarAlignment = .leading + let trailing: StatusBarAlignment = .trailing + let center: StatusBarAlignment = .center + let justified: StatusBarAlignment = .justified #expect(leading != trailing) #expect(center != justified) @@ -738,8 +738,8 @@ struct StatusBarAlignmentTests { @Test("Single item with justified alignment is centered") func singleItemJustified() { - let statusBar = TStatusBar( - items: [TStatusBarItem(shortcut: "x", label: "only")], + let statusBar = StatusBar( + items: [StatusBarItem(shortcut: "x", label: "only")], alignment: .justified ) @@ -761,8 +761,8 @@ struct StatusBarItemBuilderTests { @Test("Builder buildBlock combines arrays") func builderCreatesArray() { let items = StatusBarItemBuilder.buildBlock( - [TStatusBarItem(shortcut: "a", label: "a")], - [TStatusBarItem(shortcut: "b", label: "b")] + [StatusBarItem(shortcut: "a", label: "a")], + [StatusBarItem(shortcut: "b", label: "b")] ) #expect(items.count == 2) @@ -770,17 +770,17 @@ struct StatusBarItemBuilderTests { @Test("Builder handles expression") func builderHandlesExpression() { - let item = TStatusBarItem(shortcut: "e", label: "expr") + let item = StatusBarItem(shortcut: "e", label: "expr") let result = StatusBarItemBuilder.buildExpression(item) #expect(result.count == 1) } - @Test("Builder works with TStatusBar initializer") + @Test("Builder works with StatusBar initializer") func builderWorksWithStatusBar() { - let statusBar = TStatusBar { - TStatusBarItem(shortcut: "x", label: "test") - TStatusBarItem(shortcut: "y", label: "test2") + let statusBar = StatusBar { + StatusBarItem(shortcut: "x", label: "test") + StatusBarItem(shortcut: "y", label: "test2") } #expect(statusBar.items.count == 2) @@ -796,7 +796,7 @@ struct StatusBarItemsModifierTests { func modifierCanBeApplied() { let view = Text("Content") .statusBarItems([ - TStatusBarItem(shortcut: "q", label: "quit") + StatusBarItem(shortcut: "q", label: "quit") ]) // View should be wrapped in modifier @@ -807,8 +807,8 @@ struct StatusBarItemsModifierTests { func modifierWithBuilder() { let view = Text("Content") .statusBarItems { - TStatusBarItem(shortcut: "a", label: "alpha") - TStatusBarItem(shortcut: "b", label: "beta") + StatusBarItem(shortcut: "a", label: "alpha") + StatusBarItem(shortcut: "b", label: "beta") } #expect(view is StatusBarItemsModifier) @@ -818,7 +818,7 @@ struct StatusBarItemsModifierTests { func modifierWithContext() { let view = Text("Dialog") .statusBarItems(context: "dialog") { - TStatusBarItem(shortcut: Shortcut.escape, label: "close") + StatusBarItem(shortcut: Shortcut.escape, label: "close") } #expect(view is StatusBarItemsModifier) @@ -834,7 +834,7 @@ struct StatusBarItemsModifierTests { // Create view with modifier let view = Text("Test") .statusBarItems { - TStatusBarItem(shortcut: "t", label: "test") + StatusBarItem(shortcut: "t", label: "test") } // Render with environment @@ -861,13 +861,13 @@ struct StatusBarItemsModifierTests { // Set global items first state.setItems([ - TStatusBarItem(shortcut: "g", label: "global") + StatusBarItem(shortcut: "g", label: "global") ]) // Create view with context modifier let view = Text("Dialog") .statusBarItems(context: "dialog") { - TStatusBarItem(shortcut: "d", label: "dialog-item") + StatusBarItem(shortcut: "d", label: "dialog-item") } // Render @@ -900,7 +900,7 @@ struct StatusBarItemsModifierTests { let view = Text("Hello World") .statusBarItems { - TStatusBarItem(shortcut: "x", label: "test") + StatusBarItem(shortcut: "x", label: "test") } let context = RenderContext( @@ -920,8 +920,8 @@ struct StatusBarItemsModifierTests { @Test("statusBarItems with array and context") func modifierWithArrayAndContext() { let items = [ - TStatusBarItem(shortcut: "y", label: "yes"), - TStatusBarItem(shortcut: "n", label: "no") + StatusBarItem(shortcut: "y", label: "yes"), + StatusBarItem(shortcut: "n", label: "no") ] let view = Text("Confirm?") @@ -939,14 +939,14 @@ struct StatusBarItemsModifierTests { // Outer sets global, inner pushes context let innerView = Text("Inner") .statusBarItems(context: "inner") { - TStatusBarItem(shortcut: "i", label: "inner-item") + StatusBarItem(shortcut: "i", label: "inner-item") } let outerView = VStack { innerView } .statusBarItems { - TStatusBarItem(shortcut: "o", label: "outer-item") + StatusBarItem(shortcut: "o", label: "outer-item") } let context = RenderContext( diff --git a/Tests/SwiftTUITests/TViewTests.swift b/Tests/SwiftTUITests/TViewTests.swift index dd8d692..f69e9ed 100644 --- a/Tests/SwiftTUITests/TViewTests.swift +++ b/Tests/SwiftTUITests/TViewTests.swift @@ -1,15 +1,15 @@ // -// TViewTests.swift +// ViewTests.swift // SwiftTUI // -// Tests for the TView protocol, ViewBuilder, and basic views. +// Tests for the View protocol, ViewBuilder, and basic views. // import Testing @testable import SwiftTUI -@Suite("TView Protocol Tests") -struct TViewTests { +@Suite("View Protocol Tests") +struct ViewTests { @Test("Text view can be created") func textViewCreation() { @@ -57,8 +57,8 @@ struct ViewBuilderTests { @Test("ViewBuilder with single view") func singleView() { - @TViewBuilder - func buildView() -> some TView { + @ViewBuilder + func buildView() -> some View { Text("Single") } @@ -68,8 +68,8 @@ struct ViewBuilderTests { @Test("ViewBuilder with two views") func twoViews() { - @TViewBuilder - func buildViews() -> some TView { + @ViewBuilder + func buildViews() -> some View { Text("First") Text("Second") } @@ -80,8 +80,8 @@ struct ViewBuilderTests { @Test("ViewBuilder with three views") func threeViews() { - @TViewBuilder - func buildViews() -> some TView { + @ViewBuilder + func buildViews() -> some View { Text("One") Text("Two") Text("Three")