@seed-design/figma 1.3.8 → 1.3.9

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.
@@ -11,6 +11,7 @@ import type {
11
11
  NormalizedTextNode,
12
12
  NormalizedComponentNode,
13
13
  NormalizedInstanceNode,
14
+ NormalizedSlotNode,
14
15
  NormalizedVectorNode,
15
16
  NormalizedBooleanOperationNode,
16
17
  NormalizedHasEffectsTrait,
@@ -41,6 +42,8 @@ export function createPluginNormalizer(): (node: SceneNode) => Promise<Normalize
41
42
  return normalizeComponentNode(node);
42
43
  case "INSTANCE":
43
44
  return normalizeInstanceNode(node);
45
+ case "SLOT":
46
+ return normalizeSlotNode(node);
44
47
  case "VECTOR":
45
48
  return normalizeVectorNode(node);
46
49
  case "BOOLEAN_OPERATION":
@@ -148,7 +151,7 @@ export function createPluginNormalizer(): (node: SceneNode) => Promise<Normalize
148
151
  return [];
149
152
  }
150
153
 
151
- return fills.map(normalizePaint);
154
+ return fills.filter((paint) => paint.visible !== false).map(normalizePaint);
152
155
  }
153
156
 
154
157
  function normalizeRadiusProps(
@@ -289,6 +292,36 @@ export function createPluginNormalizer(): (node: SceneNode) => Promise<Normalize
289
292
  };
290
293
  }
291
294
 
295
+ async function normalizeSlotNode(node: SlotNode): Promise<NormalizedSlotNode> {
296
+ return {
297
+ // NormalizedIsLayerTrait
298
+ type: node.type,
299
+ id: node.id,
300
+ name: node.name,
301
+ boundVariables: normalizeBoundVariables(node),
302
+
303
+ // NormalizedHasLayoutTrait, NormalizedHasGeometryTrait, NormalizedHasEffectsTrait
304
+ ...(await normalizeShapeProps(node)),
305
+
306
+ // NormalizedCornerTrait
307
+ ...normalizeRadiusProps(node),
308
+
309
+ // NormalizedHasFramePropertiesTrait
310
+ ...(await normalizeAutolayoutProps(node)),
311
+
312
+ // NormalizedHasChildrenTrait
313
+ children: await normalizeNodes(node.children),
314
+
315
+ // NormalizedSlotNode specific
316
+ // Plugin API types don't include "slotContentId" in componentPropertyReferences yet
317
+ ...((node.componentPropertyReferences as Record<string, string> | null)?.[
318
+ "slotContentId"
319
+ ] && {
320
+ componentPropertyReferences: node.componentPropertyReferences as Record<string, string>,
321
+ }),
322
+ };
323
+ }
324
+
292
325
  async function normalizeRectangleNode(node: RectangleNode): Promise<NormalizedRectangleNode> {
293
326
  return {
294
327
  // NormalizedIsLayerTrait
@@ -18,6 +18,7 @@ import type {
18
18
  NormalizedComponentNode,
19
19
  NormalizedInstanceNode,
20
20
  NormalizedTextSegment,
21
+ NormalizedSlotNode,
21
22
  NormalizedVectorNode,
22
23
  NormalizedBooleanOperationNode,
23
24
  NormalizedShadow,
@@ -64,6 +65,8 @@ export function createRestNormalizer(
64
65
  return normalizeComponentNode(node);
65
66
  case "INSTANCE":
66
67
  return normalizeInstanceNode(node);
68
+ case "SLOT":
69
+ return normalizeSlotNode(node);
67
70
  case "VECTOR":
68
71
  return normalizeVectorNode(node);
69
72
  case "BOOLEAN_OPERATION":
@@ -125,7 +128,9 @@ export function createRestNormalizer(
125
128
  function normalizePaints(paints: FigmaRestSpec.Paint[] | undefined): NormalizedPaint[] {
126
129
  if (!paints) return [];
127
130
 
128
- return paints.map(normalizePaint);
131
+ return paints
132
+ .filter((paint) => !("visible" in paint) || paint.visible !== false)
133
+ .map(normalizePaint);
129
134
  }
130
135
 
131
136
  function normalizeRadiusProps({
@@ -268,6 +273,33 @@ export function createRestNormalizer(
268
273
  };
269
274
  }
270
275
 
276
+ function normalizeSlotNode(node: FigmaRestSpec.SlotNode): NormalizedSlotNode {
277
+ return {
278
+ // NormalizedIsLayerTrait
279
+ type: node.type,
280
+ id: node.id,
281
+ name: node.name,
282
+ boundVariables: normalizeBoundVariables(node.boundVariables),
283
+
284
+ // NormalizedHasLayoutTrait, NormalizedHasGeometryTrait, NormalizedHasEffectsTrait, NormalizedHasFramePropertiesTrait
285
+ ...normalizeShapeProps(node),
286
+
287
+ // NormalizedCornerTrait
288
+ ...normalizeRadiusProps(node),
289
+
290
+ // NormalizedHasFramePropertiesTrait
291
+ ...normalizeAutolayoutProps(node),
292
+
293
+ // NormalizedHasChildrenTrait
294
+ children: normalizeNodes(node.children),
295
+
296
+ // NormalizedSlotNode specific
297
+ ...(node.componentPropertyReferences?.["slotContentId"] && {
298
+ componentPropertyReferences: node.componentPropertyReferences,
299
+ }),
300
+ };
301
+ }
302
+
271
303
  function normalizeRectangleNode(node: FigmaRestSpec.RectangleNode): NormalizedRectangleNode {
272
304
  return {
273
305
  // NormalizedIsLayerTrait
@@ -178,6 +178,13 @@ export interface NormalizedInstanceNode extends NormalizedFrameTrait {
178
178
  children: NormalizedSceneNode[];
179
179
  }
180
180
 
181
+ export interface NormalizedSlotNode extends NormalizedFrameTrait {
182
+ type: FigmaRestSpec.SlotNode["type"];
183
+ componentPropertyReferences?: FigmaRestSpec.IsLayerTrait["componentPropertyReferences"] & {
184
+ slotContentId?: string;
185
+ };
186
+ }
187
+
181
188
  export interface NormalizedVectorNode extends NormalizedDefaultShapeTrait, NormalizedCornerTrait {
182
189
  type: FigmaRestSpec.VectorNode["type"];
183
190
  }
@@ -203,6 +210,7 @@ export type NormalizedSceneNode =
203
210
  | NormalizedTextNode
204
211
  | NormalizedComponentNode
205
212
  | NormalizedInstanceNode
213
+ | NormalizedSlotNode
206
214
  | NormalizedVectorNode
207
215
  | NormalizedBooleanOperationNode
208
216
  | NormalizedUnhandledNode;
@@ -2,6 +2,7 @@ import type {
2
2
  NormalizedHasGeometryTrait,
3
3
  NormalizedInstanceNode,
4
4
  NormalizedSceneNode,
5
+ NormalizedSlotNode,
5
6
  NormalizedSolidPaint,
6
7
  } from "../normalizer";
7
8
 
@@ -55,11 +56,19 @@ export function findAllInstances<T>({ node, key }: { node: NormalizedSceneNode;
55
56
  ) as (Omit<NormalizedInstanceNode, "componentProperties"> & { componentProperties: T })[];
56
57
  }
57
58
 
59
+ export function findSlotNode<T extends NormalizedInstanceNode["componentProperties"]>(
60
+ node: Omit<NormalizedInstanceNode, "componentProperties"> & { componentProperties: T },
61
+ slotPropertyKey: { [K in keyof T]: T[K] extends { type: "SLOT" } ? K : never }[keyof T] & string,
62
+ ): NormalizedSlotNode | undefined {
63
+ return findOne(
64
+ node,
65
+ (child) =>
66
+ child.type === "SLOT" && child.componentPropertyReferences?.slotContentId === slotPropertyKey,
67
+ ) as NormalizedSlotNode | undefined;
68
+ }
69
+
58
70
  export function getFirstSolidFill(node: NormalizedHasGeometryTrait) {
59
- const fills = node.fills.filter(
60
- (fill): fill is NormalizedSolidPaint =>
61
- fill.type === "SOLID" && (!("visible" in fill) || fill.visible === true),
62
- );
71
+ const fills = node.fills.filter((fill): fill is NormalizedSolidPaint => fill.type === "SOLID");
63
72
 
64
73
  if (fills.length === 0) {
65
74
  return undefined;
@@ -76,10 +85,7 @@ export function getFirstFillVariable(node: NormalizedHasGeometryTrait) {
76
85
 
77
86
  export function getFirstStroke(node: NormalizedHasGeometryTrait) {
78
87
  const strokes =
79
- node.strokes?.filter(
80
- (stroke): stroke is NormalizedSolidPaint =>
81
- stroke.type === "SOLID" && (!("visible" in stroke) || stroke.visible === true),
82
- ) ?? [];
88
+ node.strokes?.filter((stroke): stroke is NormalizedSolidPaint => stroke.type === "SOLID") ?? [];
83
89
 
84
90
  if (strokes.length === 0) {
85
91
  return undefined;