Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SliderStyle support #6

Merged
merged 11 commits into from
Dec 16, 2023
7 changes: 5 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ let openSwiftUITarget = Target.target(
],
swiftSettings: [
.enableExperimentalFeature("AccessLevelOnImport"),
.define("OPENSWIFTUI_SUPPRESS_DEPRECATED_WARNINGS")
],
linkerSettings: [
.unsafeFlags(
Expand All @@ -36,13 +37,15 @@ let openSwiftUITestTarget = Target.testTarget(
name: "OpenSwiftUITests",
dependencies: [
"OpenSwiftUI",
]
],
exclude: ["README.md"]
)
let openSwiftUICompatibilityTestTarget = Target.testTarget(
name: "OpenSwiftUICompatibilityTests",
dependencies: [
"OpenSwiftUI",
]
],
exclude: ["README.md"]
)

let package = Package(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,8 @@
// Status: WIP
// ID: 0D3243EDC3DD4D641848661DCC354D4B

struct AccessibilityButtonShapeModifier<V: View>: AccessibilityConfigurationModifier {
typealias Configuration = Never
typealias Content = V

// deleted method
var configuration: Never { fatalError() }

func body(content: V) -> some View {
struct AccessibilityButtonShapeModifier<Content: View>: AccessibilityConfigurationModifier {
func body(content: Content) -> some View {

Check warning on line 11 in Sources/OpenSwiftUI/Accessibility/Modifier/internal/AccessibilityButtonShapeModifier.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/Modifier/internal/AccessibilityButtonShapeModifier.swift#L11

Added line #L11 was not covered by tests
content.modifier(Child())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
// Status: Complete

protocol AccessibilityConfigurationModifier {
associatedtype Configuration
associatedtype Configuration = Never
associatedtype Body
associatedtype Content

var configuration: Configuration { get }
func body(content: Self.Content) -> Self.Body
}

extension AccessibilityConfigurationModifier where Configuration == Never {
var configuration: Configuration { fatalError() }

Check warning on line 19 in Sources/OpenSwiftUI/Accessibility/Modifier/internal/AccessibilityConfigurationModifier.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/Modifier/internal/AccessibilityConfigurationModifier.swift#L19

Added line #L19 was not covered by tests
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
struct AccessibilityLabelModifier<Content: View>: AccessibilityConfigurationModifier {
func body(content: Content) -> some View {
content.modifier(ChildModifier())

Check warning on line 3 in Sources/OpenSwiftUI/Accessibility/Modifier/internal/AccessibilityLabelModifier.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/Modifier/internal/AccessibilityLabelModifier.swift#L2-L3

Added lines #L2 - L3 were not covered by tests
}

private struct ChildModifier: PrimitiveViewModifier {}
}

extension View {
func accessibilityLabel() -> some View {
AccessibilityLabelModifier().body(content: self)

Check warning on line 11 in Sources/OpenSwiftUI/Accessibility/Modifier/internal/AccessibilityLabelModifier.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/Modifier/internal/AccessibilityLabelModifier.swift#L10-L11

Added lines #L10 - L11 were not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// AccessibilityBoundedNumber.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/12/2.
// Lastest Version: iOS 15.5
// Status: Complete

import Foundation

struct AccessibilityBoundedNumber {
var number: AccessibilityNumber
var lowerBound: AccessibilityNumber?
var upperBound: AccessibilityNumber?
var stride: AccessibilityNumber?

init?<S: Strideable>(for value: S, in range: ClosedRange<S>?, by strideValue: S.Stride?) {
let clampedValue = range.map { value.clamped(to: $0) }
let newValue = clampedValue ?? value
guard let numericValue = newValue as? AccessibilityNumeric,
let numberValue = numericValue.asNumber() else {
return nil

Check warning on line 22 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift#L22

Added line #L22 was not covered by tests
}
number = numberValue
if let range {
lowerBound = range.minimumValue?.asNumber()
upperBound = range.maximumValue?.asNumber()
}
if let strideValue,
let numericStride = strideValue as? AccessibilityNumeric {
stride = numericStride.asNumber()
}
}
}

extension AccessibilityBoundedNumber: AccessibilityValue {
// This kind of description logic is very strange
// But that's how Apple's implementation even on iOS 17 :)
// eg.
// For 1.5 and [1.0, 2.0], the accessiblity output would be 150%
// For 1.5 and [1.3, 2.3], the accessiblity output would be 1.5
var localizedDescription: String? {
let range: Double = if let lowerBound, let upperBound {
upperBound.base.doubleValue - lowerBound.base.doubleValue
} else {
.zero

Check warning on line 46 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift#L46

Added line #L46 was not covered by tests
}
if abs(range - 100) >= .ulpOfOne {
let style: NumberFormatter.Style = (abs(range - 1.0) < .ulpOfOne) ? .percent : .decimal
return NumberFormatter.localizedString(from: number.base, number: style)
} else {
return NumberFormatter.localizedString(from: NSNumber(value: number.base.doubleValue / 100), number: .percent)
}
}

var displayDescription: String? {
localizedDescription

Check warning on line 57 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift#L56-L57

Added lines #L56 - L57 were not covered by tests
}

var value: NSNumber { number.value }
var minValue: NSNumber? { lowerBound?.value }
var maxValue: NSNumber? { upperBound?.value }
static var type: AnyAccessibilityValueType { .boundedNumber }

Check warning on line 63 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift#L60-L63

Added lines #L60 - L63 were not covered by tests
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// AccessibilityNumber.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/12/2.
// Lastest Version: iOS 15.5
// Status: Complete

import Foundation

struct AccessibilityNumber {
var base: NSNumber
}

extension AccessibilityNumber: AccessibilityValue {
var localizedDescription: String? {
NumberFormatter.localizedString(from: value, number: .decimal)

Check warning on line 17 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift#L16-L17

Added lines #L16 - L17 were not covered by tests
}
var displayDescription: String? { localizedDescription }
var value: NSNumber { base }
var minValue: NSNumber? { nil }
var maxValue: NSNumber? { nil }
static var type: AnyAccessibilityValueType { .number }

Check warning on line 23 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift#L19-L23

Added lines #L19 - L23 were not covered by tests
}

extension AccessibilityNumber: ExpressibleByFloatLiteral {
init(floatLiteral value: Double) {
base = NSNumber(floatLiteral: value)

Check warning on line 28 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift#L27-L28

Added lines #L27 - L28 were not covered by tests
}
}

extension AccessibilityNumber: ExpressibleByIntegerLiteral {
init(integerLiteral value: Int) {
base = NSNumber(integerLiteral: value)

Check warning on line 34 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift#L33-L34

Added lines #L33 - L34 were not covered by tests
}
}

extension AccessibilityNumber: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let data = try container.decode(Data.self)
self.base = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSNumber.self, from: data)!

Check warning on line 42 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift#L39-L42

Added lines #L39 - L42 were not covered by tests
}

func encode(to encoder: Encoder) throws {
let data = try NSKeyedArchiver.archivedData(withRootObject: base, requiringSecureCoding: true)
var container = encoder.singleValueContainer()
try container.encode(data)

Check warning on line 48 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumber.swift#L45-L48

Added lines #L45 - L48 were not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//
// AccessibilityNumber.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/12/3.
// Lastest Version: iOS 15.5
// Status: Complete

import Foundation

protocol AccessibilityNumeric {
var isValidMinValue: Bool { get }
var isValidMaxValue: Bool { get }
func asNumber() -> AccessibilityNumber?
}

extension AccessibilityNumeric where Self: FixedWidthInteger {
var isValidMinValue: Bool {
// TODO: Add Unit Test and check usage
if Self.bitWidth == 8 || !Self.isSigned {
true
} else {
self != .min

Check warning on line 23 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L18-L23

Added lines #L18 - L23 were not covered by tests
}
}

var isValidMaxValue: Bool { self != .max }

Check warning on line 27 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L27

Added line #L27 was not covered by tests
}

extension Int: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 31 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L31

Added line #L31 was not covered by tests
}

extension Int8: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 35 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L35

Added line #L35 was not covered by tests
}

extension Int16: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 39 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L39

Added line #L39 was not covered by tests
}

extension Int32: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 43 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L43

Added line #L43 was not covered by tests
}

extension Int64: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 47 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L47

Added line #L47 was not covered by tests
}

extension UInt: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 51 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L51

Added line #L51 was not covered by tests
}

extension UInt8: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 55 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L55

Added line #L55 was not covered by tests
}

extension UInt16: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 59 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L59

Added line #L59 was not covered by tests
}

extension UInt32: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 63 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L63

Added line #L63 was not covered by tests
}

extension UInt64: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 67 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L67

Added line #L67 was not covered by tests
}

extension AccessibilityNumeric where Self: BinaryFloatingPoint {
var isValidMinValue: Bool {
isFinite && self > -Self.greatestFiniteMagnitude
}

var isValidMaxValue: Bool {
isFinite && self < Self.greatestFiniteMagnitude
}
}

extension Float: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }

Check warning on line 81 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityNumeric.swift#L81

Added line #L81 was not covered by tests
}

extension Double: AccessibilityNumeric {
func asNumber() -> AccessibilityNumber? { AccessibilityNumber(base: .init(value: self)) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// AccessibilityPlatformSafe.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/12/2.
// Lastest Version: iOS 15.5
// Status: Complete

import Foundation

protocol AccessibilityPlatformSafe {}

extension String: AccessibilityPlatformSafe {}
extension Double: AccessibilityPlatformSafe {}
extension Int: AccessibilityPlatformSafe {}
extension UInt: AccessibilityPlatformSafe {}
extension UInt8: AccessibilityPlatformSafe {}
extension Bool: AccessibilityPlatformSafe {}
extension NSNumber: AccessibilityPlatformSafe {}
extension Optional: AccessibilityPlatformSafe where Wrapped: AccessibilityPlatformSafe {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// AccessibilitySliderValue.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/12/16.
// Lastest Version: iOS 15.5
// Status: Complete

struct AccessibilitySliderValue: AccessibilityValueByProxy {
var base: AccessibilityBoundedNumber
static var type: AnyAccessibilityValueType { .slider }

Check warning on line 11 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilitySliderValue.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilitySliderValue.swift#L11

Added line #L11 was not covered by tests
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// AccessibilityValue.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/12/2.
// Lastest Version: iOS 15.5
// Status: Complete

import Foundation

protocol AccessibilityValue: Equatable {
associatedtype PlatformValue: AccessibilityPlatformSafe
var localizedDescription: String? { get }
var displayDescription: String? { get }
var value: PlatformValue { get }
var minValue: PlatformValue? { get }
var maxValue: PlatformValue? { get }
var step: PlatformValue? { get }
static var type: AnyAccessibilityValueType { get }
}

extension AccessibilityValue {
var minValue: PlatformValue? { nil }
var maxValue: PlatformValue? { nil }
var step: PlatformValue? { nil }

Check warning on line 25 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift#L23-L25

Added lines #L23 - L25 were not covered by tests
}

extension AccessibilityValue where PlatformValue: CustomStringConvertible {
var localizedDescription: String? { value.description }
var displayDescription: String? { value.description }

Check warning on line 30 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift#L29-L30

Added lines #L29 - L30 were not covered by tests
}

extension AccessibilityValue where Self == Self.PlatformValue {
var value: PlatformValue { self }

Check warning on line 34 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift#L34

Added line #L34 was not covered by tests
}

extension Int: AccessibilityValue {
typealias PlatformValue = Int
static var type: AnyAccessibilityValueType { .int }

Check warning on line 39 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift#L39

Added line #L39 was not covered by tests
}

extension Double: AccessibilityValue {
typealias PlatformValue = Double
static var type: AnyAccessibilityValueType { .number }

Check warning on line 44 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift#L44

Added line #L44 was not covered by tests
}

extension Bool: AccessibilityValue {
typealias PlatformValue = Bool
static var type: AnyAccessibilityValueType { .bool }

Check warning on line 49 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift#L49

Added line #L49 was not covered by tests
}

extension String: AccessibilityValue {
typealias PlatformValue = String
static var type: AnyAccessibilityValueType { .string }

Check warning on line 54 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValue.swift#L54

Added line #L54 was not covered by tests
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// AccessibilityValueByProxy.swift
// OpenSwiftUI
//
// Created by Kyle on 2023/12/16.
// Lastest Version: iOS 15.5
// Status: Complete

protocol AccessibilityValueByProxy: AccessibilityValue {
associatedtype Base: AccessibilityValue
var base: Base { get }
}

extension AccessibilityValueByProxy {
var localizedDescription: String? { base.localizedDescription }
var displayDescription: String? { base.displayDescription }
var value: Base.PlatformValue { base.value }
var minValue: Base.PlatformValue? { base.minValue }
var maxValue: Base.PlatformValue? { base.maxValue }
var step: Base.PlatformValue? { base.step }

Check warning on line 20 in Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValueByProxy.swift

View check run for this annotation

Codecov / codecov/patch

Sources/OpenSwiftUI/Accessibility/internal/AccessibilityValueByProxy.swift#L15-L20

Added lines #L15 - L20 were not covered by tests
}
Loading