@@ -59,24 +59,41 @@ public final class DatePickerProps: ObservableObject, Decodable {
59
59
let container = try decoder. container ( keyedBy: CodingKeys . self)
60
60
61
61
label = try container. decodeIfPresent ( String . self, forKey: . label) ?? " "
62
+
63
+ // Ensure we have at least one component
64
+ displayedComponents = try container. decodeDatePickerComponents ( forKey: . displayedComponents)
62
65
// Decode selection as ISO8601 date string
63
- let selectionString = try container. decode ( String . self, forKey: . selection)
64
- let formatter = ISO8601DateFormatter ( )
65
- formatter. formatOptions = [ . withInternetDateTime, . withFractionalSeconds]
66
- guard let date = formatter. date ( from: selectionString) else {
67
- throw DecodingError . dataCorruptedError (
68
- forKey: . selection,
69
- in: container,
70
- debugDescription: " Invalid date format: \( selectionString) "
71
- )
66
+ let selectionString = try container. decodeIfPresent ( String . self, forKey: . selection) ?? " "
67
+ if !selectionString. isEmpty {
68
+ let formatter = ISO8601DateFormatter ( )
69
+ formatter. formatOptions = [ . withInternetDateTime, . withFractionalSeconds]
70
+
71
+ if let date = formatter. date ( from: selectionString) {
72
+ selection = date
73
+ } else {
74
+ // Try more permissive formats if strict ISO8601 fails
75
+ let fallbackFormatter = DateFormatter ( )
76
+ fallbackFormatter. dateFormat = " yyyy-MM-dd'T'HH:mm:ss "
77
+
78
+ if let date = fallbackFormatter. date ( from: selectionString) {
79
+ selection = date
80
+ } else {
81
+ throw DecodingError . dataCorruptedError (
82
+ forKey: . selection,
83
+ in: container,
84
+ debugDescription: " Invalid date format: \( selectionString) "
85
+ )
86
+ }
87
+ }
88
+ } else {
89
+ var calendar = Calendar . current
90
+ // calendar.timeZone = TimeZone(identifier: "UTC")!
91
+ selection = calendar. startOfDay ( for: Date ( ) )
72
92
}
73
- selection = date
93
+
74
94
// Decode datePickerStyle
75
95
let styleString = try container. decodeIfPresent ( String . self, forKey: . datePickerStyle) ?? " default "
76
96
datePickerStyle = DatePickerStyle ( rawValue: styleString) ?? . default
77
- // Decode displayedComponents
78
- let componentsString = try container. decodeIfPresent ( String . self, forKey: . displayedComponents)
79
- displayedComponents = componentsString == " date " ? . date : [ . date, . hourAndMinute]
80
97
disabled = try container. decodeIfPresent ( Bool . self, forKey: . disabled) ?? false
81
98
}
82
99
@@ -88,3 +105,44 @@ public final class DatePickerProps: ObservableObject, Decodable {
88
105
disabled = other. disabled
89
106
}
90
107
}
108
+
109
+ extension KeyedDecodingContainer {
110
+ func decodeDatePickerComponents( forKey key: Key ) throws -> DatePickerComponents {
111
+ var datePickerComponents : DatePickerComponents = . date // Default to date
112
+ if let componentArray = try ? decodeIfPresent ( [ String ] . self, forKey: key) {
113
+ // Handle array of components: ["date", "hourAndMinute"]
114
+ datePickerComponents = [ ]
115
+ for component in componentArray {
116
+ switch component. lowercased ( ) {
117
+ case " date " :
118
+ datePickerComponents. insert ( . date)
119
+ case " hourandminute " :
120
+ datePickerComponents. insert ( . hourAndMinute)
121
+ // case "era", "epoch":
122
+ // if #available(iOS 16.0, *) {
123
+ // datePickerComponents.insert(.era)
124
+ // }
125
+ default :
126
+ break
127
+ }
128
+ }
129
+ } else if let singleComponent = try ? decodeIfPresent ( String . self, forKey: key) {
130
+ // Simple single string component
131
+ switch singleComponent. lowercased ( ) {
132
+ case " date " :
133
+ datePickerComponents = . date
134
+ case " time " :
135
+ datePickerComponents = . hourAndMinute
136
+ case " datetime " :
137
+ datePickerComponents = [ . date, . hourAndMinute]
138
+ // case "era", "epoch":
139
+ // if #available(iOS 16.0, *) {
140
+ // datePickerComponents = .era
141
+ // }
142
+ default :
143
+ datePickerComponents = . date
144
+ }
145
+ }
146
+ return datePickerComponents
147
+ }
148
+ }
0 commit comments