@seed-design/figma 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/lib/index.cjs +556 -471
  2. package/lib/index.d.ts +29 -4
  3. package/lib/index.js +556 -471
  4. package/package.json +2 -2
  5. package/src/component/handlers/action-button.ts +66 -0
  6. package/src/component/handlers/action-chip.ts +71 -0
  7. package/src/component/handlers/action-sheet.ts +74 -0
  8. package/src/component/handlers/app-bar.ts +183 -0
  9. package/src/component/handlers/avatar-stack.ts +35 -0
  10. package/src/component/handlers/avatar.ts +37 -0
  11. package/src/component/handlers/badge.ts +20 -0
  12. package/src/component/handlers/callout.ts +87 -0
  13. package/src/component/handlers/checkbox.ts +32 -0
  14. package/src/component/handlers/chip-tabs.ts +51 -0
  15. package/src/component/handlers/control-chip.ts +75 -0
  16. package/src/component/handlers/error-state.ts +37 -0
  17. package/src/component/handlers/extended-action-sheet.ts +86 -0
  18. package/src/component/handlers/extended-fab.ts +24 -0
  19. package/src/component/handlers/fab.ts +17 -0
  20. package/src/component/handlers/help-bubble.ts +66 -0
  21. package/src/component/handlers/identity-placeholder.ts +16 -0
  22. package/src/component/handlers/inline-banner.ts +83 -0
  23. package/src/component/handlers/manner-temp-badge.ts +17 -0
  24. package/src/component/handlers/multiline-text-field.ts +80 -0
  25. package/src/component/handlers/progress-circle.ts +49 -0
  26. package/src/component/handlers/reaction-button.ts +36 -0
  27. package/src/component/handlers/segmented-control.ts +51 -0
  28. package/src/component/handlers/select-box.ts +76 -0
  29. package/src/component/handlers/skeleton.ts +51 -0
  30. package/src/component/handlers/snackbar.ts +21 -0
  31. package/src/component/handlers/switch.ts +29 -0
  32. package/src/component/handlers/tabs.ts +107 -0
  33. package/src/component/handlers/text-button.ts +57 -0
  34. package/src/component/handlers/text-field.ts +108 -0
  35. package/src/component/handlers/toggle-button.ts +44 -0
  36. package/src/component/index.ts +32 -1644
  37. package/src/component/type-helper.ts +11 -0
  38. package/src/generate-code.ts +183 -145
  39. package/src/icon.ts +2 -2
  40. package/src/index.ts +1 -2
  41. package/src/jsx.ts +1 -1
  42. package/src/layout.ts +23 -281
  43. package/src/normalizer/from-plugin.ts +24 -4
  44. package/src/normalizer/from-rest.ts +22 -4
  45. package/src/normalizer/index.ts +3 -0
  46. package/src/normalizer/types.ts +3 -1
  47. package/src/{color.ts → props/color.ts} +1 -1
  48. package/src/props/layout.ts +292 -0
  49. package/src/{sizing.ts → props/sizing.ts} +17 -17
  50. package/src/{text.ts → props/text.ts} +2 -1
  51. package/src/{variable.ts → props/variable.ts} +1 -1
  52. package/src/{util.ts → utils/common.ts} +0 -2
  53. package/src/{node-util.ts → utils/figma-node.ts} +1 -1
package/src/layout.ts CHANGED
@@ -1,289 +1,31 @@
1
- import type {
2
- NormalizedComponentNode,
3
- NormalizedFrameNode,
4
- NormalizedInstanceNode,
5
- NormalizedSceneNode,
6
- } from "./normalizer/types";
7
- import { getLayoutVariableName, inferDimension, inferRadius } from "./variable";
8
-
9
- interface FigmaLayoutProps {
10
- layoutMode?: NormalizedFrameNode["layoutMode"];
11
- layoutWrap?: NormalizedFrameNode["layoutWrap"];
12
- paddingLeft?: NormalizedFrameNode["paddingLeft"];
13
- paddingRight?: NormalizedFrameNode["paddingRight"];
14
- paddingTop?: NormalizedFrameNode["paddingTop"];
15
- paddingBottom?: NormalizedFrameNode["paddingBottom"];
16
- primaryAxisAlignItems?: NormalizedFrameNode["primaryAxisAlignItems"];
17
- counterAxisAlignItems?: NormalizedFrameNode["counterAxisAlignItems"];
18
- primaryAxisSizingMode?: NormalizedFrameNode["primaryAxisSizingMode"];
19
- counterAxisSizingMode?: NormalizedFrameNode["counterAxisSizingMode"];
20
- layoutGrow?: NormalizedFrameNode["layoutGrow"];
21
- layoutAlign?: NormalizedFrameNode["layoutAlign"];
22
- itemSpacing?: NormalizedFrameNode["itemSpacing"];
23
- counterAxisSpacing?: NormalizedFrameNode["counterAxisSpacing"];
24
- boundVariables?: NormalizedFrameNode["boundVariables"];
25
- cornerRadius?: NormalizedFrameNode["cornerRadius"];
26
- rectangleCornerRadii?: NormalizedFrameNode["rectangleCornerRadii"];
27
- children: NormalizedSceneNode[];
1
+ export interface LayoutComponentProps {
2
+ flexDirection: string | number | boolean;
3
+ alignItems: string | number | boolean;
4
+ justifyContent: string | number | boolean;
5
+ flexWrap: string | number | boolean;
28
6
  }
29
7
 
30
- type LayoutPropHandler = (props: FigmaLayoutProps) => string | number | boolean | undefined;
31
-
32
- const layoutPropHandlers = {
33
- flexDirection: ({ layoutMode }) => (layoutMode === "HORIZONTAL" ? "row" : "column"),
34
- justifyContent: ({ primaryAxisAlignItems }) => {
35
- switch (primaryAxisAlignItems) {
36
- case "MIN":
37
- return "flexStart";
38
- case "CENTER":
39
- return "center";
40
- case "MAX":
41
- return "flexEnd";
42
- case "SPACE_BETWEEN":
43
- return "spaceBetween";
44
- }
45
- },
46
- alignItems: ({ counterAxisAlignItems, children }) => {
47
- const isStretch = children.every((child) => {
48
- if (!("layoutAlign" in child)) {
49
- return false;
50
- }
51
-
52
- return child.layoutAlign === "STRETCH";
53
- });
54
-
55
- if (isStretch) {
56
- return "stretch";
57
- }
58
-
59
- switch (counterAxisAlignItems) {
60
- case "MIN":
61
- return "flexStart";
62
- case "CENTER":
63
- return "center";
64
- case "MAX":
65
- return "flexEnd";
66
- case "BASELINE":
67
- return "baseline";
68
- }
69
- },
70
- flexWrap: ({ layoutWrap }) => (layoutWrap === "WRAP" ? "wrap" : "nowrap"),
71
- flexGrow: ({ layoutGrow }) => layoutGrow,
72
- alignSelf: ({ layoutAlign }) => {
73
- switch (layoutAlign) {
74
- case "STRETCH":
75
- return "stretch";
76
- case "MIN":
77
- return "flexStart";
78
- case "CENTER":
79
- return "center";
80
- case "MAX":
81
- return "flexEnd";
82
- }
83
- },
84
- gap: ({ itemSpacing, boundVariables, primaryAxisAlignItems, children }) =>
85
- children.length <= 1
86
- ? 0
87
- : primaryAxisAlignItems === "SPACE_BETWEEN"
88
- ? 0
89
- : boundVariables?.itemSpacing
90
- ? getLayoutVariableName(boundVariables.itemSpacing.id)
91
- : inferDimension(itemSpacing ?? 0),
92
- paddingTop: ({ paddingTop, boundVariables }) =>
93
- boundVariables?.paddingTop
94
- ? getLayoutVariableName(boundVariables.paddingTop.id)
95
- : inferDimension(paddingTop ?? 0),
96
- paddingBottom: ({ paddingBottom, boundVariables }) =>
97
- boundVariables?.paddingBottom
98
- ? getLayoutVariableName(boundVariables.paddingBottom.id)
99
- : inferDimension(paddingBottom ?? 0),
100
- paddingLeft: ({ paddingLeft, boundVariables }) =>
101
- boundVariables?.paddingLeft
102
- ? getLayoutVariableName(boundVariables.paddingLeft.id)
103
- : inferDimension(paddingLeft ?? 0),
104
- paddingRight: ({ paddingRight, boundVariables }) =>
105
- boundVariables?.paddingRight
106
- ? getLayoutVariableName(boundVariables.paddingRight.id)
107
- : inferDimension(paddingRight ?? 0),
108
- borderRadius: ({ cornerRadius, boundVariables }) => {
109
- // If all corner radii are the same, use the first one
110
- if (
111
- cornerRadius &&
112
- boundVariables?.bottomLeftRadius === boundVariables?.bottomRightRadius &&
113
- boundVariables?.bottomLeftRadius === boundVariables?.topLeftRadius &&
114
- boundVariables?.bottomLeftRadius === boundVariables?.topRightRadius
115
- ) {
116
- return boundVariables?.bottomLeftRadius
117
- ? getLayoutVariableName(boundVariables.bottomLeftRadius.id)
118
- : inferRadius(cornerRadius ?? 0);
119
- }
120
-
121
- // TODO: handle individual corner radii
122
- return undefined;
123
- },
124
- borderTopLeftRadius: ({ rectangleCornerRadii, boundVariables }) =>
125
- boundVariables?.topLeftRadius
126
- ? getLayoutVariableName(boundVariables.topLeftRadius.id)
127
- : inferRadius(rectangleCornerRadii?.[0] ?? 0),
128
- borderTopRightRadius: ({ rectangleCornerRadii, boundVariables }) =>
129
- boundVariables?.topRightRadius
130
- ? getLayoutVariableName(boundVariables.topRightRadius.id)
131
- : inferRadius(rectangleCornerRadii?.[1] ?? 0),
132
- borderBottomLeftRadius: ({ rectangleCornerRadii, boundVariables }) =>
133
- boundVariables?.bottomLeftRadius
134
- ? getLayoutVariableName(boundVariables.bottomLeftRadius.id)
135
- : inferRadius(rectangleCornerRadii?.[2] ?? 0),
136
- borderBottomRightRadius: ({ rectangleCornerRadii, boundVariables }) =>
137
- boundVariables?.bottomRightRadius
138
- ? getLayoutVariableName(boundVariables.bottomRightRadius.id)
139
- : inferRadius(rectangleCornerRadii?.[3] ?? 0),
140
- } satisfies Record<string, LayoutPropHandler>;
141
-
142
- type LayoutProps = keyof typeof layoutPropHandlers;
143
-
144
- type LayoutShorthandHandler = (props: Record<LayoutProps, string | number | boolean | undefined>) =>
145
- | {
146
- value: string | number | boolean | undefined;
147
- exclude: LayoutProps[];
148
- }
149
- | undefined;
150
-
151
- const layoutShorthandHandlers = {
152
- paddingX: ({ paddingLeft, paddingRight, paddingTop, paddingBottom }) => {
153
- if (
154
- paddingLeft === paddingRight &&
155
- paddingTop === paddingBottom &&
156
- paddingLeft === paddingTop
157
- ) {
158
- return undefined;
159
- }
160
- if (paddingLeft === paddingRight) {
161
- const value =
162
- paddingLeft === "globalGutter" || paddingLeft === "betweenChips"
163
- ? `spacingX.${paddingLeft}`
164
- : paddingLeft;
165
- return {
166
- value,
167
- exclude: ["paddingLeft", "paddingRight"],
168
- };
169
- }
170
- return undefined;
171
- },
172
- paddingY: ({ paddingLeft, paddingRight, paddingTop, paddingBottom }) => {
173
- if (
174
- paddingLeft === paddingRight &&
175
- paddingTop === paddingBottom &&
176
- paddingLeft === paddingTop
177
- ) {
178
- return undefined;
179
- }
180
- if (paddingTop === paddingBottom) {
181
- return {
182
- value: paddingTop,
183
- exclude: ["paddingTop", "paddingBottom"],
184
- };
185
- }
186
- return undefined;
187
- },
188
- padding: ({ paddingLeft, paddingRight, paddingTop, paddingBottom }) => {
189
- if (
190
- paddingLeft === paddingRight &&
191
- paddingTop === paddingBottom &&
192
- paddingLeft === paddingTop
193
- ) {
194
- return {
195
- value: paddingLeft,
196
- exclude: ["paddingLeft", "paddingRight", "paddingTop", "paddingBottom"],
197
- };
198
- }
199
- return undefined;
200
- },
201
- } satisfies Record<string, LayoutShorthandHandler>;
202
-
203
- type LayoutShorthandProps = keyof typeof layoutShorthandHandlers;
204
-
205
- const layoutPropDefaults: Record<string, string | number | boolean> = {
206
- flexDirection: "row",
207
- justifyContent: "flexStart",
208
- alignItems: "stretch",
209
- flexWrap: "nowrap",
210
- flexGrow: 0,
211
- alignSelf: "auto",
212
- gap: 0,
213
- padding: 0,
214
- paddingX: 0,
215
- paddingY: 0,
216
- paddingBottom: 0,
217
- paddingLeft: 0,
218
- paddingRight: 0,
219
- paddingTop: 0,
220
- borderRadius: 0,
221
- borderTopLeftRadius: 0,
222
- borderTopRightRadius: 0,
223
- borderBottomLeftRadius: 0,
224
- borderBottomRightRadius: 0,
225
- } satisfies Record<LayoutProps | LayoutShorthandProps, string | number | boolean>;
226
-
227
- type FrameLikeNode = NormalizedFrameNode | NormalizedComponentNode | NormalizedInstanceNode;
228
-
229
- export function createLayoutProps(
230
- node: FrameLikeNode,
231
- ): Record<LayoutProps | LayoutShorthandProps, string | number | boolean> {
232
- const boundVariables = node.boundVariables;
233
- const children = node.children;
234
-
235
- const autoLayoutProperties = {
236
- layoutMode: node.layoutMode,
237
- layoutWrap: node.layoutWrap,
238
- paddingLeft: node.paddingLeft,
239
- paddingRight: node.paddingRight,
240
- paddingTop: node.paddingTop,
241
- paddingBottom: node.paddingBottom,
242
- primaryAxisAlignItems: node.primaryAxisAlignItems,
243
- counterAxisAlignItems: node.counterAxisAlignItems,
244
- primaryAxisSizingMode: node.primaryAxisSizingMode,
245
- counterAxisSizingMode: node.counterAxisSizingMode,
246
- layoutGrow: node.layoutGrow,
247
- layoutAlign: node.layoutAlign,
248
- itemSpacing: node.itemSpacing,
249
- counterAxisSpacing: node.counterAxisSpacing,
250
- };
251
-
252
- const radiusProperties = {
253
- cornerRadius: node.cornerRadius,
254
- topLeftRadius: node.rectangleCornerRadii?.[0],
255
- topRightRadius: node.rectangleCornerRadii?.[1],
256
- bottomRightRadius: node.rectangleCornerRadii?.[2],
257
- bottomLeftRadius: node.rectangleCornerRadii?.[3],
258
- };
259
-
260
- const result: Record<string, string | number | boolean> = {};
8
+ export function inferLayoutComponent(props: LayoutComponentProps) {
9
+ if (
10
+ props.flexDirection === "row" &&
11
+ props.alignItems === "flexStart" &&
12
+ props.justifyContent === "flexStart" &&
13
+ props.flexWrap === "wrap"
14
+ ) {
15
+ return "Inline";
16
+ }
261
17
 
262
- for (const [prop, handler] of Object.entries(layoutPropHandlers)) {
263
- const value = handler({
264
- ...autoLayoutProperties,
265
- ...radiusProperties,
266
- boundVariables,
267
- children,
268
- });
269
- if (value !== undefined && value !== layoutPropDefaults[prop]) {
270
- result[prop] = value;
271
- }
18
+ if (
19
+ props.flexDirection === "row" &&
20
+ props.justifyContent === "flexStart" &&
21
+ props.flexWrap === "nowrap"
22
+ ) {
23
+ return "Columns";
272
24
  }
273
25
 
274
- for (const [prop, handler] of Object.entries(layoutShorthandHandlers)) {
275
- const shorthandResult = handler(result);
276
- if (shorthandResult === undefined) {
277
- continue;
278
- }
279
- const { value, exclude } = shorthandResult;
280
- if (value !== undefined && value !== layoutPropDefaults[prop]) {
281
- result[prop] = value;
282
- for (const excludedProp of exclude) {
283
- delete result[excludedProp];
284
- }
285
- }
26
+ if (props.flexDirection === "column") {
27
+ return "Stack";
286
28
  }
287
29
 
288
- return result;
30
+ return "Flex";
289
31
  }
@@ -7,9 +7,14 @@ import type {
7
7
  NormalizedComponentNode,
8
8
  NormalizedInstanceNode,
9
9
  NormalizedVectorNode,
10
+ NormalizedBooleanOperationNode,
10
11
  } from "./types";
11
12
 
12
13
  export function createPluginNormalizer() {
14
+ async function normalizeNodes(nodes: readonly SceneNode[]): Promise<NormalizedSceneNode[]> {
15
+ return Promise.all(nodes.filter((node) => node.visible).map(normalizeNode));
16
+ }
17
+
13
18
  async function normalizeNode(node: SceneNode): Promise<NormalizedSceneNode> {
14
19
  if (node.type === "FRAME") {
15
20
  return normalizeFrameNode(node);
@@ -23,6 +28,9 @@ export function createPluginNormalizer() {
23
28
  if (node.type === "VECTOR") {
24
29
  return normalizeVectorNode(node);
25
30
  }
31
+ if (node.type === "BOOLEAN_OPERATION") {
32
+ return normalizeBooleanOperationNode(node);
33
+ }
26
34
  if (node.type === "TEXT") {
27
35
  return normalizeTextNode(node);
28
36
  }
@@ -44,7 +52,7 @@ export function createPluginNormalizer() {
44
52
  boundVariables: await normalizeBoundVariables(node),
45
53
  ...normalizeRadiusProps(node),
46
54
  ...normalizeAutolayoutProps(node),
47
- children: await Promise.all(node.children.map(normalizeNode)),
55
+ children: await normalizeNodes(node.children),
48
56
  };
49
57
  }
50
58
 
@@ -75,7 +83,7 @@ export function createPluginNormalizer() {
75
83
  counterAxisSpacing: node.inferredAutoLayout?.counterAxisSpacing ?? undefined,
76
84
  fills: [],
77
85
  strokes: [],
78
- children: await Promise.all(node.children.map(normalizeNode)),
86
+ children: await normalizeNodes(node.children),
79
87
  };
80
88
  }
81
89
 
@@ -100,6 +108,18 @@ export function createPluginNormalizer() {
100
108
  };
101
109
  }
102
110
 
111
+ async function normalizeBooleanOperationNode(
112
+ node: BooleanOperationNode,
113
+ ): Promise<NormalizedBooleanOperationNode> {
114
+ return {
115
+ type: node.type,
116
+ id: node.id,
117
+ name: node.name,
118
+ boundVariables: await normalizeBoundVariables(node),
119
+ children: await normalizeNodes(node.children),
120
+ fills: normalizePaints(node.fills),
121
+ };
122
+ }
103
123
  async function normalizeTextNode(node: TextNode): Promise<NormalizedTextNode> {
104
124
  const segments = node.getStyledTextSegments([
105
125
  "fontSize",
@@ -173,7 +193,7 @@ export function createPluginNormalizer() {
173
193
  boundVariables: await normalizeBoundVariables(node),
174
194
  ...normalizeRadiusProps(node),
175
195
  ...normalizeAutolayoutProps(node),
176
- children: await Promise.all(node.children.map(normalizeNode)),
196
+ children: await normalizeNodes(node.children),
177
197
  };
178
198
  }
179
199
 
@@ -203,7 +223,7 @@ export function createPluginNormalizer() {
203
223
  boundVariables: await normalizeBoundVariables(node),
204
224
  ...normalizeRadiusProps(node),
205
225
  ...normalizeAutolayoutProps(node),
206
- children: await Promise.all(node.children.map(normalizeNode)),
226
+ children: await normalizeNodes(node.children),
207
227
  componentKey: mainComponent.key,
208
228
  componentSetKey:
209
229
  mainComponent.parent?.type === "COMPONENT_SET" ? mainComponent.parent.key : undefined,
@@ -8,6 +8,7 @@ import type {
8
8
  NormalizedInstanceNode,
9
9
  NormalizedTextSegment,
10
10
  NormalizedVectorNode,
11
+ NormalizedBooleanOperationNode,
11
12
  } from "./types";
12
13
 
13
14
  export interface RestNormalizerContext {
@@ -17,6 +18,11 @@ export interface RestNormalizerContext {
17
18
  }
18
19
 
19
20
  export function createRestNormalizer(ctx: RestNormalizerContext) {
21
+ function normalizeNodes(nodes: readonly FigmaRestSpec.Node[]): NormalizedSceneNode[] {
22
+ // Figma REST API omits default values for some fields, "visible" is one of them
23
+ return nodes.filter((node) => !("visible" in node) || node.visible).map(normalizeNode);
24
+ }
25
+
20
26
  function normalizeNode(node: FigmaRestSpec.Node): NormalizedSceneNode {
21
27
  if (node.type === "FRAME") {
22
28
  return normalizeFrameNode(node);
@@ -30,6 +36,9 @@ export function createRestNormalizer(ctx: RestNormalizerContext) {
30
36
  if (node.type === "VECTOR") {
31
37
  return normalizeVectorNode(node);
32
38
  }
39
+ if (node.type === "BOOLEAN_OPERATION") {
40
+ return normalizeBooleanOperationNode(node);
41
+ }
33
42
  if (node.type === "TEXT") {
34
43
  return normalizeTextNode(node);
35
44
  }
@@ -46,7 +55,7 @@ export function createRestNormalizer(ctx: RestNormalizerContext) {
46
55
  function normalizeFrameNode(node: FigmaRestSpec.FrameNode): NormalizedFrameNode {
47
56
  return {
48
57
  ...node,
49
- children: node.children.map(normalizeNode),
58
+ children: normalizeNodes(node.children),
50
59
  };
51
60
  }
52
61
 
@@ -54,7 +63,7 @@ export function createRestNormalizer(ctx: RestNormalizerContext) {
54
63
  return {
55
64
  ...node,
56
65
  type: "FRAME",
57
- children: node.children.map(normalizeNode),
66
+ children: normalizeNodes(node.children),
58
67
  };
59
68
  }
60
69
 
@@ -66,6 +75,15 @@ export function createRestNormalizer(ctx: RestNormalizerContext) {
66
75
  return node;
67
76
  }
68
77
 
78
+ function normalizeBooleanOperationNode(
79
+ node: FigmaRestSpec.BooleanOperationNode,
80
+ ): NormalizedBooleanOperationNode {
81
+ return {
82
+ ...node,
83
+ children: normalizeNodes(node.children),
84
+ };
85
+ }
86
+
69
87
  function normalizeTextNode(node: FigmaRestSpec.TextNode): NormalizedTextNode {
70
88
  // Function to segment a text node based on style overrides
71
89
  function segmentTextNode(textNode: FigmaRestSpec.TextNode): NormalizedTextSegment[] {
@@ -141,7 +159,7 @@ export function createRestNormalizer(ctx: RestNormalizerContext) {
141
159
  function normalizeComponentNode(node: FigmaRestSpec.ComponentNode): NormalizedComponentNode {
142
160
  return {
143
161
  ...node,
144
- children: node.children.map(normalizeNode),
162
+ children: normalizeNodes(node.children),
145
163
  };
146
164
  }
147
165
 
@@ -167,7 +185,7 @@ export function createRestNormalizer(ctx: RestNormalizerContext) {
167
185
 
168
186
  return {
169
187
  ...node,
170
- children: node.children.map(normalizeNode),
188
+ children: normalizeNodes(node.children),
171
189
  componentKey: mainComponent.key,
172
190
  componentSetKey: componentSet?.key,
173
191
  componentProperties,
@@ -0,0 +1,3 @@
1
+ export * from "./types";
2
+ export { createRestNormalizer } from "./from-rest";
3
+ export { createPluginNormalizer } from "./from-plugin";
@@ -82,7 +82,9 @@ export interface NormalizedVectorNode
82
82
  extends Pick<FigmaRestSpec.VectorNode, CommonProps | ShapeProps> {}
83
83
 
84
84
  export interface NormalizedBooleanOperationNode
85
- extends Pick<FigmaRestSpec.BooleanOperationNode, CommonProps | "fills"> {}
85
+ extends Pick<FigmaRestSpec.BooleanOperationNode, CommonProps | "fills"> {
86
+ children: NormalizedSceneNode[];
87
+ }
86
88
 
87
89
  export type NormalizedSceneNode =
88
90
  | NormalizedFrameNode
@@ -1,4 +1,4 @@
1
- import type { NormalizedFrameNode, NormalizedTextNode } from "./normalizer/types";
1
+ import type { NormalizedFrameNode, NormalizedTextNode } from "../normalizer";
2
2
  import { getColorVariableName } from "./variable";
3
3
 
4
4
  export function createBackgroundProps(