@seed-design/figma 0.0.24 → 0.0.25
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.
- package/lib/codegen/index.cjs +32 -9
- package/lib/codegen/index.d.ts +19 -7
- package/lib/codegen/index.js +32 -9
- package/lib/codegen/targets/react/index.cjs +224 -116
- package/lib/codegen/targets/react/index.d.ts +9 -3
- package/lib/codegen/targets/react/index.js +224 -116
- package/package.json +2 -2
- package/src/codegen/core/codegen.ts +6 -3
- package/src/codegen/core/jsx.ts +38 -7
- package/src/codegen/targets/figma/shape.ts +3 -1
- package/src/codegen/targets/figma/text.ts +4 -7
- package/src/codegen/targets/react/component/handlers/action-button.ts +8 -5
- package/src/codegen/targets/react/component/handlers/action-chip.ts +9 -8
- package/src/codegen/targets/react/component/handlers/action-sheet.ts +17 -15
- package/src/codegen/targets/react/component/handlers/app-bar.ts +31 -24
- package/src/codegen/targets/react/component/handlers/avatar-stack.ts +6 -5
- package/src/codegen/targets/react/component/handlers/avatar.ts +12 -7
- package/src/codegen/targets/react/component/handlers/badge.ts +4 -3
- package/src/codegen/targets/react/component/handlers/callout.ts +9 -4
- package/src/codegen/targets/react/component/handlers/checkbox.ts +6 -3
- package/src/codegen/targets/react/component/handlers/chip-tabs.ts +8 -5
- package/src/codegen/targets/react/component/handlers/control-chip.ts +14 -8
- package/src/codegen/targets/react/component/handlers/error-state.ts +6 -3
- package/src/codegen/targets/react/component/handlers/extended-action-sheet.ts +22 -20
- package/src/codegen/targets/react/component/handlers/extended-fab.ts +5 -4
- package/src/codegen/targets/react/component/handlers/fab.ts +9 -5
- package/src/codegen/targets/react/component/handlers/help-bubble.ts +9 -5
- package/src/codegen/targets/react/component/handlers/identity-placeholder.ts +4 -4
- package/src/codegen/targets/react/component/handlers/inline-banner.ts +8 -3
- package/src/codegen/targets/react/component/handlers/manner-temp-badge.ts +6 -3
- package/src/codegen/targets/react/component/handlers/multiline-text-field.ts +7 -4
- package/src/codegen/targets/react/component/handlers/progress-circle.ts +6 -3
- package/src/codegen/targets/react/component/handlers/reaction-button.ts +7 -4
- package/src/codegen/targets/react/component/handlers/segmented-control.ts +15 -11
- package/src/codegen/targets/react/component/handlers/select-box.ts +17 -21
- package/src/codegen/targets/react/component/handlers/skeleton.ts +5 -4
- package/src/codegen/targets/react/component/handlers/snackbar.ts +6 -3
- package/src/codegen/targets/react/component/handlers/switch.ts +6 -3
- package/src/codegen/targets/react/component/handlers/tabs.ts +13 -10
- package/src/codegen/targets/react/component/handlers/text-button.ts +3 -2
- package/src/codegen/targets/react/component/handlers/text-field.ts +7 -4
- package/src/codegen/targets/react/component/handlers/toggle-button.ts +8 -5
- package/src/codegen/targets/react/element-factories.ts +59 -0
- package/src/codegen/targets/react/frame.ts +5 -9
- package/src/codegen/targets/react/icon.ts +7 -2
- package/src/codegen/targets/react/instance.ts +2 -2
- package/src/codegen/targets/react/shape.ts +11 -4
- package/src/codegen/targets/react/text.ts +6 -8
package/lib/codegen/index.cjs
CHANGED
|
@@ -40,13 +40,13 @@ function objectEntries(obj) {
|
|
|
40
40
|
return Object.entries(obj);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
function createElement(tag, props = {}, children,
|
|
43
|
+
function createElement(tag, props = {}, children, meta) {
|
|
44
44
|
return {
|
|
45
45
|
__IS_JSX_ELEMENT_NODE: true,
|
|
46
46
|
tag,
|
|
47
47
|
props,
|
|
48
48
|
children: ensureArray(children).filter(exists),
|
|
49
|
-
|
|
49
|
+
meta: meta ?? {}
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
function cloneElement(element, props = {}, children) {
|
|
@@ -69,14 +69,25 @@ function isElement(node) {
|
|
|
69
69
|
return typeof node === "object" && node != null && "__IS_JSX_ELEMENT_NODE" in node && node.__IS_JSX_ELEMENT_NODE === true;
|
|
70
70
|
}
|
|
71
71
|
function stringifyElement(element, options = {}) {
|
|
72
|
+
const importMap = new Map();
|
|
72
73
|
function recursive(node, depth) {
|
|
73
74
|
if (typeof node === "string") {
|
|
74
75
|
return node;
|
|
75
76
|
}
|
|
76
|
-
const { tag, props, children, comment } = node;
|
|
77
|
+
const { tag, props, children, meta: { comment, source, importPath } } = node;
|
|
78
|
+
if (importPath) {
|
|
79
|
+
const existing = importMap.get(importPath);
|
|
80
|
+
if (existing) {
|
|
81
|
+
existing.add(tag);
|
|
82
|
+
} else {
|
|
83
|
+
importMap.set(importPath, new Set([
|
|
84
|
+
tag
|
|
85
|
+
]));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
77
88
|
const propEntries = Object.entries(options.printSource ? {
|
|
78
89
|
...props,
|
|
79
|
-
"data-figma-node-id":
|
|
90
|
+
"data-figma-node-id": source
|
|
80
91
|
} : props);
|
|
81
92
|
const propFragments = propEntries.map(([key, value])=>{
|
|
82
93
|
if (typeof value === "string") {
|
|
@@ -113,7 +124,12 @@ function stringifyElement(element, options = {}) {
|
|
|
113
124
|
].join("\n");
|
|
114
125
|
return result;
|
|
115
126
|
}
|
|
116
|
-
|
|
127
|
+
const jsx = recursive(element, 0);
|
|
128
|
+
const imports = Array.from(importMap.entries()).sort((a, b)=>a[0].localeCompare(b[0])).map(([importPath, tags])=>`import { ${Array.from(tags).join(", ")} } from "${importPath}";`).join("\n");
|
|
129
|
+
return {
|
|
130
|
+
imports,
|
|
131
|
+
jsx
|
|
132
|
+
};
|
|
117
133
|
}
|
|
118
134
|
|
|
119
135
|
// --- Helper Functions ---
|
|
@@ -456,9 +472,12 @@ function createCodeGenerator({ frameTransformer, textTransformer, rectangleTrans
|
|
|
456
472
|
}
|
|
457
473
|
function generateCode(node, options) {
|
|
458
474
|
const jsxTree = generateJsxTree(node);
|
|
459
|
-
|
|
475
|
+
if (!jsxTree) {
|
|
476
|
+
return undefined;
|
|
477
|
+
}
|
|
478
|
+
return stringifyElement(jsxTree, {
|
|
460
479
|
printSource: options.shouldPrintSource
|
|
461
|
-
})
|
|
480
|
+
});
|
|
462
481
|
}
|
|
463
482
|
return {
|
|
464
483
|
generateJsxTree,
|
|
@@ -7879,7 +7898,9 @@ function createVectorTransformer({ propsConverters }) {
|
|
|
7879
7898
|
...propsConverters.radius(node),
|
|
7880
7899
|
...propsConverters.stroke(node),
|
|
7881
7900
|
...propsConverters.shapeFill(node)
|
|
7882
|
-
}, [],
|
|
7901
|
+
}, [], {
|
|
7902
|
+
comment: "Vector Node Placeholder"
|
|
7903
|
+
});
|
|
7883
7904
|
});
|
|
7884
7905
|
}
|
|
7885
7906
|
function createBooleanOperationTransformer({ propsConverters }) {
|
|
@@ -7902,7 +7923,9 @@ function createTextTransformer({ propsConverters }) {
|
|
|
7902
7923
|
...typeStyleProps,
|
|
7903
7924
|
...fillProps
|
|
7904
7925
|
});
|
|
7905
|
-
return createElement("Text", props, node.characters,
|
|
7926
|
+
return createElement("Text", props, node.characters, {
|
|
7927
|
+
comment: hasMultipleFills ? "Multiple fills in Text node encountered, only the first fill is used." : undefined
|
|
7928
|
+
});
|
|
7906
7929
|
});
|
|
7907
7930
|
}
|
|
7908
7931
|
|
package/lib/codegen/index.d.ts
CHANGED
|
@@ -77,10 +77,13 @@ interface ElementNode {
|
|
|
77
77
|
tag: string;
|
|
78
78
|
props: Record<string, string | number | boolean | ElementNode | object | undefined>;
|
|
79
79
|
children: (ElementNode | string)[];
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
meta: {
|
|
81
|
+
comment?: string;
|
|
82
|
+
source?: string;
|
|
83
|
+
importPath?: string;
|
|
84
|
+
};
|
|
82
85
|
}
|
|
83
|
-
declare function createElement(tag: string, props?: Record<string, string | number | boolean | object | undefined>, children?: ElementNode | string | undefined | (ElementNode | string | undefined)[],
|
|
86
|
+
declare function createElement(tag: string, props?: Record<string, string | number | boolean | object | undefined>, children?: ElementNode | string | undefined | (ElementNode | string | undefined)[], meta?: ElementNode["meta"]): ElementNode;
|
|
84
87
|
declare function cloneElement(element: ElementNode, props?: Record<string, string | number | boolean | object | undefined>, children?: ElementNode | string | undefined | (ElementNode | string | undefined)[]): {
|
|
85
88
|
props: {
|
|
86
89
|
[x: string]: string | number | boolean | object | ElementNode | undefined;
|
|
@@ -88,8 +91,11 @@ declare function cloneElement(element: ElementNode, props?: Record<string, strin
|
|
|
88
91
|
children: (string | ElementNode)[];
|
|
89
92
|
__IS_JSX_ELEMENT_NODE: true;
|
|
90
93
|
tag: string;
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
meta: {
|
|
95
|
+
comment?: string;
|
|
96
|
+
source?: string;
|
|
97
|
+
importPath?: string;
|
|
98
|
+
};
|
|
93
99
|
};
|
|
94
100
|
|
|
95
101
|
type ElementTransformer<T extends NormalizedSceneNode> = (node: T, traverse: (node: NormalizedSceneNode) => ElementNode | undefined) => ElementNode | undefined;
|
|
@@ -108,7 +114,10 @@ declare function createCodeGenerator({ frameTransformer, textTransformer, rectan
|
|
|
108
114
|
generateJsxTree: (node: NormalizedSceneNode) => ElementNode | undefined;
|
|
109
115
|
generateCode: (node: NormalizedSceneNode, options: {
|
|
110
116
|
shouldPrintSource: boolean;
|
|
111
|
-
}) =>
|
|
117
|
+
}) => {
|
|
118
|
+
imports: string;
|
|
119
|
+
jsx: string;
|
|
120
|
+
} | undefined;
|
|
112
121
|
};
|
|
113
122
|
|
|
114
123
|
interface ComponentHandler<T extends NormalizedInstanceNode["componentProperties"] = NormalizedInstanceNode["componentProperties"]> {
|
|
@@ -1680,7 +1689,10 @@ declare function createPipeline(options?: CreatePipelineConfig): {
|
|
|
1680
1689
|
generateJsxTree: (node: ________.NormalizedSceneNode) => ElementNode | undefined;
|
|
1681
1690
|
generateCode: (node: ________.NormalizedSceneNode, options: {
|
|
1682
1691
|
shouldPrintSource: boolean;
|
|
1683
|
-
}) =>
|
|
1692
|
+
}) => {
|
|
1693
|
+
imports: string;
|
|
1694
|
+
jsx: string;
|
|
1695
|
+
} | undefined;
|
|
1684
1696
|
};
|
|
1685
1697
|
|
|
1686
1698
|
type FigmaValueResolver = ValueResolver<string, number, number, number>;
|
package/lib/codegen/index.js
CHANGED
|
@@ -21,13 +21,13 @@ function objectEntries(obj) {
|
|
|
21
21
|
return Object.entries(obj);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
function createElement(tag, props = {}, children,
|
|
24
|
+
function createElement(tag, props = {}, children, meta) {
|
|
25
25
|
return {
|
|
26
26
|
__IS_JSX_ELEMENT_NODE: true,
|
|
27
27
|
tag,
|
|
28
28
|
props,
|
|
29
29
|
children: ensureArray(children).filter(exists),
|
|
30
|
-
|
|
30
|
+
meta: meta ?? {}
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
function cloneElement(element, props = {}, children) {
|
|
@@ -50,14 +50,25 @@ function isElement(node) {
|
|
|
50
50
|
return typeof node === "object" && node != null && "__IS_JSX_ELEMENT_NODE" in node && node.__IS_JSX_ELEMENT_NODE === true;
|
|
51
51
|
}
|
|
52
52
|
function stringifyElement(element, options = {}) {
|
|
53
|
+
const importMap = new Map();
|
|
53
54
|
function recursive(node, depth) {
|
|
54
55
|
if (typeof node === "string") {
|
|
55
56
|
return node;
|
|
56
57
|
}
|
|
57
|
-
const { tag, props, children, comment } = node;
|
|
58
|
+
const { tag, props, children, meta: { comment, source, importPath } } = node;
|
|
59
|
+
if (importPath) {
|
|
60
|
+
const existing = importMap.get(importPath);
|
|
61
|
+
if (existing) {
|
|
62
|
+
existing.add(tag);
|
|
63
|
+
} else {
|
|
64
|
+
importMap.set(importPath, new Set([
|
|
65
|
+
tag
|
|
66
|
+
]));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
58
69
|
const propEntries = Object.entries(options.printSource ? {
|
|
59
70
|
...props,
|
|
60
|
-
"data-figma-node-id":
|
|
71
|
+
"data-figma-node-id": source
|
|
61
72
|
} : props);
|
|
62
73
|
const propFragments = propEntries.map(([key, value])=>{
|
|
63
74
|
if (typeof value === "string") {
|
|
@@ -94,7 +105,12 @@ function stringifyElement(element, options = {}) {
|
|
|
94
105
|
].join("\n");
|
|
95
106
|
return result;
|
|
96
107
|
}
|
|
97
|
-
|
|
108
|
+
const jsx = recursive(element, 0);
|
|
109
|
+
const imports = Array.from(importMap.entries()).sort((a, b)=>a[0].localeCompare(b[0])).map(([importPath, tags])=>`import { ${Array.from(tags).join(", ")} } from "${importPath}";`).join("\n");
|
|
110
|
+
return {
|
|
111
|
+
imports,
|
|
112
|
+
jsx
|
|
113
|
+
};
|
|
98
114
|
}
|
|
99
115
|
|
|
100
116
|
// --- Helper Functions ---
|
|
@@ -437,9 +453,12 @@ function createCodeGenerator({ frameTransformer, textTransformer, rectangleTrans
|
|
|
437
453
|
}
|
|
438
454
|
function generateCode(node, options) {
|
|
439
455
|
const jsxTree = generateJsxTree(node);
|
|
440
|
-
|
|
456
|
+
if (!jsxTree) {
|
|
457
|
+
return undefined;
|
|
458
|
+
}
|
|
459
|
+
return stringifyElement(jsxTree, {
|
|
441
460
|
printSource: options.shouldPrintSource
|
|
442
|
-
})
|
|
461
|
+
});
|
|
443
462
|
}
|
|
444
463
|
return {
|
|
445
464
|
generateJsxTree,
|
|
@@ -7860,7 +7879,9 @@ function createVectorTransformer({ propsConverters }) {
|
|
|
7860
7879
|
...propsConverters.radius(node),
|
|
7861
7880
|
...propsConverters.stroke(node),
|
|
7862
7881
|
...propsConverters.shapeFill(node)
|
|
7863
|
-
}, [],
|
|
7882
|
+
}, [], {
|
|
7883
|
+
comment: "Vector Node Placeholder"
|
|
7884
|
+
});
|
|
7864
7885
|
});
|
|
7865
7886
|
}
|
|
7866
7887
|
function createBooleanOperationTransformer({ propsConverters }) {
|
|
@@ -7883,7 +7904,9 @@ function createTextTransformer({ propsConverters }) {
|
|
|
7883
7904
|
...typeStyleProps,
|
|
7884
7905
|
...fillProps
|
|
7885
7906
|
});
|
|
7886
|
-
return createElement("Text", props, node.characters,
|
|
7907
|
+
return createElement("Text", props, node.characters, {
|
|
7908
|
+
comment: hasMultipleFills ? "Multiple fills in Text node encountered, only the first fill is used." : undefined
|
|
7909
|
+
});
|
|
7887
7910
|
});
|
|
7888
7911
|
}
|
|
7889
7912
|
|