From 4519bc7bf3f08d18c584a8a8d97961b46275b7c8 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 25 Oct 2026 17:41:43 +0800 Subject: [PATCH 1/9] feat(stepper): add Stepper and supporting API stubs --- ...llowsWindowActivationEventsResponder.swift | 16 +- .../View/Control/Stepper/Stepper.swift | 1334 +++++++++++++++++ .../View/TextField/TextField.swift | 35 + 3 files changed, 1383 insertions(+), 2 deletions(-) create mode 100644 Sources/OpenSwiftUI/View/Control/Stepper/Stepper.swift create mode 100644 Sources/OpenSwiftUI/View/TextField/TextField.swift diff --git a/Sources/OpenSwiftUI/Event/Responder/AllowsWindowActivationEventsResponder.swift b/Sources/OpenSwiftUI/Event/Responder/AllowsWindowActivationEventsResponder.swift index 0eef282da..f74c56208 100644 --- a/Sources/OpenSwiftUI/Event/Responder/AllowsWindowActivationEventsResponder.swift +++ b/Sources/OpenSwiftUI/Event/Responder/AllowsWindowActivationEventsResponder.swift @@ -6,10 +6,22 @@ // Status: WIP // ID: 302179F1EB9AE99B83C6A183C0B4143E (?) -#if os(macOS) @_spi(ForOpenSwiftUIOnly) -import OpenSwiftUICore +public import OpenSwiftUICore + +// MARK: - View + allowsWindowActivationEvents [TBA] + +@available(OpenSwiftUI_v6_0, *) +@available(tvOS, unavailable) +@available(watchOS, unavailable) +extension View { + nonisolated public func allowsWindowActivationEvents(_ value: Bool? = true) -> some View { + _openSwiftUIUnimplementedWarning() + return self + } +} +#if os(macOS) // TODO: AllowsWindowActivationEventsResponder class AllowsWindowActivationEventsResponder: DefaultLayoutViewResponder { var value: Bool? diff --git a/Sources/OpenSwiftUI/View/Control/Stepper/Stepper.swift b/Sources/OpenSwiftUI/View/Control/Stepper/Stepper.swift new file mode 100644 index 000000000..de475d7e1 --- /dev/null +++ b/Sources/OpenSwiftUI/View/Control/Stepper/Stepper.swift @@ -0,0 +1,1334 @@ +// +// Stepper.swift +// OpenSwiftUI +// +// Audited for 6.5.4 +// Status: Complete +// ID: FF6E896BA929580F70ACD453368504D0 (SwiftUI) + +public import Foundation +@_spi(ForOpenSwiftUIOnly) +public import OpenSwiftUICore + +// MARK: - Stepper + +/// A control that performs increment and decrement actions. +/// +/// Use a stepper control when you want the user to have granular control while +/// incrementing or decrementing a value. For example, you can use a stepper +/// to: +/// +/// * Change a value up or down by `1`. +/// * Operate strictly over a prescribed range. +/// * Step by specific amounts over a stepper's range of possible values. +/// +/// The example below uses an array that holds a number of ``Color`` values, +/// a local state variable, `value`, to set the control's background +/// color, and title label. When the user clicks or taps the stepper's +/// increment or decrement buttons, OpenSwiftUI executes the relevant +/// closure that updates `value`, wrapping the `value` to prevent overflow. +/// OpenSwiftUI then re-renders the view, updating the text and background +/// color to match the current index: +/// +/// struct StepperView: View { +/// @State private var value = 0 +/// let colors: [Color] = [.orange, .red, .gray, .blue, +/// .green, .purple, .pink] +/// +/// func incrementStep() { +/// value += 1 +/// if value >= colors.count { value = 0 } +/// } +/// +/// func decrementStep() { +/// value -= 1 +/// if value < 0 { value = colors.count - 1 } +/// } +/// +/// var body: some View { +/// Stepper { +/// Text("Value: \(value) Color: \(colors[value].description)") +/// } onIncrement: { +/// incrementStep() +/// } onDecrement: { +/// decrementStep() +/// } +/// .padding(5) +/// .background(colors[value]) +/// } +/// } +/// +/// ![A view displaying a stepper that uses a text view for stepper's title and that changes the background color of its view when incremented or decremented. The view selects the new background color from a predefined array of colors using the stepper's value as the index.](OpenSwiftUI-Stepper-increment-decrement-closures) +/// +/// The following example shows a stepper that displays the effect of +/// incrementing or decrementing a value with the step size of `step` with +/// the bounds defined by `range`: +/// +/// struct StepperView: View { +/// @State private var value = 0 +/// let step = 5 +/// let range = 1...50 +/// +/// var body: some View { +/// Stepper( +/// value: $value, +/// in: range, +/// step: step +/// ) { +/// Text("Current: \(value) in \(range.description) " + +/// "stepping by \(step)") +/// } +/// .padding(10) +/// } +/// } +/// +/// ![A view displaying a stepper with a step size of five, and a prescribed range of 1 though 50.](OpenSwiftUI-Stepper-value-step-range) +@available(OpenSwiftUI_v1_0, *) +@available(OpenSwiftUI_watchOS_v4_0, *) +@available(tvOS, unavailable) +public struct Stepper