Skip to content

Commit 7f79072

Browse files
authored
Add time data source format style support (#889)
1 parent 60a2593 commit 7f79072

13 files changed

Lines changed: 1286 additions & 32 deletions

Sources/OpenSwiftUICore/Animation/Transition/ContentTransition.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,17 @@ public struct ContentTransition: Equatable, Sendable {
350350
/// system uses an opacity transition instead.
351351
public static let interpolate: ContentTransition = .init(storage: .named(.init())) // FIXME
352352

353+
public static func numericText(countsDown: Bool = false) -> ContentTransition {
354+
// FIXME
355+
.init(storage: .named(.init(name: .numericText(.init(direction: .fixed(downwards: countsDown))))))
356+
}
357+
358+
@_spi(Private)
359+
@available(*, deprecated, message: "replaced by numericText(countsDown:)")
360+
public static func numericText(increasing: Bool) -> ContentTransition {
361+
.numericText(countsDown: !increasing)
362+
}
363+
353364
// MARK: - ContentTransition.Options
354365

355366
@_spi(Private)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//
2+
// CalendarDependentFormatStyle.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for 6.5.4
6+
// Status: Complete (Blocked by WhitespaceRemovingFormatStyle/SystemFormatStyle)
7+
// ID: 26D279F2E8972E56094553A13FA39915 (SwiftUICore)
8+
9+
package import Foundation
10+
11+
protocol CalendarDependentFormatStyle: FormatStyle {
12+
func withCalendar(_ calendar: Calendar) -> Self
13+
}
14+
15+
extension FormatStyle {
16+
package func calendar(_ calendar: Calendar) -> Self {
17+
guard let style = self as? any CalendarDependentFormatStyle else {
18+
return self
19+
}
20+
return style.withCalendar(calendar) as! Self
21+
}
22+
}
23+
24+
#if canImport(Darwin)
25+
@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
26+
extension Date.FormatStyle: CalendarDependentFormatStyle {
27+
func withCalendar(_ calendar: Calendar) -> Self {
28+
var style = self
29+
style.calendar = calendar
30+
return style
31+
}
32+
}
33+
34+
@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
35+
extension Date.VerbatimFormatStyle: CalendarDependentFormatStyle {
36+
func withCalendar(_ calendar: Calendar) -> Self {
37+
var style = self
38+
style.calendar = calendar
39+
return style
40+
}
41+
}
42+
43+
@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
44+
extension Date.ComponentsFormatStyle: CalendarDependentFormatStyle {
45+
func withCalendar(_ calendar: Calendar) -> Self {
46+
self.calendar(calendar)
47+
}
48+
}
49+
50+
@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *)
51+
extension Date.FormatStyle.Attributed: CalendarDependentFormatStyle {
52+
func withCalendar(_ calendar: Calendar) -> Self {
53+
var style = self
54+
style[dynamicMember: \.calendar] = calendar
55+
return style
56+
}
57+
}
58+
59+
@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *)
60+
extension Date.VerbatimFormatStyle.Attributed: CalendarDependentFormatStyle {
61+
func withCalendar(_ calendar: Calendar) -> Self {
62+
var style = self
63+
style[dynamicMember: \.calendar] = calendar
64+
return style
65+
}
66+
}
67+
68+
@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
69+
extension Date.AnchoredRelativeFormatStyle: CalendarDependentFormatStyle {
70+
func withCalendar(_ calendar: Calendar) -> Self {
71+
var style = self
72+
style.calendar = calendar
73+
return style
74+
}
75+
}
76+
77+
// TODO: Add conformance when these concrete format styles land:
78+
// WhitespaceRemovingFormatStyle where A: CalendarDependentFormatStyle
79+
// SystemFormatStyle.DateReference
80+
#endif

Sources/OpenSwiftUICore/View/Text/Text/CapitalizationContextDependentFormatStyle.swift renamed to Sources/OpenSwiftUICore/View/Text/FormatStyle/CapitalizationContextDependentFormatStyle.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// Status: Complete (Blocked by SystemFormatStyle)
77
// ID: B2C9C13C743DF2F6E22ED614C39E3A5D (SwiftUICore)
88

9-
#if canImport(Darwin)
109
public import Foundation
1110

1211
protocol CapitalizationContextDependentFormatStyle: FormatStyle {
@@ -44,4 +43,3 @@ extension EnvironmentValues {
4443
// Date.AnchoredRelativeFormatStyle
4544
// Date.FormatStyle
4645
// ...
47-
#endif
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// protocol ContentTransitionProvidingFormatStyle.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for 6.5.4
6+
// Status: WIP (Blocked by SystemFormatStyle)
7+
8+
package import Foundation
9+
10+
package protocol ContentTransitionProvidingFormatStyle<FormatInput>: FormatStyle {
11+
func contentTransition<Source>(
12+
for source: Source
13+
) -> ContentTransition where Source: TimeDataSourceStorage, Source.Value == FormatInput
14+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// InterfaceIdiomDependentFormatStyle.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for 6.5.4
6+
// Status: WIP (Blocked by SystemFormatStyle)
7+
8+
import Foundation
9+
10+
protocol InterfaceIdiomDependentFormatStyle: FormatStyle {
11+
func interfaceIdiom(_ idiom: AnyInterfaceIdiom) -> Self
12+
}
13+
14+
// TODO: Add conformance when these concrete format styles land:
15+
// SystemFormatStyle.Timer
16+
// SystemFormatStyle.Stopwatch
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// SafelySerializableDiscreteFormatStyle.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for 6.5.4
6+
// Status: WIP
7+
// ID: 6E7304511B702F2103288779936F04AA (SwiftUICore)
8+
9+
import Foundation
10+
11+
protocol SafelySerializableDiscreteFormatStyle: DiscreteFormatStyle where FormatOutput: AttributedStringConvertible {
12+
static func representation<Source>(
13+
of resolvable: TimeDataFormatting.Resolvable<Source, Self>,
14+
for version: ArchivedViewInput.DeploymentVersion
15+
) -> any ResolvableStringAttributeRepresentation
16+
where Source: TimeDataSourceStorage, Source.Value == FormatInput
17+
}
18+
19+
// TODO: Conformance

0 commit comments

Comments
 (0)