Skip to content

Commit 3ccbe13

Browse files
authored
fix: widgets not consuming styles (#18)
This pull request fixes an issue where styles were not being correctly applied in Widgets. The root cause was missing logic for handling style and element deduplication via a shared registry.
1 parent 8f7efe5 commit 3ccbe13

1 file changed

Lines changed: 49 additions & 18 deletions

File tree

ios/target/VoltraHomeWidget.swift

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -137,30 +137,64 @@ private func selectContentForFamily(_ data: Data, family: WidgetFamily) -> Data
137137

138138
// Try to get content for the specific family
139139
if let familyContent = root[familyKey] {
140-
if JSONSerialization.isValidJSONObject(familyContent),
141-
let familyData = try? JSONSerialization.data(withJSONObject: familyContent)
142-
{
143-
return familyData
144-
}
140+
return reconstructWithSharedData(content: familyContent, root: root)
145141
}
146142

147143
// Fallback: try families in order of preference
148144
let fallbackOrder = ["systemMedium", "systemSmall", "systemLarge", "systemExtraLarge",
149145
"accessoryRectangular", "accessoryCircular", "accessoryInline"]
150146
for fallbackKey in fallbackOrder {
151147
if let fallbackContent = root[fallbackKey] {
152-
if JSONSerialization.isValidJSONObject(fallbackContent),
153-
let fallbackData = try? JSONSerialization.data(withJSONObject: fallbackContent)
154-
{
155-
return fallbackData
156-
}
148+
return reconstructWithSharedData(content: fallbackContent, root: root)
157149
}
158150
}
159151

160152
// No content found, return empty
161153
return Data("[]".utf8)
162154
}
163155

156+
/// Reconstruct JSON with family-specific content plus shared stylesheet and elements.
157+
/// This ensures VoltraNode.parse can resolve style references and element deduplication.
158+
private func reconstructWithSharedData(content: Any, root: [String: Any]) -> Data {
159+
var result: [String: Any] = [:]
160+
161+
// If content is a dictionary (single component), wrap it in the result
162+
// If content is an array or other type, it will be returned as-is below
163+
if let contentDict = content as? [String: Any] {
164+
// Copy all keys from the component
165+
result = contentDict
166+
}
167+
168+
// Add shared stylesheet if present (key "s")
169+
if let stylesheet = root["s"] {
170+
result["s"] = stylesheet
171+
}
172+
173+
// Add shared elements if present (key "e")
174+
if let sharedElements = root["e"] {
175+
result["e"] = sharedElements
176+
}
177+
178+
// If we built a result dict with shared data, serialize it
179+
if !result.isEmpty {
180+
if JSONSerialization.isValidJSONObject(result),
181+
let data = try? JSONSerialization.data(withJSONObject: result)
182+
{
183+
return data
184+
}
185+
}
186+
187+
// Fallback: return content as-is if it's serializable
188+
if JSONSerialization.isValidJSONObject(content),
189+
let data = try? JSONSerialization.data(withJSONObject: content)
190+
{
191+
return data
192+
}
193+
194+
// Final fallback: empty array
195+
return Data("[]".utf8)
196+
}
197+
164198
// MARK: - Deep link + rendering helpers
165199

166200
private func buildStaticContentView(data: Data, source _: String) -> AnyView {
@@ -233,14 +267,11 @@ private func normalizeJsonData(_ data: Data) -> Data? {
233267
return data
234268
}
235269

236-
// If it's a single component (dictionary), wrap it in an array
237-
if let dict = obj as? [String: Any] {
238-
guard JSONSerialization.isValidJSONObject([dict]),
239-
let wrapped = try? JSONSerialization.data(withJSONObject: [dict])
240-
else {
241-
return nil
242-
}
243-
return wrapped
270+
// If it's a single component (dictionary), return as-is
271+
// Don't wrap in array - VoltraNode.parse handles single objects and needs
272+
// to find "s" (stylesheet) and "e" (elements) at the root level
273+
if obj is [String: Any] {
274+
return data
244275
}
245276

246277
// Invalid input (string, number, boolean, null) - return nil to indicate error

0 commit comments

Comments
 (0)