From b783b3900219e8e16e488899dc4d99c25c810f74 Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 19 Nov 2025 00:55:30 +0800 Subject: [PATCH 1/7] Add Group interface --- Sources/OpenSwiftUICore/View/Group.swift | 384 ++++++++++++++++++ .../OpenSwiftUICore/View/Input/ViewList.swift | 5 - 2 files changed, 384 insertions(+), 5 deletions(-) create mode 100644 Sources/OpenSwiftUICore/View/Group.swift diff --git a/Sources/OpenSwiftUICore/View/Group.swift b/Sources/OpenSwiftUICore/View/Group.swift new file mode 100644 index 000000000..073435020 --- /dev/null +++ b/Sources/OpenSwiftUICore/View/Group.swift @@ -0,0 +1,384 @@ +// +// Group.swift +// OpenSwiftUICore +// +// Audited for 6.5.4 +// Status: Blocked by _ViewListOutputs +// ID: C1B8B6896BB94C69479F427820712D02 (SwiftUICore) + +package import OpenAttributeGraphShims + +// MARK: - Group + +/// A type that collects multiple instances of a content type --- like views, +/// scenes, or commands --- into a single unit. +/// +/// Use a group to collect multiple views into a single instance, without +/// affecting the layout of those views, like an ``OpenSwiftUI/HStack``, +/// ``OpenSwiftUI/VStack``, or ``OpenSwiftUI/Section`` would. After creating a group, +/// any modifier you apply to the group affects all of that group's members. +/// For example, the following code applies the ``OpenSwiftUI/Font/headline`` +/// font to three views in a group. +/// +/// Group { +/// Text("OpenSwiftUI") +/// Text("Combine") +/// Text("Swift System") +/// } +/// .font(.headline) +/// +/// Because you create a group of views with a ``OpenSwiftUI/ViewBuilder``, you can +/// use the group's initializer to produce different kinds of views from a +/// conditional, and then optionally apply modifiers to them. The following +/// example uses a `Group` to add a navigation bar title, +/// regardless of the type of view the conditional produces: +/// +/// Group { +/// if isLoggedIn { +/// WelcomeView() +/// } else { +/// LoginView() +/// } +/// } +/// .navigationBarTitle("Start") +/// +/// The modifier applies to all members of the group --- and not to the group +/// itself. For example, if you apply ``View/onAppear(perform:)`` to the above +/// group, it applies to all of the views produced by the `if isLoggedIn` +/// conditional, and it executes every time `isLoggedIn` changes. +/// +/// Because a group of views itself is a view, you can compose a group within +/// other view builders, including nesting within other groups. This allows you +/// to add large numbers of views to different view builder containers. The +/// following example uses a `Group` to collect 10 ``OpenSwiftUI/Text`` instances, +/// meaning that the vertical stack's view builder returns only two views --- +/// the group, plus an additional ``OpenSwiftUI/Text``: +/// +/// var body: some View { +/// VStack { +/// Group { +/// Text("1") +/// Text("2") +/// Text("3") +/// Text("4") +/// Text("5") +/// Text("6") +/// Text("7") +/// Text("8") +/// Text("9") +/// Text("10") +/// } +/// Text("11") +/// } +/// } +/// +/// You can initialize groups with several types other than ``OpenSwiftUI/View``, +/// such as ``OpenSwiftUI/Scene`` and ``OpenSwiftUI/ToolbarContent``. The closure you +/// provide to the group initializer uses the corresponding builder type +/// (``OpenSwiftUI/SceneBuilder``, ``OpenSwiftUI/ToolbarContentBuilder``, and so on), +/// and the capabilities of these builders vary between types. For example, +/// you can use groups to return large numbers of scenes or toolbar content +/// instances, but not to return different scenes or toolbar content based +/// on conditionals. +@available(OpenSwiftUI_v1_0, *) +@frozen +public struct Group { + + public typealias Body = Never + + @usableFromInline + package var content: Content + + @_disfavoredOverload + @_alwaysEmitIntoClient + internal init(_content: Content) { + self.content = _content + } +} + +@available(*, unavailable) +extension Group: Sendable {} + +@available(OpenSwiftUI_v1_0, *) +extension Group { + + + @available(OpenSwiftUI_v1_0, *) + @_alwaysEmitIntoClient + public static func _make(content: Content) -> Group { + self.init(_content: content) + } +} + +@available(OpenSwiftUI_v1_0, *) +extension Group: View, MultiView, PrimitiveView where Content: View { + + /// Creates a group of views. + /// - Parameter content: A ``OpenSwiftUI/ViewBuilder`` that produces the views + /// to group. + @inlinable + nonisolated public init(@ViewBuilder content: () -> Content) { + self.content = content() + } + + nonisolated public static func _makeViewList( + view: _GraphValue, + inputs: _ViewListInputs + ) -> _ViewListOutputs { + _VariadicView.Tree.makeDebuggableViewList( + view: view.unsafeBitCast(to: _VariadicView.Tree.self), + inputs: inputs + ) + } + + @available(OpenSwiftUI_v2_0, *) + nonisolated public static func _viewListCount(inputs: _ViewListCountInputs) -> Int? { + Content._viewListCount(inputs: inputs) + } +} + +// MARK: - _ViewListOutputs + Group [WIP] + +extension _ViewListOutputs { + package static func sectionListOutputs( + _ outputs: [_ViewListOutputs], + inputs: _ViewListInputs + ) -> _ViewListOutputs { + _openSwiftUIUnimplementedFailure() + } + + package static func groupViewList( + parent: _GraphValue, + footer: Attribute