diff --git a/Example/Example.xcodeproj/xcshareddata/xcschemes/OSUI_Example.xcscheme b/Example/Example.xcodeproj/xcshareddata/xcschemes/OSUI_Example.xcscheme
index 430e75275..f8c687531 100644
--- a/Example/Example.xcodeproj/xcshareddata/xcschemes/OSUI_Example.xcscheme
+++ b/Example/Example.xcodeproj/xcshareddata/xcschemes/OSUI_Example.xcscheme
@@ -63,6 +63,13 @@
ReferencedContainer = "container:Example.xcodeproj">
+
+
+
+
-
-
+ isEnabled = "NO">
diff --git a/Example/Example.xcodeproj/xcshareddata/xcschemes/OSUI_UITests.xcscheme b/Example/Example.xcodeproj/xcshareddata/xcschemes/OSUI_UITests.xcscheme
index 9c7f44871..382e37f12 100644
--- a/Example/Example.xcodeproj/xcshareddata/xcschemes/OSUI_UITests.xcscheme
+++ b/Example/Example.xcodeproj/xcshareddata/xcschemes/OSUI_UITests.xcscheme
@@ -42,13 +42,6 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
-
-
-
-
+
+
+
+
-
-
+ isEnabled = "NO">
+ isEnabled = "NO">
diff --git a/Example/OpenSwiftUIUITests/Shape/ShapeUITests.swift b/Example/OpenSwiftUIUITests/Shape/ShapeUITests.swift
index 8c65a7f2c..d128d45cf 100644
--- a/Example/OpenSwiftUIUITests/Shape/ShapeUITests.swift
+++ b/Example/OpenSwiftUIUITests/Shape/ShapeUITests.swift
@@ -13,6 +13,8 @@ struct ShapeUITests {
struct ContentView: View {
var body: some View {
Rectangle()
+ .fill(Color.red)
+ .frame(width: 100, height: 100, alignment: .center)
}
}
openSwiftUIAssertSnapshot(of: ContentView())
@@ -23,8 +25,24 @@ struct ShapeUITests {
struct ContentView: View {
var body: some View {
Circle()
+ .fill(Color.red)
+ .frame(width: 100, height: 100, alignment: .center)
}
}
- openSwiftUIAssertSnapshot(of: ContentView())
+ // FIXME
+ openSwiftUIAssertSnapshot(of: ContentView(), perceptualPrecision: 0.8)
+ }
+
+ @Test
+ func shadow() {
+ struct ContentView: View {
+ var body: some View {
+ Circle()
+ .fill(Color.red.shadow(.drop(color: .blue,radius: 5, x: 10, y: 10)))
+ .frame(width: 100, height: 100, alignment: .center)
+ }
+ }
+ // FIXME
+ openSwiftUIAssertSnapshot(of: ContentView(), perceptualPrecision: 0.8)
}
}
diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShadowStyle.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShadowStyle.swift
index 5a33532fb..3b4197db5 100644
--- a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShadowStyle.swift
+++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShadowStyle.swift
@@ -9,6 +9,7 @@ public import Foundation
// MARK: - ShadowStyle
+/// A style to use when rendering shadows.
@available(OpenSwiftUI_v4_0, *)
public struct ShadowStyle: Equatable, Sendable {
package struct Kind: OptionSet {
@@ -64,6 +65,20 @@ public struct ShadowStyle: Equatable, Sendable {
@_spi(Private)
public static let inner: ShadowStyle = .inner(radius: 0)
+ /// Creates a custom drop shadow style.
+ ///
+ /// Drop shadows draw behind the source content by blurring,
+ /// tinting and offsetting its per-pixel alpha values.
+ ///
+ /// - Parameters:
+ /// - color: The shadow's color.
+ /// - radius: The shadow's size.
+ /// - x: A horizontal offset you use to position the shadow
+ /// relative to this view.
+ /// - y: A vertical offset you use to position the shadow
+ /// relative to this view.
+ ///
+ /// - Returns: A new shadow style.
public static func drop(
color: Color = .init(.sRGBLinear, white: 0, opacity: 0.33),
radius: CGFloat,
@@ -76,6 +91,20 @@ public struct ShadowStyle: Equatable, Sendable {
)
}
+ /// Creates a custom inner shadow style.
+ ///
+ /// Inner shadows draw on top of the source content by blurring,
+ /// tinting, inverting and offsetting its per-pixel alpha values.
+ ///
+ /// - Parameters:
+ /// - color: The shadow's color.
+ /// - radius: The shadow's size.
+ /// - x: A horizontal offset you use to position the shadow
+ /// relative to this view.
+ /// - y: A vertical offset you use to position the shadow
+ /// relative to this view.
+ ///
+ /// - Returns: A new shadow style.
public static func inner(
color: Color = .init(.sRGBLinear, white: 0, opacity: 0.55),
radius: CGFloat,
@@ -151,6 +180,17 @@ extension ShadowStyle {
@available(OpenSwiftUI_v4_0, *)
extension ShapeStyle {
+
+ /// Applies the specified shadow effect to the shape style.
+ ///
+ /// For example, you can create a rectangle that adds a drop shadow to
+ /// the ``ShapeStyle/red`` shape style.
+ ///
+ /// Rectangle().fill(.red.shadow(.drop(radius: 2, y: 3)))
+ ///
+ /// - Parameter style: The shadow style to apply.
+ ///
+ /// - Returns: A new shape style that uses the specified shadow style.
@inlinable
public func shadow(_ style: ShadowStyle) -> some ShapeStyle {
return _ShadowShapeStyle(style: self, shadowStyle: style)
@@ -159,6 +199,23 @@ extension ShapeStyle {
@available(OpenSwiftUI_v4_0, *)
extension ShapeStyle where Self == AnyShapeStyle {
+
+ /// Returns a shape style that applies the specified shadow style to the
+ /// current style.
+ ///
+ /// In most contexts the current style is the foreground, but not always.
+ /// For example, when setting the value of the background style, that
+ /// becomes the current implicit style.
+ ///
+ /// The following example creates a circle filled with the current
+ /// foreground style that uses an inner shadow:
+ ///
+ /// Circle().fill(.shadow(.inner(radius: 1, y: 1)))
+ ///
+ /// - Parameter style: The shadow style to apply.
+ ///
+ /// - Returns: A new shape style based on the current style that uses the
+ /// specified shadow style.
@_alwaysEmitIntoClient
public static func shadow(_ style: ShadowStyle) -> some ShapeStyle {
return _ShadowShapeStyle(
diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleRendering.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleRendering.swift
index bbf5df84a..54c38f842 100644
--- a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleRendering.swift
+++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ShapeStyleRendering.swift
@@ -187,6 +187,13 @@ package struct _ShapeStyle_RenderedShape {
default:
_openSwiftUIUnimplementedFailure()
}
+ // FIXME
+ for effect in style.effects {
+ guard case let .shadow(shadow) = effect.kind else {
+ continue
+ }
+ addEffect(.filter(.shadow(shadow)))
+ }
_openSwiftUIUnimplementedWarning()
}