@@ -177,15 +177,15 @@ const canBeFlattened = (node: Node): boolean => {
177177 * @param settings Plugin settings
178178 * @param parentNode Optional parent node reference to set
179179 * @param parentCumulativeRotation Optional parent cumulative rotation to inherit
180- * @returns Potentially modified jsonNode
180+ * @returns Potentially modified jsonNode, array of nodes (for inlined groups), or null
181181 */
182182const processNodePair = async (
183183 jsonNode : Node ,
184184 figmaNode : SceneNode ,
185185 settings : PluginSettings ,
186186 parentNode ?: Node ,
187187 parentCumulativeRotation : number = 0 ,
188- ) : Promise < Node | null > => {
188+ ) : Promise < Node | Node [ ] | null > => {
189189 if ( ! jsonNode . id ) return null ;
190190 if ( jsonNode . visible === false ) return null ;
191191
@@ -195,6 +195,9 @@ const processNodePair = async (
195195 // Handle node type-specific conversions (from convertNodeToAltNode)
196196 const nodeType = jsonNode . type ;
197197
198+ // Store the cumulative rotation (parent's cumulative + node's own)
199+ jsonNode . cumulativeRotation = parentCumulativeRotation ;
200+
198201 // Handle empty frames and convert to rectangles
199202 if (
200203 ( nodeType === "FRAME" ||
@@ -214,21 +217,46 @@ const processNodePair = async (
214217 ) ;
215218 }
216219
217- // Handle single-child groups that should be ungrouped
218- if (
219- nodeType === "GROUP" &&
220- jsonNode . children &&
221- jsonNode . children . length === 1 &&
222- jsonNode . visible
223- ) {
224- // Process the child directly, but preserve parent reference
225- return processNodePair (
226- jsonNode . children [ 0 ] ,
227- ( figmaNode as GroupNode ) . children [ 0 ] ,
228- settings ,
229- parentNode ,
230- parentCumulativeRotation ,
231- ) ;
220+ if ( "rotation" in jsonNode ) {
221+ jsonNode . rotation = - jsonNode . rotation * ( 180 / Math . PI ) ;
222+ }
223+
224+ // Inline all GROUP nodes by processing their children directly
225+ if ( nodeType === "GROUP" && jsonNode . children ) {
226+ const processedChildren = [ ] ;
227+
228+ if (
229+ Array . isArray ( jsonNode . children ) &&
230+ figmaNode &&
231+ "children" in figmaNode &&
232+ figmaNode . children . length === jsonNode . children . length
233+ ) {
234+ for ( let i = 0 ; i < jsonNode . children . length ; i ++ ) {
235+ const child = jsonNode . children [ i ] ;
236+ const figmaChild = figmaNode . children [ i ] ;
237+ if ( ! figmaChild ) continue ;
238+
239+ const processedChild = await processNodePair (
240+ child ,
241+ figmaChild ,
242+ settings ,
243+ parentNode , // The group’s parent
244+ parentCumulativeRotation + ( jsonNode . rotation || 0 ) ,
245+ ) ;
246+
247+ // Push the processed group children directly
248+ if ( processedChild !== null ) {
249+ if ( Array . isArray ( processedChild ) ) {
250+ processedChildren . push ( ...processedChild ) ;
251+ } else {
252+ processedChildren . push ( processedChild ) ;
253+ }
254+ }
255+ }
256+ }
257+
258+ // Simply return the processed children; skip splicing parent’s children
259+ return processedChildren ;
232260 }
233261
234262 // Return null for unsupported nodes
@@ -241,11 +269,6 @@ const processNodePair = async (
241269 ( jsonNode as any ) . parent = parentNode ;
242270 }
243271
244- // Store the cumulative rotation (parent's cumulative + node's own)
245- if ( parentNode ?. type === "GROUP" ) {
246- jsonNode . cumulativeRotation = parentCumulativeRotation ;
247- }
248-
249272 // Ensure node has a unique name with simple numbering
250273 const cleanName = jsonNode . name . trim ( ) ;
251274
@@ -342,10 +365,6 @@ const processNodePair = async (
342365 jsonNode . y = figmaNode . y ;
343366 }
344367
345- if ( "rotation" in jsonNode ) {
346- jsonNode . rotation = jsonNode . rotation * ( 180 / Math . PI ) ;
347- }
348-
349368 if ( "individualStrokeWeights" in jsonNode ) {
350369 jsonNode . strokeTopWeight = jsonNode . individualStrokeWeights . top ;
351370 jsonNode . strokeBottomWeight = jsonNode . individualStrokeWeights . bottom ;
@@ -424,7 +443,11 @@ const processNodePair = async (
424443 ) ;
425444
426445 if ( processedChild !== null ) {
427- processedChildren . push ( processedChild ) ;
446+ if ( Array . isArray ( processedChild ) ) {
447+ processedChildren . push ( ...processedChild ) ;
448+ } else {
449+ processedChildren . push ( processedChild ) ;
450+ }
428451 }
429452 }
430453
@@ -488,12 +511,28 @@ export const nodesToJSON = async (
488511
489512 // Now process each top-level node pair (JSON node + Figma node)
490513 const processNodesStart = Date . now ( ) ;
514+ const result : Node [ ] = [ ] ;
515+
491516 for ( let i = 0 ; i < nodes . length ; i ++ ) {
492- await processNodePair ( nodeJson [ i ] , nodes [ i ] , settings ) ;
517+ const processedNode = await processNodePair (
518+ nodeJson [ i ] ,
519+ nodes [ i ] ,
520+ settings ,
521+ ) ;
522+ if ( processedNode !== null ) {
523+ if ( Array . isArray ( processedNode ) ) {
524+ // If processNodePair returns an array (inlined group), add all nodes
525+ result . push ( ...processedNode ) ;
526+ } else {
527+ // If it returns a single node, add it directly
528+ result . push ( processedNode ) ;
529+ }
530+ }
493531 }
532+
494533 console . log (
495534 `[benchmark][inside nodesToJSON] Process node pairs: ${ Date . now ( ) - processNodesStart } ms` ,
496535 ) ;
497536
498- return nodeJson ;
537+ return result ;
499538} ;
0 commit comments