Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions Example/OpenSwiftUIUITests/Layout/Separator/DividerUITests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// DividerUITests.swift
// OpenSwiftUIUITests

import Testing
import SnapshotTesting

@MainActor
@Suite(.snapshots(record: .never, diffTool: diffTool))
struct DividerUITests {

// MARK: - Basic Spacer in HStack

@Test("TODO: Fix colorScheme issue")
func dividerWithColorScheme() {
struct ContentView: View {
var body: some View {
HStack {
VStack {
VStack {
Color.red
Divider()
Color.blue
}
HStack {
Color.red
Divider()
Color.blue
}
}.colorScheme(.light)
VStack {
HStack {
Color.red
Divider()
Color.blue
}
VStack {
Color.red
Divider()
Color.blue
}
}.colorScheme(.dark)
}
.background(Color.green)
}
}
withKnownIssue("Path/Shape is not implemented") {
openSwiftUIAssertSnapshot(of: ContentView())
}
}
}
6 changes: 6 additions & 0 deletions Scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@ OPENSWIFTUI_ROOT="$(dirname $(dirname $(filepath $0)))"

cd $OPENSWIFTUI_ROOT

# Set OPENSWIFTUI_LIB_SWIFT_PATH on Linux if swiftly is installed
if [[ "$(uname)" == "Linux" ]] && command -v swiftly &> /dev/null && [[ -z "$OPENSWIFTUI_LIB_SWIFT_PATH" ]]; then
export OPENSWIFTUI_LIB_SWIFT_PATH="$(swiftly use --print-location)/usr/lib/swift"
echo "Set OPENSWIFTUI_LIB_SWIFT_PATH=$OPENSWIFTUI_LIB_SWIFT_PATH"
fi

swift build
20 changes: 20 additions & 0 deletions Sources/OpenSwiftUI/Layout/Separator/DefaultDividerStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// DefaultDividerStyle.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: Complete

// MARK: - DefaultDividerStyle

extension DividerStyle where Self == DefaultDividerStyle {
static var `default`: DefaultDividerStyle {
.init()
}
}

struct DefaultDividerStyle: DividerStyle {
func makeBody(configuration: Configuration) -> some View {
Divider().dividerStyle(.plain)
}
}
103 changes: 103 additions & 0 deletions Sources/OpenSwiftUI/Layout/Separator/Divider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//
// Divider.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: Complete
// ID: A41482AADD0929733C3343B5E142E952 (SwiftUI)

import OpenAttributeGraphShims
@_spi(ForOpenSwiftUIOnly)
public import OpenSwiftUICore

// MARK: - Divider

/// A visual element that can be used to separate other content.
///
/// When contained in a stack, the divider extends across the minor axis of the
/// stack, or horizontally when not in a stack.
@available(OpenSwiftUI_v1_0, *)
public struct Divider: View, UnaryView, PrimitiveView {

public init() {
_openSwiftUIEmptyStub()
}

nonisolated public static func _makeView(
view: _GraphValue<Self>,
inputs: _ViewInputs
) -> _ViewOutputs {
var newInputs = inputs
if inputs.preferences.requiresPlatformItemList {
newInputs.preferences.requiresPlatformItemList = false
newInputs.requestedTextRepresentation = nil
}
let orientation = inputs.stackOrientation
let child = Attribute(
Child(
orientation: orientation,
dynamicOrientation: orientation == nil ? inputs.dynamicStackOrientation : .init()
)
)
var outputs = ResolvedDivider.makeDebuggableView(
view: .init(child),
inputs: newInputs
)
if let representation = inputs.requestedDividerRepresentation,
representation.shouldMakeRepresentation(inputs: inputs) {
representation.makeRepresentation(inputs: inputs, outputs: &outputs)
}
return outputs
}

private struct Child: Rule {
var orientation: Axis?
@OptionalAttribute var dynamicOrientation: Axis??

var value: ResolvedDivider {
let axis: Axis
if let orientation {
axis = orientation
} else if let dynamicOrientation {
axis = dynamicOrientation ?? .vertical
} else {
axis = .vertical
}
return ResolvedDivider(configuration: .init(orientation: axis.otherAxis))
}
}
}

@available(*, unavailable)
extension Divider: Sendable {}

// MARK: - PlatformDividerRepresentable

package protocol PlatformDividerRepresentable {
static func shouldMakeRepresentation(
inputs: _ViewInputs
) -> Bool

static func makeRepresentation(
inputs: _ViewInputs,
outputs: inout _ViewOutputs
)
}

extension _ViewInputs {
package var requestedDividerRepresentation: (any PlatformDividerRepresentable.Type)? {
get { base.requestedDividerRepresentation }
set { base.requestedDividerRepresentation = newValue }
}
}

extension _GraphInputs {
private struct DividerRepresentationKey: GraphInput {
static var defaultValue: (any PlatformDividerRepresentable.Type)? { nil }
}

package var requestedDividerRepresentation: (any PlatformDividerRepresentable.Type)? {
get { self[DividerRepresentationKey.self] }
set { self[DividerRepresentationKey.self] = newValue }
}
}
65 changes: 65 additions & 0 deletions Sources/OpenSwiftUI/Layout/Separator/DividerStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// DividerStyle.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: Complete

public import OpenSwiftUICore

// MARK: - DividerStyle

@_spi(Private)
@available(OpenSwiftUI_v3_0, *)
@MainActor
@preconcurrency
public protocol DividerStyle {
associatedtype Body: View

@ViewBuilder
func makeBody(configuration: Configuration) -> Body

typealias Configuration = DividerStyleConfiguration
}

// MARK: - DividerStyleConfiguration

@_spi(Private)
@available(OpenSwiftUI_v3_0, *)
public struct DividerStyleConfiguration {
public var orientation: Axis
}

@_spi(Private)
@available(*, unavailable)
extension DividerStyleConfiguration: Sendable {}

// MARK: - ResolvedDivider

struct ResolvedDivider: StyleableView {
static var defaultStyleModifier: DividerStyleModifier = .init(style: .default)

var configuration: DividerStyleConfiguration
}

// MARK: - DividerStyleModifier

@_spi(Private)
@available(OpenSwiftUI_v3_0, *)
extension View {
nonisolated public func dividerStyle<S>(_ style: S) -> some View where S: DividerStyle {
modifier(DividerStyleModifier(style: style))
}
}

struct DividerStyleModifier<S>: StyleModifier where S: DividerStyle {
var style: S

init(style: S) {
self.style = style
}

func styleBody(configuration: DividerStyleConfiguration) -> some View {
style.makeBody(configuration: configuration)
}
}
81 changes: 81 additions & 0 deletions Sources/OpenSwiftUI/Layout/Separator/PlainDividerStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// PlainDividerStyle.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: Blocked by Shape
// ID: 4E7A7B805FC8F5CEEF99A1E333CA7AA7 (SwiftUI)

import OpenCoreGraphicsShims
@_spi(Private)
import OpenSwiftUICore

// MARK: - PlainDividerStyle

extension DividerStyle where Self == PlainDividerStyle {
static var plain: PlainDividerStyle {
.init()
}
}

struct PlainDividerStyle: DividerStyle {
@Environment(\.dividerThickness)
private var thickness: CGFloat

func makeBody(configuration: DividerStyleConfiguration) -> some View {
// TODO: Shape is not implemented yet
Color(provider: PlainDividerShapeStyle())
// DividerShape(base: Rectangle())
// .fill(PlainDividerShapeStyle())
.frame(
width: configuration.orientation == .horizontal ? nil : thickness,
height: configuration.orientation == .horizontal ? thickness : nil
)
}
}

// MARK: - PlainDividerShapeStyle

struct PlainDividerShapeStyle: ShapeStyle, ColorProvider {
private static let sharedColor = Color(provider: PlainDividerShapeStyle())

func _apply(to shape: inout _ShapeStyle_Shape) {
if shape.environment.isVisionEnabled {
SeparatorShapeStyle()._apply(to: &shape)
} else {
let color: Color
if shape.environment.backgroundMaterial != nil {
color = Color.quaternary
} else {
color = Self.sharedColor
}
color._apply(to: &shape)
}
}

func resolve(in environment: EnvironmentValues) -> Color.Resolved {
if environment.colorScheme == .dark {
Color.Resolved(red: 84 / 255, green: 84 / 255, blue: 88 / 255, opacity: 0.6)
} else {
Color.Resolved(red: 60 / 255, green: 60 / 255, blue: 67 / 255, opacity: 0.29)
}
}
}

// MARK: - DividerShape

private struct DividerShape<S>: Shape where S: Shape {
var base: S

nonisolated func path(in rect: CGRect) -> Path {
base.path(in: rect)
}

nonisolated static var role: ShapeRole {
.separator
}

nonisolated var layoutDirectionBehavior: LayoutDirectionBehavior {
base.layoutDirectionBehavior
}
}
14 changes: 0 additions & 14 deletions Sources/OpenSwiftUICore/Layout/Separator/Divider.swift

This file was deleted.

1 change: 0 additions & 1 deletion Sources/OpenSwiftUICore/Layout/Separator/Spacer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ extension PrimitiveSpacer {
) -> _ViewOutputs {
var outputs = _ViewOutputs()
if inputs.requestsLayoutComputer {

let computer = if let orientation = axis ?? inputs.stackOrientation {
SpacerLayoutComputer(
spacer: view.value,
Expand Down
5 changes: 4 additions & 1 deletion Sources/OpenSwiftUICore/Shape/ShapeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ public struct _ShapeView<Content, Style>: View, UnaryView, ShapeStyledLeafView,
self.fillStyle = fillStyle
}

nonisolated public static func _makeView(view: _GraphValue<_ShapeView<Content, Style>>, inputs: _ViewInputs) -> _ViewOutputs {
nonisolated public static func _makeView(
view: _GraphValue<Self>,
inputs: _ViewInputs
) -> _ViewOutputs {
_openSwiftUIUnimplementedFailure()
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/OpenSwiftUICore/View/Input/ViewInputs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,15 @@ public struct _ViewInputs {
@available(*, unavailable)
extension _ViewInputs: Sendable {}

// MARK: - DynamicStackOrientation [6.0.87]
// MARK: - DynamicStackOrientation [6.5.4]

package struct DynamicStackOrientation: ViewInput {
package static let defaultValue: OptionalAttribute<Axis?> = .init()
}

extension _ViewInputs {
@inline(__always)
var dynamicStackOrientation: OptionalAttribute<Axis?> {
package var dynamicStackOrientation: OptionalAttribute<Axis?> {
get { self[DynamicStackOrientation.self] }
set { self[DynamicStackOrientation.self] = newValue }
}
Expand Down
Loading
Loading