From 277e9a186f8505050849f619fee8bb49959cb6cb Mon Sep 17 00:00:00 2001 From: Helbert Gomes Date: Sat, 21 Sep 2024 01:31:20 -0400 Subject: [PATCH] chore: improve some accessibility modifiers, add Text, LocalizedString, and Label structures --- .../AccessibilityActionResult.swift | 6 + .../AccessibilityActionStorage.swift | 19 + .../AccessibilityAttachment.swift | 11 + .../AccessibilityAttachmentModifier.swift | 7 +- .../AccessibilityProperties.swift | 9 + .../AccessibilityPropertiesEntry.swift | 9 + .../AccessibilityScrollAction.swift | 6 + .../AccessibilityVoidAction.swift | 9 + .../AnyAccessibilityAction.swift | 5 + ...PlatformAccessibilityElementProtocol.swift | 4 + .../View+AccessibilityFundamentals.swift | 14 +- .../View+AccessibleAppearance.swift | 6 +- .../AccessibilityActionKind.swift | 4 +- .../AccessibilityAdjustableAction.swift | 9 + .../View+AccessibilityControls.swift | 140 +++++-- .../AccessibilityLabelStorage.swift | 17 + .../AccessibilityLabeledPairRole.swift | 1 + .../AccessibilityValueStorage.swift | 11 + .../AnyAccessibilityValue.swift | 4 + .../RelationshipModifier.swift | 19 + .../View+AccessibleDescriptions.swift | 382 ++++++++++++++++-- .../View+AcessibleNavigations.swift | 38 +- .../App Structure/Scenes/Scene.swift | 4 +- .../Model Data/MutableBox.swift | 9 + .../Views/Text Input and Output/.keep | 0 .../LocalizedStringKey.swift | 119 +++++- .../Views/View Fundamentals/Label.swift | 5 + .../Views/View Fundamentals/Text.swift | 5 + 28 files changed, 757 insertions(+), 115 deletions(-) create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityActionResult.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityActionStorage.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityAttachment.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityProperties.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityPropertiesEntry.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityScrollAction.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityVoidAction.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AnyAccessibilityAction.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/PlatformAccessibilityElementProtocol.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessible Controls/AccessibilityAdjustableAction.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessible Descriptions/AccessibilityLabelStorage.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessible Descriptions/AccessibilityValueStorage.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessible Descriptions/AnyAccessibilityValue.swift create mode 100644 Sources/OpenSwiftUI/Accessibility/Accessible Descriptions/RelationshipModifier.swift create mode 100644 Sources/OpenSwiftUI/Data and Storage/Model Data/MutableBox.swift delete mode 100644 Sources/OpenSwiftUI/Views/Text Input and Output/.keep create mode 100644 Sources/OpenSwiftUI/Views/View Fundamentals/Label.swift diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityActionResult.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityActionResult.swift new file mode 100644 index 0000000..9f06399 --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityActionResult.swift @@ -0,0 +1,6 @@ +import Foundation + +public struct AccessibilityActionResult { + public init() { + } +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityActionStorage.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityActionStorage.swift new file mode 100644 index 0000000..9a2c162 --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityActionStorage.swift @@ -0,0 +1,19 @@ +import Foundation + +class AccessibilityActionStorage : AnyAccessibilityAction { + var action: Value + var category: AccessibilityActionCategory? + var label: Text? + var image: Image? + var handler: Any? + var seed: Int + + init(action: Value, category: AccessibilityActionCategory?, label: Text?, image: Image?, handler: Any?, seed: Int) { + self.action = action + self.category = category + self.label = label + self.image = image + self.handler = handler + self.seed = seed + } +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityAttachment.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityAttachment.swift new file mode 100644 index 0000000..0aaee3f --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityAttachment.swift @@ -0,0 +1,11 @@ +import Foundation + +public struct AccessibilityAttachment { + var properties: AccessibilityProperties + var platformElement: (any PlatformAccessibilityElementProtocol)? + + init(properties: AccessibilityProperties, platformElement: (any PlatformAccessibilityElementProtocol)?) { + self.properties = properties + self.platformElement = platformElement + } +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityAttachmentModifier.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityAttachmentModifier.swift index 22edc74..3698d69 100644 --- a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityAttachmentModifier.swift +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityAttachmentModifier.swift @@ -2,6 +2,11 @@ import Foundation /// A view modifier that adds accessibility properties to the view public struct AccessibilityAttachmentModifier { - public init() { + let storage: MutableBox + let behavior: AccessibilityChildBehavior? + + public init(storage: MutableBox, behavior: AccessibilityChildBehavior?) { + self.storage = storage + self.behavior = behavior } } \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityProperties.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityProperties.swift new file mode 100644 index 0000000..cc07eaa --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityProperties.swift @@ -0,0 +1,9 @@ +import Foundation + +class AccessibilityProperties { + let storage: [ObjectIdentifier: Any] + + init(storage: [ObjectIdentifier: Any]) { + self.storage = storage + } +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityPropertiesEntry.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityPropertiesEntry.swift new file mode 100644 index 0000000..62282b4 --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityPropertiesEntry.swift @@ -0,0 +1,9 @@ +import Foundation + +class AccessibilityPropertiesEntry { + let typedValue: Value + + init(typedValue: Value) { + self.typedValue = typedValue + } +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityScrollAction.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityScrollAction.swift new file mode 100644 index 0000000..806c06f --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityScrollAction.swift @@ -0,0 +1,6 @@ +import Foundation + +struct AccessibilityScrollAction { + init() { + } +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityVoidAction.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityVoidAction.swift new file mode 100644 index 0000000..bf8177a --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AccessibilityVoidAction.swift @@ -0,0 +1,9 @@ +import Foundation + +class AccessibilityVoidAction { + var kind: AccessibilityActionKind + + init(kind: AccessibilityActionKind) { + self.kind = kind + } +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AnyAccessibilityAction.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AnyAccessibilityAction.swift new file mode 100644 index 0000000..b8f993e --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/AnyAccessibilityAction.swift @@ -0,0 +1,5 @@ +import Foundation + +class AnyAccessibilityAction { + var bridged: Bool = false +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/PlatformAccessibilityElementProtocol.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/PlatformAccessibilityElementProtocol.swift new file mode 100644 index 0000000..a98fa61 --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/PlatformAccessibilityElementProtocol.swift @@ -0,0 +1,4 @@ +import Foundation + +protocol PlatformAccessibilityElementProtocol { +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/View+AccessibilityFundamentals.swift b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/View+AccessibilityFundamentals.swift index a67d182..e533aad 100644 --- a/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/View+AccessibilityFundamentals.swift +++ b/Sources/OpenSwiftUI/Accessibility/Accessibility Fundamentals/View+AccessibilityFundamentals.swift @@ -7,19 +7,19 @@ extension View { /// Creates a new accessibility element, or modifies the AccessibilityChildBehavior of the existing accessibility element. /// - Parameter children: The behavior to use when creating or transforming an accessibility element. The default is ignore nonisolated public func accessibilityElement(children: AccessibilityChildBehavior = .ignore) -> some View { - modifier(EmptyModifier()) + fatalError() } /// Replaces the existing accessibility element’s children with one or more new synthetic accessibility elements. /// - Parameter children: A ViewBuilder that represents the replacement child views the framework uses to generate accessibility elements. nonisolated public func accessibilityChildren(@ViewBuilder children: () -> V) -> some View where V : View { - modifier(EmptyModifier()) + fatalError() } /// Replaces one or more accessibility elements for this view with new accessibility elements. /// - Parameter representation: A hidden view that the accessibility system uses to generate accessibility elements. nonisolated public func accessibilityRepresentation(@ViewBuilder representation: () -> V) -> some View where V : View { - modifier(EmptyModifier()) + fatalError() } // MARK: - Identifying elements @@ -27,7 +27,7 @@ extension View { /// Uses the string you specify to identify the view. /// Use this value for testing. It isn’t visible to the user. nonisolated public func accessibilityIdentifier(_ identifier: String) -> ModifiedContent { - modifier(AccessibilityAttachmentModifier()) + fatalError() } /// Uses the string you specify to identify the view. @@ -36,14 +36,14 @@ extension View { /// - identifier: The accessibility identifier to apply. /// - isEnabled: If true the accessibility identifier is applied; otherwise the accessibility identifier is unchanged. nonisolated public func accessibilityIdentifier(_ identifier: String, isEnabled: Bool) -> ModifiedContent { - modifier(AccessibilityAttachmentModifier()) + fatalError() } // MARK: - Hiding elements /// Specifies whether to hide this view from system accessibility features. nonisolated public func accessibilityHidden(_ hidden: Bool) -> ModifiedContent { - modifier(AccessibilityAttachmentModifier()) + fatalError() } /// Specifies whether to hide this view from system accessibility features. @@ -51,6 +51,6 @@ extension View { /// - hidden: Whether to hide this view from accessibility features. /// - isEnabled: If true the accessibility hidden state is applied; otherwise the accessibility hidden state is unchanged. nonisolated public func accessibilityHidden(_ hidden: Bool, isEnabled: Bool) -> ModifiedContent { - modifier(AccessibilityAttachmentModifier()) + fatalError() } } \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessible Appearance/View+AccessibleAppearance.swift b/Sources/OpenSwiftUI/Accessibility/Accessible Appearance/View+AccessibleAppearance.swift index e763b67..ef160a2 100644 --- a/Sources/OpenSwiftUI/Accessibility/Accessible Appearance/View+AccessibleAppearance.swift +++ b/Sources/OpenSwiftUI/Accessibility/Accessible Appearance/View+AccessibleAppearance.swift @@ -9,7 +9,7 @@ extension View { /// - Parameter active: A true value ignores the system Smart Invert setting. A false value follows the system setting. /// - Returns: The modified view. nonisolated public func accessibilityIgnoresInvertColors(_ active: Bool = true) -> some View { - modifier(EmptyModifier()) + fatalError() } // MARK: - Enlarging content @@ -17,12 +17,12 @@ extension View { /// Adds a default large content view to be shown by the large content viewer. /// - Returns: The modified view. nonisolated public func accessibilityShowsLargeContentViewer() -> some View { - modifier(EmptyModifier()) + fatalError() } /// Adds a custom large content view to be shown by the large content viewer. /// - Returns: The modified view. nonisolated public func accessibilityShowsLargeContentViewer(@ViewBuilder _ largeContentView: () -> V) -> some View where V : View { - modifier(EmptyModifier()) + fatalError() } } \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessible Controls/AccessibilityActionKind.swift b/Sources/OpenSwiftUI/Accessibility/Accessible Controls/AccessibilityActionKind.swift index d2afd20..40afc2c 100644 --- a/Sources/OpenSwiftUI/Accessibility/Accessible Controls/AccessibilityActionKind.swift +++ b/Sources/OpenSwiftUI/Accessibility/Accessible Controls/AccessibilityActionKind.swift @@ -31,7 +31,7 @@ public struct AccessibilityActionKind : Equatable, Sendable { // MARK: - Creating an action type - public init(named name: String) { + public init(named name: Text) { self = .init(kind: .custom(name)) } @@ -47,7 +47,7 @@ extension AccessibilityActionKind { case delete case magicTap case showMenu - case custom(String) + case custom(Text) static func == (_ lhs: ActionKind, _ rhs: ActionKind) -> Bool { return switch (lhs, rhs) { diff --git a/Sources/OpenSwiftUI/Accessibility/Accessible Controls/AccessibilityAdjustableAction.swift b/Sources/OpenSwiftUI/Accessibility/Accessible Controls/AccessibilityAdjustableAction.swift new file mode 100644 index 0000000..f1bbef9 --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/Accessible Controls/AccessibilityAdjustableAction.swift @@ -0,0 +1,9 @@ +import Foundation + +class AccessibilityAdjustableAction : AnyAccessibilityAction { + var continuous: Bool? + + init(continuous: Bool?) { + self.continuous = continuous + } +} \ No newline at end of file diff --git a/Sources/OpenSwiftUI/Accessibility/Accessible Controls/View+AccessibilityControls.swift b/Sources/OpenSwiftUI/Accessibility/Accessible Controls/View+AccessibilityControls.swift index d3e9ebb..a17faaf 100644 --- a/Sources/OpenSwiftUI/Accessibility/Accessible Controls/View+AccessibilityControls.swift +++ b/Sources/OpenSwiftUI/Accessibility/Accessible Controls/View+AccessibilityControls.swift @@ -18,7 +18,27 @@ extension View { /// } /// nonisolated public func accessibilityAction(_ actionKind: AccessibilityActionKind = .default,_ handler: @escaping () -> Void) -> ModifiedContent { - modifier(AccessibilityAttachmentModifier()) + modifier(AccessibilityAttachmentModifier( + storage: .init(value: .init( + properties: .init( + storage: [ + ObjectIdentifier(AnyAccessibilityAction.self): + AccessibilityPropertiesEntry>(typedValue: [ + AccessibilityActionStorage( + action: AccessibilityVoidAction(kind: actionKind), + category: nil, + label: nil, + image: nil, + handler: handler, + seed: 0 + ) + ]) + ] + ), + platformElement: nil + )), + behavior: nil + )) } /// Adds an accessibility action to the view. Actions allow assistive technologies, @@ -35,7 +55,27 @@ extension View { /// } /// nonisolated public func accessibilityAction(named name: Text, _ handler: @escaping () -> Void) -> ModifiedContent { - modifier(AccessibilityAttachmentModifier()) + modifier(AccessibilityAttachmentModifier( + storage: .init(value: .init( + properties: .init( + storage: [ + ObjectIdentifier(AnyAccessibilityAction.self): + AccessibilityPropertiesEntry>(typedValue: [ + AccessibilityActionStorage( + action: AccessibilityVoidAction(kind: .init(named: name)), + category: nil, + label: nil, + image: nil, + handler: handler, + seed: 0 + ) + ]) + ] + ), + platformElement: nil + )), + behavior: nil + )) } /// Adds an accessibility action to the view. Actions allow assistive technologies, @@ -54,23 +94,63 @@ extension View { /// } /// nonisolated public func accessibilityAction