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
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import OpenAttributeGraphShims
///
/// Conforming types must provide an empty initializer and will inherit the view
/// implementation from the source view when rendered.
@MainActor
@preconcurrency
protocol ViewAlias: PrimitiveView {
init()
}
Expand Down
38 changes: 38 additions & 0 deletions Sources/OpenSwiftUI/View/Configuration/ViewInputFlagModifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// ViewInputFlagModifier.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: Complete
// ID: 481852E6B9C17510DAAE09E84ECE4A2D (SwiftUI?)

struct ViewInputFlagModifier<Flag>: _GraphInputsModifier, PrimitiveViewModifier where Flag: ViewInputFlag {
var flag: Flag

static func _makeInputs(modifier: _GraphValue<Self>, inputs: inout _GraphInputs) {
Flag._makeInputs(
modifier: modifier[offset: { .of(&$0.flag) }],
inputs: &inputs
)
}
}

extension View {
nonisolated func input<Flag>(_ flag: Flag.Type) -> some View where Flag: ViewInputFlag {
modifier(ViewInputFlagModifier(flag: flag.init()))
}
}

private struct FalseViewInputBoolFlagModifier<Flag>: _GraphInputsModifier, MultiViewModifier, PrimitiveViewModifier where Flag: ViewInputBoolFlag {
var flag: Flag

static func _makeInputs(modifier: _GraphValue<Self>, inputs: inout _GraphInputs) {
inputs[Flag.self] = false
}
}

extension View {
nonisolated func input<Flag>(_ flag: Flag.Type) -> some View where Flag: ViewInputBoolFlag {
modifier(ViewInputFlagModifier(flag: flag.init()))
}
}
136 changes: 136 additions & 0 deletions Sources/OpenSwiftUI/View/Label/AccessibilityLabeledContent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//
// AccessibilityLabeledContent.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: WIP
// ID: 28161D0154DF546094400EFEC8044F4B (SwiftUI)

import OpenAttributeGraphShims
import OpenSwiftUICore

// MARK: - AccessibilityLabeledContentModifier

protocol AccessibilityLabeledContentModifier: MultiViewModifier, PrimitiveViewModifier {
var presentation: AccessibilityLabeledContentPresentation? {
get
set
}

func _makePresentation(
modifier: _GraphValue<Self>,
inputs: _ViewInputs
) -> Attribute<AccessibilityLabeledContentPresentation>
}

// MARK: - AccessibilityLabeledContentPresentation

enum AccessibilityLabeledContentPresentation {
case standard
case merged
}

// MARK: - AccessibilityCombinedLabeledContent

struct AccessibilityCombinedLabeledContent: ViewInputBoolFlag {}


// MARK: - AccessibilityLabeledContentContentModifier [WIP]

struct AccessibilityLabeledContentContentModifier<Label>: AccessibilityLabeledContentModifier where Label: View {
private struct Attachment: StatefulRule {
// @OptionalAttribute var labelChild: AccessibilityAttachment.Tree?
@Attribute var presentation: AccessibilityLabeledContentPresentation?

typealias Value = AccessibilityAttachmentModifier

func updateValue() {
_openSwiftUIUnimplementedFailure()
}
}

private struct LabelChild: Rule {
@Attribute var label: Label

var value: some View {
_openSwiftUIUnimplementedFailure()
}
}

var label: Label

var presentation: AccessibilityLabeledContentPresentation?

static func _makeView(
modifier: _GraphValue<Self>,
inputs: _ViewInputs,
body: (_Graph, _ViewInputs) -> _ViewOutputs
) -> _ViewOutputs {
_openSwiftUIUnimplementedWarning()
return body(_Graph(), inputs)
}

func _makePresentation(
modifier: _GraphValue<Self>,
inputs: _ViewInputs
) -> Attribute<AccessibilityLabeledContentPresentation> {
_openSwiftUIUnimplementedFailure()
}
}

// MARK: - AccessibilityLabeledContentLabelModifier [WIP]

struct AccessibilityLabeledContentLabelModifier: AccessibilityLabeledContentModifier {
private struct Attachment: Rule {
@Attribute var presentation: AccessibilityLabeledContentPresentation

var value: AccessibilityAttachmentModifier {
_openSwiftUIUnimplementedFailure()
}
}

var presentation: AccessibilityLabeledContentPresentation?

static func _makeView(
modifier: _GraphValue<Self>,
inputs: _ViewInputs,
body: (_Graph, _ViewInputs) -> _ViewOutputs
) -> _ViewOutputs {
_openSwiftUIUnimplementedWarning()
return body(_Graph(), inputs)
}

func _makePresentation(
modifier: _GraphValue<Self>,
inputs: _ViewInputs
) -> Attribute<AccessibilityLabeledContentPresentation> {
_openSwiftUIUnimplementedFailure()
}
}

// MARK: - ResolvedPresentation [WIP]

struct ResolvedPresentation: Rule {
@Attribute var explicit: AccessibilityLabeledContentPresentation?

@Attribute var labelsVisibility: Visibility

var value: AccessibilityLabeledContentPresentation {
_openSwiftUIUnimplementedFailure()
}
}

// FIXME
struct AccessibilityAttachmentModifier {}

// FIXME
enum AccessibilityAttachment {
enum Tree {}
}

// FIXME
struct AccessibilityFrameModifier: ViewModifier {
func body(content: Content) -> some View {
content
}
}
52 changes: 52 additions & 0 deletions Sources/OpenSwiftUI/View/Label/AutomaticLabeledContentStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// AutomaticLabeledContentStyle.swift
// OpenSwiftUI
//
// Audited fror 6.5.4
// Status: WIP

import OpenSwiftUICore

@available(OpenSwiftUI_v4_0, *)
extension LabeledContentStyle where Self == AutomaticLabeledContentStyle {

/// A labeled content style that resolves its appearance automatically based
/// on the current context.
@MainActor
@preconcurrency
public static var automatic: AutomaticLabeledContentStyle {
.init()
}
}

/// The default labeled content style.
///
/// Use ``LabeledContentStyle/automatic`` to construct this style.
@available(OpenSwiftUI_v4_0, *)
public struct AutomaticLabeledContentStyle: LabeledContentStyle {

@Environment(\.labelsVisibility)
private var labelsVisibility: Visibility

/// Creates an automatic labeled content style.
public init() {
_openSwiftUIEmptyStub()
}

// FIXME
public func makeBody(configuration: AutomaticLabeledContentStyle.Configuration) -> some View {
LabeledContent {
configuration.content
.modifier(_LabeledContentStyleModifier(style: self))
} label: {
StaticIf(LabelVisibilityConfigured.self) {
labelsVisibility == .hidden ? nil : configuration.label
} else: {
configuration.label
}
}
}
}

@available(*, unavailable)
extension AutomaticLabeledContentStyle: Sendable {}
116 changes: 116 additions & 0 deletions Sources/OpenSwiftUI/View/Label/LabelVisibility.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
//
// LabelVisibility.swift
// OpenSwiftUI
//
// Audited for 6.5.4
// Status: Complete
// ID: D83D7206E97BF0FFC98D060894E9FA4D (SwiftUI)

import OpenSwiftUICore

// MARK: - View + labelsVisibility

extension View {

/// Controls the visibility of labels of any controls contained within this
/// view.
///
/// Use this modifier when you want to omit a label from one or more
/// labeled content in your user interface. For example, the first ``Toggle``
/// in the following example hides its label:
///
/// VStack {
/// Toggle(isOn: $toggle1) {
/// Text("Toggle 1")
/// }
/// .labelsVisibility(.hidden)
///
/// Toggle(isOn: $toggle2) {
/// Text("Toggle 2")
/// }
/// }
///
/// The ``VStack`` in the example above centers the first toggle's control
/// element in the available space, while it centers the second toggle's
/// combined label and control element:
///
/// ![A screenshot showing a view with two toggle controls where one label
/// is visible and the other label is hidden.](View-labelsHidden-1.png)
///
/// Always provide a label for controls, even when you hide the label,
/// because OpenSwiftUI uses labels for other purposes, including accessibility.
///
/// On iOS, a `Picker` within a `Menu` hides its label by default. You can use
/// this modifier to explicitly show the label in that context:
///
/// Menu {
/// Picker("Flavor", selection: $selectedFlavor) {
/// Text("Chocolate").tag(Flavor.chocolate)
/// Text("Vanilla").tag(Flavor.vanilla)
/// Text("Strawberry").tag(Flavor.strawberry)
/// }
/// .labelsVisibility(.visible)
/// }
///
/// > Note: This modifier doesn't work for all labels. It applies to
/// ``LabeledContent`` elements, including controls like ``Picker`` and
/// ``Toggle``, but not to controls like a bordered button where the label
/// is inside the button's border.
@available(OpenSwiftUI_v6_0, *)
nonisolated public func labelsVisibility(_ visibility: Visibility) -> some View {
labels(visibility)
}

@_spi(Private)
@available(OpenSwiftUI_v4_0, *)
@available(*, deprecated, message: "Use labelsVisibility(_:) instead")
nonisolated public func labels(_ visibility: Visibility) -> some View {
environment(\.labelsVisibility, visibility)
.input(LabelVisibilityConfigured.self)
}
}

// MARK: Environment + labelsVisibility

private struct LabelsVisibilityKey: EnvironmentKey {
static var defaultValue: Visibility { .automatic }
}

@available(OpenSwiftUI_v6_0, *)
extension EnvironmentValues {

/// The labels visibility set by ``View/labelsVisibility(_:)``.
///
/// Read this environment value from within a view to obtain the preferred
/// visibility for labels within the hierarchy. If you would like to
/// dynamically hide the label of your custom view, make sure to include an
/// accessibility label via the ``View/accessibilityLabel(content:)``
/// modifier as illustrated below:
///
/// @Environment(\.labelsVisibility)
/// private var labelsVisibility
///
/// var body: some View {
/// VStack {
/// QuizCardView()
/// if labelsVisibility != .hidden {
/// label
/// }
/// }
/// .accessibilityLabel {
/// label
/// }
/// }
///
/// private var label: some View {
/// Text("Quiz Card")
/// }
public var labelsVisibility: Visibility {
get { self[LabelsVisibilityKey.self] }
set { self[LabelsVisibilityKey.self] = newValue }
}
}

// MARK: - LabelVisibilityConfigured

struct LabelVisibilityConfigured: ViewInputBoolFlag {}
Loading