Skip to content

Commit f1a6122

Browse files
committed
Fix ordering with Figma.
1 parent 4436712 commit f1a6122

File tree

8 files changed

+94
-38
lines changed

8 files changed

+94
-38
lines changed

apps/plugin/plugin-src/code.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ switch (figma.mode) {
108108
// figma.codegen.on("preferenceschange", (preferences) => {
109109

110110
// });
111-
112111
figma.codegen.on("generate", ({ language, node }) => {
113112
const convertedSelection = convertIntoNodes([node], null);
114113

packages/backend/src/altNodes/altConversion.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const frameNodeTo = (
4141
return frameToRectangleNode(node, parent);
4242
}
4343
const clone = standardClone(node, parent);
44+
4445
overrideReadonlyProperty(
4546
clone,
4647
"children",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export const commonSortChildrenWhenInferredAutoLayout = (
2+
node: SceneNode & ChildrenMixin,
3+
optimize: boolean
4+
) => {
5+
if (node.children.length <= 1) {
6+
return node.children;
7+
}
8+
9+
if (
10+
optimize &&
11+
"inferredAutoLayout" in node &&
12+
node.inferredAutoLayout !== null
13+
) {
14+
const children = [...node.children];
15+
switch (node.inferredAutoLayout.layoutMode) {
16+
case "HORIZONTAL":
17+
return children.sort((a, b) => a.x - b.x);
18+
// NONE is a bug from Figma.
19+
case "NONE":
20+
case "VERTICAL":
21+
console.log(
22+
"ordering",
23+
children.map((c) => c.name),
24+
children.sort((a, b) => a.y - b.y).map((c) => c.name)
25+
);
26+
return children.sort((a, b) => a.y - b.y);
27+
}
28+
}
29+
console.log("no inferredAutoLayout for ", node.name);
30+
return node.children;
31+
};

packages/backend/src/common/nodeWidthHeight.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,24 @@ export const nodeSize = (
1010
const hasLayout =
1111
"layoutAlign" in node && node.parent && "layoutMode" in node.parent;
1212

13-
if (!hasLayout || ("layoutMode" in node && node.layoutMode === "NONE")) {
13+
if (!hasLayout) {
1414
return { width: node.width, height: node.height };
1515
}
1616

17-
// const parentLayoutMode = node.parent.layoutMode;
18-
const parentLayoutMode = optimizeLayout
19-
? node.parent.inferredAutoLayout?.layoutMode
20-
: null ?? node.parent.layoutMode;
21-
2217
const nodeAuto =
2318
(optimizeLayout && "inferredAutoLayout" in node
2419
? node.inferredAutoLayout
2520
: null) ?? node;
2621

22+
if ("layoutMode" in nodeAuto && nodeAuto.layoutMode === "NONE") {
23+
return { width: node.width, height: node.height };
24+
}
25+
26+
// const parentLayoutMode = node.parent.layoutMode;
27+
const parentLayoutMode = optimizeLayout
28+
? node.parent.inferredAutoLayout?.layoutMode
29+
: null ?? node.parent.layoutMode;
30+
2731
const isWidthFill =
2832
(parentLayoutMode === "HORIZONTAL" && nodeAuto.layoutGrow === 1) ||
2933
(parentLayoutMode === "VERTICAL" && nodeAuto.layoutAlign === "STRETCH");

packages/backend/src/flutter/flutterMain.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
getCrossAxisAlignment,
99
getMainAxisAlignment,
1010
} from "./builderImpl/flutterAutoLayout";
11+
import { commonSortChildrenWhenInferredAutoLayout } from "../common/commonChildrenOrder";
1112

1213
let localSettings: PluginSettings;
1314
let previousExecutionCache: string[];
@@ -167,7 +168,9 @@ const flutterText = (node: TextNode): string => {
167168
const flutterFrame = (
168169
node: SceneNode & BaseFrameMixin & MinimalBlendMixin
169170
): string => {
170-
const children = flutterWidgetGenerator(node.children);
171+
const children = flutterWidgetGenerator(
172+
commonSortChildrenWhenInferredAutoLayout(node, localSettings.optimizeLayout)
173+
);
171174

172175
if (node.layoutMode !== "NONE") {
173176
const rowColumn = makeRowColumn(node, node, children);

packages/backend/src/html/htmlMain.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { HtmlDefaultBuilder } from "./htmlDefaultBuilder";
55
import { PluginSettings } from "../code";
66
import { htmlAutoLayoutProps } from "./builderImpl/htmlAutoLayout";
77
import { formatWithJSX } from "../common/parseJSX";
8+
import { commonSortChildrenWhenInferredAutoLayout } from "../common/commonChildrenOrder";
89

910
let showLayerName = false;
1011

@@ -135,7 +136,13 @@ const htmlFrame = (
135136
node: SceneNode & BaseFrameMixin,
136137
isJsx: boolean = false
137138
): string => {
138-
const childrenStr = htmlWidgetGenerator(node.children, isJsx);
139+
const childrenStr = htmlWidgetGenerator(
140+
commonSortChildrenWhenInferredAutoLayout(
141+
node,
142+
localSettings.optimizeLayout
143+
),
144+
isJsx
145+
);
139146

140147
if (node.layoutMode !== "NONE") {
141148
const rowColumn = htmlAutoLayoutProps(node, node, isJsx);

packages/backend/src/swiftui/swiftuiMain.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { className, sliceNum } from "../common/numToAutoFixed";
33
import { SwiftuiTextBuilder } from "./swiftuiTextBuilder";
44
import { SwiftuiDefaultBuilder } from "./swiftuiDefaultBuilder";
55
import { PluginSettings } from "../code";
6+
import { commonSortChildrenWhenInferredAutoLayout } from "../common/commonChildrenOrder";
67

78
let localSettings: PluginSettings;
89
let previousExecutionCache: string[];
@@ -68,6 +69,7 @@ const swiftuiWidgetGenerator = (
6869
switch (node.type) {
6970
case "RECTANGLE":
7071
case "ELLIPSE":
72+
case "LINE":
7173
comp.push(swiftuiContainer(node));
7274
break;
7375
case "GROUP":
@@ -105,7 +107,7 @@ export const swiftuiContainer = (
105107
}
106108

107109
let kind = "";
108-
if (node.type === "RECTANGLE") {
110+
if (node.type === "RECTANGLE" || node.type === "LINE") {
109111
kind = "Rectangle()";
110112
} else if (node.type === "ELLIPSE") {
111113
kind = "Ellipse()";
@@ -234,17 +236,26 @@ export const generateSwiftViewCode = (
234236

235237
// todo should the plugin manually Group items? Ideally, it would detect the similarities and allow a ForEach.
236238
const widgetGeneratorWithLimits = (
237-
node: ChildrenMixin,
239+
node: SceneNode & ChildrenMixin,
238240
indentLevel: number
239241
) => {
240242
if (node.children.length < 10) {
241243
// standard way
242-
return swiftuiWidgetGenerator(node.children, indentLevel);
244+
return swiftuiWidgetGenerator(
245+
commonSortChildrenWhenInferredAutoLayout(
246+
node,
247+
localSettings.optimizeLayout
248+
),
249+
indentLevel
250+
);
243251
}
244252

245253
const chunk = 10;
246254
let strBuilder = "";
247-
const slicedChildren = node.children.slice(0, 100);
255+
const slicedChildren = commonSortChildrenWhenInferredAutoLayout(
256+
node,
257+
localSettings.optimizeLayout
258+
).slice(0, 100);
248259

249260
// I believe no one should have more than 100 items in a single nesting level. If you do, please email me.
250261
if (node.children.length > 100) {

packages/backend/src/tailwind/tailwindMain.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@ import { TailwindTextBuilder } from "./tailwindTextBuilder";
55
import { TailwindDefaultBuilder } from "./tailwindDefaultBuilder";
66
import { PluginSettings } from "../code";
77
import { tailwindAutoLayoutProps } from "./builderImpl/tailwindAutoLayout";
8+
import { commonSortChildrenWhenInferredAutoLayout } from "../common/commonChildrenOrder";
89

9-
let globalLocalSettings: PluginSettings;
10+
let localSettings: PluginSettings;
1011

1112
let previousExecutionCache: { style: string; text: string }[];
1213

1314
const selfClosingTags = ["img"];
1415

1516
export const tailwindMain = (
1617
sceneNode: Array<SceneNode>,
17-
localSettings: PluginSettings
18+
settings: PluginSettings
1819
): string => {
19-
globalLocalSettings = localSettings;
20+
localSettings = settings;
2021
previousExecutionCache = [];
2122

2223
let result = tailwindWidgetGenerator(sceneNode, localSettings.jsx);
@@ -81,7 +82,7 @@ const tailwindGroup = (node: GroupNode, isJsx: boolean = false): string => {
8182

8283
const vectorIfExists = tailwindVector(
8384
node,
84-
globalLocalSettings.layerName,
85+
localSettings.layerName,
8586
"",
8687
isJsx
8788
);
@@ -90,12 +91,12 @@ const tailwindGroup = (node: GroupNode, isJsx: boolean = false): string => {
9091
// this needs to be called after CustomNode because widthHeight depends on it
9192
const builder = new TailwindDefaultBuilder(
9293
node,
93-
globalLocalSettings.layerName,
94+
localSettings.layerName,
9495
isJsx
9596
)
9697
.blend(node)
97-
.size(node, globalLocalSettings.optimizeLayout)
98-
.position(node, globalLocalSettings.optimizeLayout);
98+
.size(node, localSettings.optimizeLayout)
99+
.position(node, localSettings.optimizeLayout);
99100

100101
if (builder.attributes || builder.style) {
101102
const attr = builder.build("");
@@ -111,10 +112,10 @@ const tailwindGroup = (node: GroupNode, isJsx: boolean = false): string => {
111112
export const tailwindText = (node: TextNode, isJsx: boolean): string => {
112113
let layoutBuilder = new TailwindTextBuilder(
113114
node,
114-
globalLocalSettings.layerName,
115+
localSettings.layerName,
115116
isJsx
116117
)
117-
.commonPositionStyles(node, globalLocalSettings.optimizeLayout)
118+
.commonPositionStyles(node, localSettings.optimizeLayout)
118119
.textAlign(node);
119120

120121
const styledHtml = layoutBuilder.getTextSegments(node.id);
@@ -137,16 +138,19 @@ const tailwindFrame = (
137138
node: FrameNode | InstanceNode | ComponentNode | ComponentSetNode,
138139
isJsx: boolean
139140
): string => {
140-
const childrenStr = tailwindWidgetGenerator(node.children, isJsx);
141+
const childrenStr = tailwindWidgetGenerator(
142+
commonSortChildrenWhenInferredAutoLayout(
143+
node,
144+
localSettings.optimizeLayout
145+
),
146+
isJsx
147+
);
141148

142149
if (node.layoutMode !== "NONE") {
143150
const rowColumn = tailwindAutoLayoutProps(node, node);
144151
return tailwindContainer(node, childrenStr, rowColumn, isJsx);
145152
} else {
146-
if (
147-
globalLocalSettings.optimizeLayout &&
148-
node.inferredAutoLayout !== null
149-
) {
153+
if (localSettings.optimizeLayout && node.inferredAutoLayout !== null) {
150154
const rowColumn = tailwindAutoLayoutProps(node, node.inferredAutoLayout);
151155
return tailwindContainer(node, childrenStr, rowColumn, isJsx);
152156
}
@@ -177,12 +181,8 @@ export const tailwindContainer = (
177181
return children;
178182
}
179183

180-
let builder = new TailwindDefaultBuilder(
181-
node,
182-
globalLocalSettings.layerName,
183-
isJsx
184-
)
185-
.commonPositionStyles(node, globalLocalSettings.optimizeLayout)
184+
let builder = new TailwindDefaultBuilder(node, localSettings.layerName, isJsx)
185+
.commonPositionStyles(node, localSettings.optimizeLayout)
186186
.commonShapeStyles(node);
187187

188188
if (builder.attributes || additionalAttr) {
@@ -221,10 +221,10 @@ export const tailwindContainer = (
221221
export const tailwindLine = (node: LineNode, isJsx: boolean): string => {
222222
const builder = new TailwindDefaultBuilder(
223223
node,
224-
globalLocalSettings.layerName,
224+
localSettings.layerName,
225225
isJsx
226226
)
227-
.commonPositionStyles(node, globalLocalSettings.optimizeLayout)
227+
.commonPositionStyles(node, localSettings.optimizeLayout)
228228
.commonShapeStyles(node);
229229

230230
return `\n<div${builder.build()}></div>`;
@@ -234,11 +234,11 @@ export const tailwindSection = (node: SectionNode, isJsx: boolean): string => {
234234
const childrenStr = tailwindWidgetGenerator(node.children, isJsx);
235235
const builder = new TailwindDefaultBuilder(
236236
node,
237-
globalLocalSettings.layerName,
237+
localSettings.layerName,
238238
isJsx
239239
)
240-
.size(node, globalLocalSettings.optimizeLayout)
241-
.position(node, globalLocalSettings.optimizeLayout)
240+
.size(node, localSettings.optimizeLayout)
241+
.position(node, localSettings.optimizeLayout)
242242
.customColor(node.fills, "bg");
243243

244244
if (childrenStr) {

0 commit comments

Comments
 (0)