From a26da04fee9ade0ea23032f4ece3c0e58ad0bd20 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 8 Feb 2026 22:31:15 +0800 Subject: [PATCH 1/8] Update ImplicitShapeStyle --- .../OpenSwiftUICore/Shape/ShapeStyle/ImplicitShapeStyle.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ImplicitShapeStyle.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ImplicitShapeStyle.swift index 0a2f11947..6dba0c7ee 100644 --- a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ImplicitShapeStyle.swift +++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ImplicitShapeStyle.swift @@ -2,10 +2,11 @@ // ImplicitShapeStyle.swift // OpenSwiftUICore // -// Audited for 6.0.87 +// Audited for 6.5.4 // Status: Complete /// A shape style representing the implicit base of style modifiers. +@available(OpenSwiftUI_v1_0, *) @frozen public struct _ImplicitShapeStyle: ShapeStyle, PrimitiveShapeStyle { @inlinable From 2a03e91828a37295231f3e7a7f4c46586bfd7579 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 8 Feb 2026 23:32:45 +0800 Subject: [PATCH 2/8] Implement BackgroundStyle --- .../Shape/ShapeStyle/BackgroundStyle.swift | 285 +++++++++++++++++- 1 file changed, 276 insertions(+), 9 deletions(-) diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/BackgroundStyle.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/BackgroundStyle.swift index 03b5bd66a..85bbcd36d 100644 --- a/Sources/OpenSwiftUICore/Shape/ShapeStyle/BackgroundStyle.swift +++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/BackgroundStyle.swift @@ -2,11 +2,64 @@ // BackgroundStyle.swift // OpenSwiftUICore // -// Audited for 6.0.87 -// Status: WIP +// Audited for 6.5.4 +// Status: Complete // ID: C7D4771CFE453D905E7BCD5A907D32EB (SwiftUICore) +import OpenAttributeGraphShims + +// MARK: - Color + background + +@available(OpenSwiftUI_v1_0, *) +extension Color { + private struct BackgroundColorProvider: ColorProvider { + func resolve(in environment: EnvironmentValues) -> Color.Resolved { + Color.systemBackgroundColor( + info: environment.backgroundInfo, + context: environment.backgroundContext, + scheme: environment.colorScheme + ) + } + } + + package static var _background: Color { + Color(provider: BackgroundColorProvider()) + } + + package static func systemBackgroundColor( + info: BackgroundInfo, + context: BackgroundContext, + scheme: ColorScheme + ) -> Color.Resolved { + switch scheme { + case .light: + let combined = info.groupCount + context.rawValue + if combined & 1 == 0 { + return .white + } else { + return Color.Resolved(red: 242 / 255, green: 242 / 255, blue: 247 / 255) + } + case .dark: + let level = info.layer + info.groupCount + switch level { + case 0: + return .black + case 1: + return Color.Resolved(red: 28 / 255, green: 28 / 255, blue: 30 / 255) + case 2: + return Color.Resolved(red: 44 / 255, green: 44 / 255, blue: 46 / 255) + default: + return Color.Resolved(red: 58 / 255, green: 58 / 255, blue: 60 / 255) + } + } + } +} + +// MARK: - ShapeStyle + BackgroundStyle + +@available(OpenSwiftUI_v2_0, *) extension ShapeStyle where Self == BackgroundStyle { + /// The background style in the current context. /// /// Access this value to get the style OpenSwiftUI uses for the background @@ -21,35 +74,249 @@ extension ShapeStyle where Self == BackgroundStyle { } } +// MARK: - BackgroundStyle + +/// The background style in the current context. +/// +/// You can also use ``ShapeStyle/background`` to construct this style. +@available(OpenSwiftUI_v2_0, *) @frozen public struct BackgroundStyle: ShapeStyle { static let shared = AnyShapeStyle(BackgroundStyle()) - + + /// Creates a background style instance. @inlinable public init() {} - - // TODO + + nonisolated public static func _makeView(view: _GraphValue<_ShapeView>, inputs: _ViewInputs) -> _ViewOutputs where S: Shape { + legacyMakeShapeView(view: view, inputs: inputs) + } + + private func base(level: Int, env: EnvironmentValues) -> some ShapeStyle { + var info = env.backgroundInfo + info.groupCount += level + let resolved = Color.systemBackgroundColor( + info: info, + context: env.backgroundContext, + scheme: env.colorScheme + ) + return resolved + } + + @available(OpenSwiftUI_v3_0, *) + public func _apply(to shape: inout _ShapeStyle_Shape) { + if !shape.activeRecursiveStyles.contains(.background) { + if let style = shape.environment.currentBackgroundStyle { + shape.activeRecursiveStyles.formUnion(.background) + style._apply(to: &shape) + if shape.activeRecursiveStyles.contains(.background) { + shape.activeRecursiveStyles.subtract(.background) + } + return + } + } + switch shape.operation { + case let .resolveStyle(name, _) where name == .background: + HierarchicalShapeStyle.quaternary._apply(to: &shape) + case let .resolveStyle(name, levels): + guard !levels.isEmpty else { return } + var pack = shape.stylePack + for level in levels { + var innerShape = shape + base(level: level, env: shape.environment)._apply(to: &innerShape) + let style = innerShape.stylePack[name, 0] + shape.stylePack[name, level] = style + } + shape.result = .pack(shape.stylePack) + case let .prepareText(level): + base(level: level, env: shape.environment)._apply(to: &shape) + case let .fallbackColor(level): + base(level: level, env: shape.environment)._apply(to: &shape) + case .copyStyle, .primaryStyle: + shape.result = .style(AnyShapeStyle(BackgroundStyle())) + case let .modifyBackground(level): + shape.environment.backgroundInfo.groupCount += level + case .multiLevel: + shape.result = .bool(false) + } + } + + public static func _apply(to type: inout _ShapeStyle_ShapeType) { + type.result = .bool(true) + } } +// MARK: - View + _addingBackgroundGroup / _addingBackgroundLayer + +@available(OpenSwiftUI_v1_0, *) +extension View { + + /// Add a background group, affecting the default background color. + @MainActor + @preconcurrency + public func _addingBackgroundGroup() -> some View { + transformEnvironment(\.backgroundInfo) { $0.groupCount += 1 } + } + + /// Add a background layer, affecting the default background color. + @MainActor + @preconcurrency + public func _addingBackgroundLayer() -> some View { + transformEnvironment(\.backgroundInfo) { $0.layer += 1 } + } + + /// Sets the specified style to render backgrounds within the view. + /// + /// The following example uses this modifier to set the + /// ``EnvironmentValues/backgroundStyle`` environment value to a + /// ``ShapeStyle/blue`` color that includes a subtle ``Color/gradient``. + /// OpenSwiftUI fills the ``Circle`` shape that acts as a background element + /// with this style: + /// + /// Image(systemName: "swift") + /// .padding() + /// .background(in: Circle()) + /// .backgroundStyle(.blue.gradient) + /// + /// To restore the default background style, set the + /// ``EnvironmentValues/backgroundStyle`` environment value to + /// `nil` using the ``View/environment(_:_:)`` modifer: + /// + /// .environment(\.backgroundStyle, nil) + /// + @available(OpenSwiftUI_v4_0, *) + @inlinable + nonisolated public func backgroundStyle(_ style: S) -> some View where S: ShapeStyle { + return modifier(_EnvironmentBackgroundStyleModifier(style: style)) + } +} + + // MARK: - BackgroundStyleKey private struct BackgroundStyleKey: EnvironmentKey { static let defaultValue: AnyShapeStyle? = nil } -// MARK: - EnvironmentValues + ForegroundStyle +// MARK: - BackgroundContextKey + +private struct BackgroundContextKey: EnvironmentKey { + static let defaultValue: BackgroundContext = .normal +} + +// MARK: - BackgroundInfoKey + +private struct BackgroundInfoKey: EnvironmentKey { + static let defaultValue = BackgroundInfo(layer: 0, groupCount: 0) +} + +// MARK: - EnvironmentValues + BackgroundStyle extension EnvironmentValues { - package var backgroundStyle: AnyShapeStyle? { + + /// An optional style that overrides the default system background + /// style when set. + @available(OpenSwiftUI_v4_0, *) + public var backgroundStyle: AnyShapeStyle? { get { self[BackgroundStyleKey.self] } set { self[BackgroundStyleKey.self] = newValue } } - + package var currentBackgroundStyle: AnyShapeStyle? { backgroundStyle } - + package var effectiveBackgroundStyle: AnyShapeStyle { currentBackgroundStyle ?? BackgroundStyle.shared } + + package var backgroundContext: BackgroundContext { + get { self[BackgroundContextKey.self] } + set { self[BackgroundContextKey.self] = newValue } + } + + package var backgroundInfo: BackgroundInfo { + get { self[BackgroundInfoKey.self] } + set { self[BackgroundInfoKey.self] = newValue } + } +} + +// MARK: - BackgroundContext + +package enum BackgroundContext: Int, CaseIterable { + case normal + case grouped +} + +// MARK: - BackgroundInfo + +package struct BackgroundInfo: Equatable { + package var layer: Int + + package var groupCount: Int + + package init(layer: Int, groupCount: Int) { + self.layer = layer + self.groupCount = groupCount + } } + +// MARK: - _EnvironmentBackgroundStyleModifier + +@available(OpenSwiftUI_v4_0, *) +@frozen +@MainActor +@preconcurrency +public struct _EnvironmentBackgroundStyleModifier: ViewInputsModifier, PrimitiveViewModifier where S: ShapeStyle { + @usableFromInline + var style: S + + @inlinable + init(style: S) { + self.style = style + } + + nonisolated public static func _makeViewInputs( + modifier: _GraphValue, + inputs: inout _ViewInputs + ) { + _makeInputs(modifier: modifier, inputs: &inputs.base) + } + + nonisolated private static func _makeInputs( + modifier: _GraphValue, + inputs: inout _GraphInputs + ) { + inputs.environment = Attribute( + ChildEnvironment( + modifier: modifier.value, + environment: inputs.environment + ) + ) + } + + nonisolated public static func _makeViewList( + modifier: _GraphValue, + inputs: _ViewListInputs, + body: @escaping (_Graph, _ViewListInputs) -> _ViewListOutputs + ) -> _ViewListOutputs { + var inputs = inputs + _makeInputs(modifier: modifier, inputs: &inputs.base) + return body(_Graph(), inputs) + } + + private struct ChildEnvironment: Rule, AsyncAttribute { + @Attribute var modifier: _EnvironmentBackgroundStyleModifier + @Attribute var environment: EnvironmentValues + + var value: EnvironmentValues { + var environment = environment + let style = modifier.style.copyStyle(name: .background, in: environment) + environment.backgroundStyle = style + return environment + } + } +} + +@available(*, unavailable) +extension _EnvironmentBackgroundStyleModifier: Sendable {} From bda9d099e27663944539f4362d50025b697fb2ea Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 9 Feb 2026 00:25:08 +0800 Subject: [PATCH 3/8] Add InterpolatedShapeStyle --- .../ShapeStyle/InterpolatedShapeStyle.swift | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Sources/OpenSwiftUICore/Shape/ShapeStyle/InterpolatedShapeStyle.swift diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/InterpolatedShapeStyle.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/InterpolatedShapeStyle.swift new file mode 100644 index 000000000..a63a6ab7d --- /dev/null +++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/InterpolatedShapeStyle.swift @@ -0,0 +1,68 @@ +// +// InterpolatedShapeStyle.swift +// OpenSwiftUICore +// +// Audited for 6.5.4 +// Status: Complete + +// MARK: - InterpolatedShapeStyle + +package struct InterpolatedShapeStyle: ShapeStyle where From: ShapeStyle, To: ShapeStyle { + package var from: From + package var to: To + package var progress: Float + + package init(from: From, to: To, progress: Float) { + self.from = from + self.to = to + self.progress = progress + } + + package func _apply(to shape: inout _ShapeStyle_Shape) { + if progress == 0.0 { + from._apply(to: &shape) + return + } + if progress == 1.0 { + to._apply(to: &shape) + return + } + switch shape.operation { + case .prepareText: + shape.result = .preparedText(.foregroundKeyColor) + case .resolveStyle: + var innerShape = shape + from._apply(to: &innerShape) + if case .pack = innerShape.result { + let fromPack = innerShape.stylePack + to._apply(to: &shape) + if case .pack = shape.result { + let toPack = shape.stylePack + var fromData = fromPack.animatableData + let toData = toPack.animatableData + var diff = toData + diff -= fromData + diff.scale(by: Double(progress)) + fromData += diff + var resultPack = fromPack + resultPack.animatableData = fromData + shape.result = .pack(resultPack) + } else { + shape.result = .pack(fromPack) + } + } else { + to._apply(to: &shape) + } + case .fallbackColor, .copyStyle: + to._apply(to: &shape) + case .modifyBackground, .primaryStyle: + break + case .multiLevel: + from._apply(to: &shape) + if case let .bool(value) = shape.result, value { + return + } + to._apply(to: &shape) + } + } +} From 6db316e1d399f0449efdf87fcb1eb585c55fc418 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 9 Feb 2026 00:27:05 +0800 Subject: [PATCH 4/8] Update OffsetShapeStyle --- .../Shape/ShapeStyle/OffsetShapeStyle.swift | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/OffsetShapeStyle.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/OffsetShapeStyle.swift index 10c63b963..fc8bf827c 100644 --- a/Sources/OpenSwiftUICore/Shape/ShapeStyle/OffsetShapeStyle.swift +++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/OffsetShapeStyle.swift @@ -2,8 +2,8 @@ // OffsetShapeStyle.swift // OpenSwiftUICore // -// Audited for 6.0.87 -// Status: Blocked by _ShapeStyle_Pack +// Audited for 6.5.4 +// Status: Complete package struct OffsetShapeStyle: ShapeStyle where Base: ShapeStyle { package var base: Base @@ -12,34 +12,38 @@ package struct OffsetShapeStyle: ShapeStyle where Base: ShapeStyle { package func _apply(to shape: inout _ShapeStyle_Shape) { switch shape.operation { - case .prepareText(let level): - shape.operation = .prepareText(level: offset + level) - base._apply(to: &shape) - case let .resolveStyle(_, levels): - let _ = levels.lowerBound + offset ..< levels.upperBound + offset - // Blocked by _ShapeStyle_Pack - case .multiLevel: - shape.result = .bool(false) - case .fallbackColor(let level): - shape.operation = .fallbackColor(level: offset + level) - base._apply(to: &shape) - case .copyStyle: - base.mapCopiedStyle(in: &shape) { style in - style.offset(by: offset) - } - case .primaryStyle: - shape.result = .style(AnyShapeStyle(base)) - case .modifyBackground(let level): - shape.operation = .modifyBackground(level: offset + level) - base._apply(to: &shape) + case let .prepareText(level): + shape.operation = .prepareText(level: offset + level) + base._apply(to: &shape) + case let .resolveStyle(name, levels): + let offsetLevels = levels.lowerBound + offset ..< levels.upperBound + offset + shape.stylePack.adjustLevelIndices(of: name, by: offset) + shape.operation = .resolveStyle(name: name, levels: offsetLevels) + base._apply(to: &shape) + if case var .pack(resultPack) = shape.result { + resultPack.adjustLevelIndices(of: name, by: -offset) + shape.result = .pack(resultPack) + } + case .multiLevel: + shape.result = .bool(false) + case let .fallbackColor(level): + shape.operation = .fallbackColor(level: offset + level) + base._apply(to: &shape) + case .copyStyle: + base.mapCopiedStyle(in: &shape) { style in + style.offset(by: offset) + } + case .primaryStyle: + shape.result = .style(AnyShapeStyle(base)) + case let .modifyBackground(level): + shape.operation = .modifyBackground(level: offset + level) + base._apply(to: &shape) } } package static func _apply(to type: inout _ShapeStyle_ShapeType) { Base._apply(to: &type) } - - package typealias Resolved = Never } extension ShapeStyle { From 81c627cbf9482ebd57864f410b18647911a6b6e2 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 9 Feb 2026 00:33:01 +0800 Subject: [PATCH 5/8] Update ShapeStyleShape and name --- .../OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleName.swift | 4 ++-- .../OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleShape.swift | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleName.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleName.swift index dedf92c9a..1951f2d62 100644 --- a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleName.swift +++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleName.swift @@ -1,8 +1,8 @@ // -// ShapeStyle_Name.swift +// ShapeStyleName.swift // OpenSwiftUICore // -// Audited for 6.0.87 +// Audited for 6.5.4 // Status: Complete package enum _ShapeStyle_Name: UInt8, Equatable, Comparable { diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleShape.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleShape.swift index 58e9b209c..259144579 100644 --- a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleShape.swift +++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleShape.swift @@ -1,14 +1,15 @@ // -// ShapeStyle_Shape.swift +// ShapeStyleShape.swift // OpenSwiftUICore // -// Audited for 6.0.87 -// Status: Blocked by Color / ColorProvider / Color.Resolved +// Audited for 6.5.4 +// Status: Complete package import Foundation // MARK: - _ShapeStyle_Shape +@available(OpenSwiftUI_v3_0, *) public struct _ShapeStyle_Shape { package enum Operation { case prepareText(level: Int) From 032a3e72f419deb0c9ad48e87e458d6f4a89b089 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 9 Feb 2026 00:50:41 +0800 Subject: [PATCH 6/8] Implement ForegroundStyle --- .../Shape/ShapeStyle/ForegroundStyle.swift | 362 +++++++++++++++++- .../ShapeStyle/ForegroundStyleModifier.swift | 251 ------------ .../Shape/ShapeStyle/ShapeStylePair.swift | 141 +++++++ 3 files changed, 495 insertions(+), 259 deletions(-) delete mode 100644 Sources/OpenSwiftUICore/Shape/ShapeStyle/ForegroundStyleModifier.swift create mode 100644 Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStylePair.swift diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ForegroundStyle.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ForegroundStyle.swift index d9226edcc..694eeb384 100644 --- a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ForegroundStyle.swift +++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ForegroundStyle.swift @@ -2,12 +2,179 @@ // ForegroundStyle.swift // OpenSwiftUICore // -// Audited for 6.0.87 +// Audited for 6.5.4 // Status: Complete // ID: BEFE9363F68E039B4AB6422B8AA4535A (SwiftUICore) package import OpenAttributeGraphShims +// MARK: - View + foregroundStyle + +@available(OpenSwiftUI_v3_0, *) +extension View { + /// Sets a view's foreground elements to use a given style. + /// + /// Use this method to style + /// foreground content like text, shapes, and template images + /// (including symbols): + /// + /// HStack { + /// Image(systemName: "triangle.fill") + /// Text("Hello, world!") + /// RoundedRectangle(cornerRadius: 5) + /// .frame(width: 40, height: 20) + /// } + /// .foregroundStyle(.teal) + /// + /// The example above creates a row of ``ShapeStyle/teal`` foreground + /// elements: + /// + /// ![A screenshot of a teal triangle, string, and rounded + /// rectangle.](View-foregroundStyle-1) + /// + /// You can use any style that conforms to the ``ShapeStyle`` protocol, + /// like the ``ShapeStyle/teal`` color in the example above, or the + /// ``ShapeStyle/linearGradient(colors:startPoint:endPoint:)`` gradient + /// shown below: + /// + /// Text("Gradient Text") + /// .font(.largeTitle) + /// .foregroundStyle( + /// .linearGradient( + /// colors: [.yellow, .blue], + /// startPoint: .top, + /// endPoint: .bottom + /// ) + /// ) + /// + /// ![A screenshot of the words Gradient Text, with letters that + /// appear yellow at the top, and transition to blue + /// toward the bottom.](View-foregroundStyle-2) + /// + /// > Tip: If you want to fill a single ``Shape`` instance with a style, + /// use the ``Shape/fill(style:)`` shape modifier instead because it's more + /// efficient. + /// + /// OpenSwiftUI creates a context-dependent render for a given style. + /// For example, a ``Color`` that you load from an asset catalog + /// can have different light and dark appearances, while some styles + /// also vary by platform. + /// + /// Hierarchical foreground styles like ``ShapeStyle/secondary`` + /// don't impose a style of their own, but instead modify other styles. + /// In particular, they modify the primary + /// level of the current foreground style to the degree given by + /// the hierarchical style's name. + /// To find the current foreground style to modify, OpenSwiftUI looks for + /// the innermost containing style that you apply with the + /// `foregroundStyle(_:)` or the ``View/foregroundColor(_:)`` modifier. + /// If you haven't specified a style, OpenSwiftUI uses the default foreground + /// style, as in the following example: + /// + /// VStack(alignment: .leading) { + /// Label("Primary", systemImage: "1.square.fill") + /// Label("Secondary", systemImage: "2.square.fill") + /// .foregroundStyle(.secondary) + /// } + /// + /// ![A screenshot of two labels with the text primary and secondary. + /// The first appears in a brighter shade than the + /// second, both in a grayscale color.](View-foregroundStyle-3) + /// + /// If you add a foreground style on the enclosing + /// ``VStack``, the hierarchical styling responds accordingly: + /// + /// VStack(alignment: .leading) { + /// Label("Primary", systemImage: "1.square.fill") + /// Label("Secondary", systemImage: "2.square.fill") + /// .foregroundStyle(.secondary) + /// } + /// .foregroundStyle(.blue) + /// + /// ![A screenshot of two labels with the text primary and secondary. + /// The first appears in a brighter shade than the + /// second, both tinted blue.](View-foregroundStyle-4) + /// + /// When you apply a custom style to a view, the view disables the vibrancy + /// effect for foreground elements in that view, or in any of its child + /// views, that it would otherwise gain from adding a background material + /// --- for example, using the ``View/background(_:ignoresSafeAreaEdges:)`` + /// modifier. However, hierarchical styles applied to the default foreground + /// don't disable vibrancy. + /// + /// - Parameter style: The color or pattern to use when filling in the + /// foreground elements. To indicate a specific value, use ``Color`` or + /// ``ShapeStyle/image(_:sourceRect:scale:)``, or one of the gradient + /// types, like + /// ``ShapeStyle/linearGradient(colors:startPoint:endPoint:)``. To set a + /// style that’s relative to the containing view's style, use one of the + /// semantic styles, like ``ShapeStyle/primary``. + /// + /// - Returns: A view that uses the given foreground style. + @inlinable + nonisolated public func foregroundStyle(_ style: S) -> some View where S: ShapeStyle { + modifier(_ForegroundStyleModifier(style: style)) + } + + /// Sets the primary and secondary levels of the foreground + /// style in the child view. + /// + /// OpenSwiftUI uses these styles when rendering child views + /// that don't have an explicit rendering style, like images, + /// text, shapes, and so on. + /// + /// Symbol images within the view hierarchy use the + /// ``SymbolRenderingMode/palette`` rendering mode when you apply this + /// modifier, if you don't explicitly specify another mode. + /// + /// - Parameters: + /// - primary: The primary color or pattern to use when filling in + /// the foreground elements. To indicate a specific value, use ``Color`` + /// or ``ShapeStyle/image(_:sourceRect:scale:)``, or one of the gradient + /// types, like + /// ``ShapeStyle/linearGradient(colors:startPoint:endPoint:)``. To set a + /// style that’s relative to the containing view's style, use one of the + /// semantic styles, like ``ShapeStyle/primary``. + /// - secondary: The secondary color or pattern to use when + /// filling in the foreground elements. + /// + /// - Returns: A view that uses the given foreground styles. + @inlinable + nonisolated public func foregroundStyle(_ primary: S1, _ secondary: S2) -> some View where S1: ShapeStyle, S2: ShapeStyle { + modifier(_ForegroundStyleModifier2(primary: primary, secondary: secondary)) + } + + /// Sets the primary, secondary, and tertiary levels of + /// the foreground style. + /// + /// OpenSwiftUI uses these styles when rendering child views + /// that don't have an explicit rendering style, like images, + /// text, shapes, and so on. + /// + /// Symbol images within the view hierarchy use the + /// ``SymbolRenderingMode/palette`` rendering mode when you apply this + /// modifier, if you don't explicitly specify another mode. + /// + /// - Parameters: + /// - primary: The primary color or pattern to use when filling in + /// the foreground elements. To indicate a specific value, use ``Color`` + /// or ``ShapeStyle/image(_:sourceRect:scale:)``, or one of the gradient + /// types, like + /// ``ShapeStyle/linearGradient(colors:startPoint:endPoint:)``. To set a + /// style that’s relative to the containing view's style, use one of the + /// semantic styles, like ``ShapeStyle/primary``. + /// - secondary: The secondary color or pattern to use when + /// filling in the foreground elements. + /// - tertiary: The tertiary color or pattern to use when + /// filling in the foreground elements. + /// + /// - Returns: A view that uses the given foreground styles. + @inlinable + nonisolated public func foregroundStyle(_ primary: S1, _ secondary: S2, _ tertiary: S3) -> some View where S1: ShapeStyle, S2: ShapeStyle, S3: ShapeStyle { + modifier(_ForegroundStyleModifier3(primary: primary, secondary: secondary, tertiary: tertiary)) + } +} + // MARK: - ForegroundStyleKey private struct ForegroundStyleKey: EnvironmentKey { @@ -27,18 +194,18 @@ extension EnvironmentValues { get { self[ForegroundStyleKey.self] } set { self[ForegroundStyleKey.self] = newValue } } - + package var defaultForegroundStyle: AnyShapeStyle? { get { self[DefaultForegroundStyleKey.self] } set { self[DefaultForegroundStyleKey.self] = newValue } } - + package var currentForegroundStyle: AnyShapeStyle? { foregroundStyle ?? defaultForegroundStyle } - + package var _effectiveForegroundStyle: AnyShapeStyle { - currentForegroundStyle ?? .init(.foreground) + currentForegroundStyle ?? HierarchicalShapeStyle.sharedPrimary } } @@ -52,8 +219,180 @@ extension _ViewInputs { } } +// MARK: - _DefaultForegroundStyleModifier + +struct _DefaultForegroundStyleModifier