@seed-design/figma 0.0.21 → 0.0.23
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 +8012 -0
- package/lib/codegen/index.d.ts +1828 -0
- package/lib/codegen/index.js +7983 -0
- package/lib/codegen/targets/react/index.cjs +12198 -0
- package/lib/codegen/targets/react/index.d.ts +267 -0
- package/lib/codegen/targets/react/index.js +12180 -0
- package/lib/index.cjs +79 -2741
- package/lib/index.d.ts +17 -1937
- package/lib/index.js +61 -2715
- package/package.json +12 -2
- package/src/codegen/{targets/react/component/properties.type.ts → component-properties.ts} +43 -43
- package/src/codegen/core/codegen.ts +17 -6
- package/src/codegen/core/{component.ts → component-handler.ts} +3 -3
- package/src/codegen/core/component-type-helper.ts +35 -0
- package/src/codegen/core/index.ts +14 -14
- package/src/codegen/core/{props.ts → props-converter.ts} +10 -13
- package/src/codegen/core/{value.ts → value-resolver.ts} +87 -50
- package/src/codegen/default-services.ts +44 -0
- package/src/codegen/index.ts +1 -44
- package/src/codegen/targets/figma/frame.ts +8 -8
- package/src/codegen/targets/figma/index.ts +1 -1
- package/src/codegen/targets/figma/pipeline.ts +94 -0
- package/src/codegen/targets/figma/props.ts +59 -70
- package/src/codegen/targets/figma/shape.ts +18 -18
- package/src/codegen/targets/figma/text.ts +6 -6
- package/src/codegen/targets/figma/value-resolver.ts +19 -0
- package/src/codegen/targets/react/component/deps.interface.ts +5 -4
- package/src/codegen/targets/react/component/{transformers → handlers}/action-button.ts +8 -14
- package/src/codegen/targets/react/component/{transformers → handlers}/action-chip.ts +10 -20
- package/src/codegen/targets/react/component/{transformers → handlers}/action-sheet.ts +13 -10
- package/src/codegen/targets/react/component/{transformers → handlers}/app-bar.ts +28 -36
- package/src/codegen/targets/react/component/handlers/avatar-stack.ts +29 -0
- package/src/codegen/targets/react/component/{transformers → handlers}/avatar.ts +12 -9
- package/src/codegen/targets/react/component/handlers/badge.ts +18 -0
- package/src/codegen/targets/react/component/{transformers → handlers}/callout.ts +6 -8
- package/src/codegen/targets/react/component/{transformers → handlers}/checkbox.ts +5 -5
- package/src/codegen/targets/react/component/{transformers → handlers}/chip-tabs.ts +10 -10
- package/src/codegen/targets/react/component/{transformers → handlers}/control-chip.ts +10 -20
- package/src/codegen/targets/react/component/{transformers → handlers}/error-state.ts +9 -9
- package/src/codegen/targets/react/component/{transformers → handlers}/extended-action-sheet.ts +16 -18
- package/src/codegen/targets/react/component/{transformers → handlers}/extended-fab.ts +6 -6
- package/src/codegen/targets/react/component/handlers/fab.ts +18 -0
- package/src/codegen/targets/react/component/{transformers → handlers}/help-bubble.ts +5 -5
- package/src/codegen/targets/react/component/{transformers → handlers}/identity-placeholder.ts +5 -5
- package/src/codegen/targets/react/component/{transformers → handlers}/inline-banner.ts +7 -10
- package/src/codegen/targets/react/component/{transformers → handlers}/manner-temp-badge.ts +5 -5
- package/src/codegen/targets/react/component/{transformers → handlers}/multiline-text-field.ts +5 -5
- package/src/codegen/targets/react/component/{transformers → handlers}/progress-circle.ts +5 -5
- package/src/codegen/targets/react/component/{transformers → handlers}/reaction-button.ts +6 -6
- package/src/codegen/targets/react/component/{transformers → handlers}/segmented-control.ts +10 -10
- package/src/codegen/targets/react/component/{transformers → handlers}/select-box.ts +10 -10
- package/src/codegen/targets/react/component/handlers/skeleton.ts +25 -0
- package/src/codegen/targets/react/component/{transformers → handlers}/snackbar.ts +5 -5
- package/src/codegen/targets/react/component/{transformers → handlers}/switch.ts +5 -5
- package/src/codegen/targets/react/component/{transformers → handlers}/tabs.ts +15 -15
- package/src/codegen/targets/react/component/{transformers → handlers}/text-button.ts +7 -13
- package/src/codegen/targets/react/component/{transformers → handlers}/text-field.ts +9 -9
- package/src/codegen/targets/react/component/{transformers → handlers}/toggle-button.ts +7 -11
- package/src/codegen/targets/react/component/index.ts +79 -75
- package/src/codegen/targets/react/frame.ts +8 -8
- package/src/codegen/targets/react/icon.ts +50 -0
- package/src/codegen/targets/react/index.ts +1 -1
- package/src/codegen/targets/react/instance.ts +19 -50
- package/src/codegen/targets/react/pipeline.ts +124 -0
- package/src/codegen/targets/react/props.ts +95 -73
- package/src/codegen/targets/react/shape.ts +5 -5
- package/src/codegen/targets/react/text.ts +6 -6
- package/src/codegen/targets/react/value-resolver.ts +32 -0
- package/src/entities/icon.repository.ts +2 -2
- package/src/entities/icon.service.ts +9 -20
- package/src/entities/style.service.ts +5 -17
- package/src/entities/variable.service.ts +36 -68
- package/src/utils/figma-variable.ts +39 -3
- package/src/codegen/core/component.types.ts +0 -29
- package/src/codegen/targets/figma/context.ts +0 -139
- package/src/codegen/targets/react/component/transformers/avatar-stack.ts +0 -29
- package/src/codegen/targets/react/component/transformers/badge.ts +0 -21
- package/src/codegen/targets/react/component/transformers/fab.ts +0 -18
- package/src/codegen/targets/react/component/transformers/skeleton.ts +0 -51
- package/src/codegen/targets/react/context.ts +0 -176
- /package/src/codegen/core/{element.ts → element-transformer.ts} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StyleService, VariableValueResolved } from "@/entities";
|
|
1
2
|
import type {
|
|
2
3
|
NormalizedCornerTrait,
|
|
3
4
|
NormalizedHasFramePropertiesTrait,
|
|
@@ -15,7 +16,7 @@ import {
|
|
|
15
16
|
import type { RGBA } from "@figma/rest-api-spec";
|
|
16
17
|
import type { VariableService } from "../../entities/variable.service";
|
|
17
18
|
|
|
18
|
-
export interface
|
|
19
|
+
export interface ValueResolver<TColor, TDimension, TFontDimension, TFontWeight> {
|
|
19
20
|
getFormattedValue: {
|
|
20
21
|
frameFill: (
|
|
21
22
|
node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,
|
|
@@ -84,11 +85,17 @@ export interface ValueTransformer<TColor, TDimension, TFontDimension, TFontWeigh
|
|
|
84
85
|
node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,
|
|
85
86
|
) => string | TFontDimension | undefined;
|
|
86
87
|
};
|
|
88
|
+
getTextStyleValue: (
|
|
89
|
+
node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,
|
|
90
|
+
) => string | undefined; // TODO: we might turn this into a generic; not sure yet
|
|
87
91
|
}
|
|
88
92
|
|
|
89
|
-
export interface
|
|
93
|
+
export interface ValueResolverDeps<TColor, TDimension, TFontDimension, TFontWeight> {
|
|
90
94
|
variableService: VariableService;
|
|
91
|
-
|
|
95
|
+
variableNameFormatter: (props: { slug: string[] }) => string;
|
|
96
|
+
styleService: StyleService;
|
|
97
|
+
styleNameFormatter: (props: { slug: string[] }) => string;
|
|
98
|
+
rawValueFormatters: {
|
|
92
99
|
color: (value: RGBA) => string | TColor;
|
|
93
100
|
dimension: (value: number) => string | TDimension;
|
|
94
101
|
fontDimension: (value: number) => string | TFontDimension;
|
|
@@ -97,31 +104,64 @@ export interface ValueTransformerDeps<TColor, TDimension, TFontDimension, TFontW
|
|
|
97
104
|
shouldInferVariableName: boolean;
|
|
98
105
|
}
|
|
99
106
|
|
|
100
|
-
export function
|
|
107
|
+
export function createValueResolver<TColor, TDimension, TFontDimension, TFontWeight>({
|
|
101
108
|
variableService,
|
|
102
|
-
|
|
109
|
+
variableNameFormatter,
|
|
110
|
+
styleService,
|
|
111
|
+
styleNameFormatter,
|
|
112
|
+
rawValueFormatters,
|
|
103
113
|
shouldInferVariableName,
|
|
104
|
-
}:
|
|
114
|
+
}: ValueResolverDeps<TColor, TDimension, TFontDimension, TFontWeight>): ValueResolver<
|
|
105
115
|
TColor,
|
|
106
116
|
TDimension,
|
|
107
117
|
TFontDimension,
|
|
108
118
|
TFontWeight
|
|
109
119
|
> {
|
|
120
|
+
function getVariableName(key: string) {
|
|
121
|
+
const slug = variableService.getSlug(key);
|
|
122
|
+
|
|
123
|
+
if (!slug) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return variableNameFormatter({ slug });
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function inferVariableName(value: VariableValueResolved, scope: VariableScope) {
|
|
131
|
+
if (!shouldInferVariableName) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const inferred = variableService.infer(value, scope);
|
|
136
|
+
|
|
137
|
+
if (!inferred) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return getVariableName(inferred.key);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function getStyleName(key: string) {
|
|
145
|
+
const slug = styleService.getSlug(key);
|
|
146
|
+
|
|
147
|
+
if (!slug) {
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return styleNameFormatter({ slug });
|
|
152
|
+
}
|
|
153
|
+
|
|
110
154
|
function processColor(
|
|
111
155
|
key: string | undefined,
|
|
112
156
|
value: RGBA | undefined,
|
|
113
157
|
scope: "FRAME_FILL" | "SHAPE_FILL" | "STROKE_COLOR" | "TEXT_FILL",
|
|
114
158
|
) {
|
|
115
159
|
if (key) {
|
|
116
|
-
return
|
|
160
|
+
return getVariableName(key);
|
|
117
161
|
}
|
|
118
162
|
|
|
119
|
-
if (value) {
|
|
120
|
-
|
|
121
|
-
return variableService.inferVariableName(value, scope) ?? formatters.color(value);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return formatters.color(value);
|
|
163
|
+
if (value !== undefined) {
|
|
164
|
+
return inferVariableName(value, scope) ?? rawValueFormatters.color(value);
|
|
125
165
|
}
|
|
126
166
|
|
|
127
167
|
return undefined;
|
|
@@ -133,15 +173,11 @@ export function createValueTransformer<TColor, TDimension, TFontDimension, TFont
|
|
|
133
173
|
scope: "WIDTH_HEIGHT" | "GAP" | "CORNER_RADIUS",
|
|
134
174
|
) {
|
|
135
175
|
if (key) {
|
|
136
|
-
return
|
|
176
|
+
return getVariableName(key);
|
|
137
177
|
}
|
|
138
178
|
|
|
139
|
-
if (value) {
|
|
140
|
-
|
|
141
|
-
return variableService.inferVariableName(value, scope) ?? formatters.dimension(value);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return formatters.dimension(value);
|
|
179
|
+
if (value !== undefined) {
|
|
180
|
+
return inferVariableName(value, scope) ?? rawValueFormatters.dimension(value);
|
|
145
181
|
}
|
|
146
182
|
|
|
147
183
|
return undefined;
|
|
@@ -153,15 +189,11 @@ export function createValueTransformer<TColor, TDimension, TFontDimension, TFont
|
|
|
153
189
|
scope: "FONT_SIZE" | "LINE_HEIGHT",
|
|
154
190
|
) {
|
|
155
191
|
if (key) {
|
|
156
|
-
return
|
|
192
|
+
return getVariableName(key);
|
|
157
193
|
}
|
|
158
194
|
|
|
159
|
-
if (value) {
|
|
160
|
-
|
|
161
|
-
return variableService.inferVariableName(value, scope) ?? formatters.fontDimension(value);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return formatters.fontDimension(value);
|
|
195
|
+
if (value !== undefined) {
|
|
196
|
+
return inferVariableName(value, scope) ?? rawValueFormatters.fontDimension(value);
|
|
165
197
|
}
|
|
166
198
|
|
|
167
199
|
return undefined;
|
|
@@ -169,37 +201,33 @@ export function createValueTransformer<TColor, TDimension, TFontDimension, TFont
|
|
|
169
201
|
|
|
170
202
|
function processFontWeight(key: string | undefined, value: number | undefined) {
|
|
171
203
|
if (key) {
|
|
172
|
-
return
|
|
204
|
+
return getVariableName(key);
|
|
173
205
|
}
|
|
174
206
|
|
|
175
|
-
if (value) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
};
|
|
207
|
+
if (value !== undefined) {
|
|
208
|
+
const fontWeightToString: Record<number, string> = {
|
|
209
|
+
100: "thin",
|
|
210
|
+
200: "extra-light",
|
|
211
|
+
300: "light",
|
|
212
|
+
400: "regular",
|
|
213
|
+
500: "medium",
|
|
214
|
+
600: "semi-bold",
|
|
215
|
+
700: "bold",
|
|
216
|
+
800: "extra-bold",
|
|
217
|
+
900: "black",
|
|
218
|
+
};
|
|
188
219
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return formatters.fontWeight(value);
|
|
220
|
+
return (
|
|
221
|
+
inferVariableName(value, "FONT_WEIGHT") ??
|
|
222
|
+
inferVariableName(fontWeightToString[value], "FONT_STYLE") ??
|
|
223
|
+
rawValueFormatters.fontWeight(value)
|
|
224
|
+
);
|
|
197
225
|
}
|
|
198
226
|
|
|
199
227
|
return undefined;
|
|
200
228
|
}
|
|
201
229
|
|
|
202
|
-
const getFormattedValue:
|
|
230
|
+
const getFormattedValue: ValueResolver<
|
|
203
231
|
TColor,
|
|
204
232
|
TDimension,
|
|
205
233
|
TFontDimension,
|
|
@@ -283,7 +311,16 @@ export function createValueTransformer<TColor, TDimension, TFontDimension, TFont
|
|
|
283
311
|
),
|
|
284
312
|
};
|
|
285
313
|
|
|
314
|
+
function getTextStyleValue(node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait) {
|
|
315
|
+
if (node.textStyleKey) {
|
|
316
|
+
return getStyleName(node.textStyleKey);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
321
|
+
|
|
286
322
|
return {
|
|
287
323
|
getFormattedValue,
|
|
324
|
+
getTextStyleValue,
|
|
288
325
|
};
|
|
289
326
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createIconService,
|
|
3
|
+
createStyleService,
|
|
4
|
+
createVariableService,
|
|
5
|
+
iconRepository,
|
|
6
|
+
styleRepository,
|
|
7
|
+
variableRepository,
|
|
8
|
+
} from "@/entities";
|
|
9
|
+
|
|
10
|
+
export const styleService = createStyleService({
|
|
11
|
+
styleRepository,
|
|
12
|
+
});
|
|
13
|
+
export const variableService = createVariableService({
|
|
14
|
+
variableRepository,
|
|
15
|
+
inferCompareFunction: (a, b) => {
|
|
16
|
+
const scoreFn = (name: string) => {
|
|
17
|
+
let score = 0;
|
|
18
|
+
if (name.includes("bg")) {
|
|
19
|
+
score += 100;
|
|
20
|
+
}
|
|
21
|
+
if (name.includes("fg")) {
|
|
22
|
+
score += 100;
|
|
23
|
+
}
|
|
24
|
+
if (name.includes("stroke")) {
|
|
25
|
+
score += 100;
|
|
26
|
+
}
|
|
27
|
+
if (name.includes("spacing-x")) {
|
|
28
|
+
score -= 100;
|
|
29
|
+
}
|
|
30
|
+
if (name.includes("spacing-y")) {
|
|
31
|
+
score -= 100;
|
|
32
|
+
}
|
|
33
|
+
if (name.endsWith("pressed")) {
|
|
34
|
+
score -= 100;
|
|
35
|
+
}
|
|
36
|
+
return score;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return scoreFn(b.name) - scoreFn(a.name);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
export const iconService = createIconService({
|
|
43
|
+
iconRepository,
|
|
44
|
+
});
|
package/src/codegen/index.ts
CHANGED
|
@@ -1,46 +1,3 @@
|
|
|
1
|
+
export * from "./component-properties";
|
|
1
2
|
export * from "./core";
|
|
2
3
|
export * from "./targets";
|
|
3
|
-
|
|
4
|
-
import type { NormalizedSceneNode } from "@/normalizer";
|
|
5
|
-
import { stringifyElement } from "./core/jsx";
|
|
6
|
-
import { figma, react } from "./targets";
|
|
7
|
-
|
|
8
|
-
export function generateJsxTree(
|
|
9
|
-
node: NormalizedSceneNode,
|
|
10
|
-
options: Partial<react.CreateContextOptions> = {},
|
|
11
|
-
) {
|
|
12
|
-
const { shouldInferVariableName = true, shouldInferAutoLayout = true } = options;
|
|
13
|
-
const codegen = react.createContext({
|
|
14
|
-
shouldInferVariableName,
|
|
15
|
-
shouldInferAutoLayout,
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
return codegen(node);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function generateCode(
|
|
22
|
-
node: NormalizedSceneNode,
|
|
23
|
-
options: Partial<react.CreateContextOptions> & { shouldPrintSource?: boolean } = {},
|
|
24
|
-
) {
|
|
25
|
-
const result = generateJsxTree(node, options);
|
|
26
|
-
return result ? stringifyElement(result, { printSource: options.shouldPrintSource }) : undefined;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function generateFigmaSummary(
|
|
30
|
-
node: NormalizedSceneNode,
|
|
31
|
-
options: Partial<figma.CreateContextOptions> & { shouldPrintSource?: boolean } = {},
|
|
32
|
-
) {
|
|
33
|
-
const {
|
|
34
|
-
shouldInferVariableName = false,
|
|
35
|
-
shouldPrintSource = false,
|
|
36
|
-
shouldInferAutoLayout = false,
|
|
37
|
-
} = options;
|
|
38
|
-
const codegen = figma.createContext({
|
|
39
|
-
shouldInferVariableName,
|
|
40
|
-
shouldInferAutoLayout,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const result = codegen(node);
|
|
44
|
-
|
|
45
|
-
return result ? stringifyElement(result, { printSource: shouldPrintSource }) : undefined;
|
|
46
|
-
}
|
|
@@ -4,14 +4,14 @@ import type {
|
|
|
4
4
|
NormalizedInstanceNode,
|
|
5
5
|
} from "@/normalizer";
|
|
6
6
|
import { createElement, defineElementTransformer, type ElementTransformer } from "../../core";
|
|
7
|
-
import type {
|
|
7
|
+
import type { PropsConverters } from "./props";
|
|
8
8
|
|
|
9
9
|
export interface FrameTransformerDeps {
|
|
10
|
-
|
|
10
|
+
propsConverters: PropsConverters;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function createFrameTransformer({
|
|
14
|
-
|
|
14
|
+
propsConverters,
|
|
15
15
|
}: FrameTransformerDeps): ElementTransformer<
|
|
16
16
|
NormalizedFrameNode | NormalizedInstanceNode | NormalizedComponentNode
|
|
17
17
|
> {
|
|
@@ -20,11 +20,11 @@ export function createFrameTransformer({
|
|
|
20
20
|
const children = node.children;
|
|
21
21
|
|
|
22
22
|
const props = {
|
|
23
|
-
...
|
|
24
|
-
...
|
|
25
|
-
...
|
|
26
|
-
...
|
|
27
|
-
...
|
|
23
|
+
...propsConverters.radius(node),
|
|
24
|
+
...propsConverters.containerLayout(node),
|
|
25
|
+
...propsConverters.selfLayout(node),
|
|
26
|
+
...propsConverters.frameFill(node),
|
|
27
|
+
...propsConverters.stroke(node),
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
return createElement(
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createCodeGenerator, createValueResolver } from "@/codegen/core";
|
|
2
|
+
import { styleService, variableService } from "@/codegen/default-services";
|
|
3
|
+
import { createFrameTransformer } from "./frame";
|
|
4
|
+
import { createInstanceTransformer } from "./instance";
|
|
5
|
+
import {
|
|
6
|
+
createContainerLayoutPropsConverter,
|
|
7
|
+
createFrameFillPropsConverter,
|
|
8
|
+
createRadiusPropsConverter,
|
|
9
|
+
createSelfLayoutPropsConverter,
|
|
10
|
+
createShapeFillPropsConverter,
|
|
11
|
+
createStrokePropsConverter,
|
|
12
|
+
createTextFillPropsConverter,
|
|
13
|
+
createTypeStylePropsConverter,
|
|
14
|
+
} from "./props";
|
|
15
|
+
import {
|
|
16
|
+
createBooleanOperationTransformer,
|
|
17
|
+
createRectangleTransformer,
|
|
18
|
+
createVectorTransformer,
|
|
19
|
+
} from "./shape";
|
|
20
|
+
import { createTextTransformer } from "./text";
|
|
21
|
+
import {
|
|
22
|
+
defaultRawValueFormatters,
|
|
23
|
+
defaultStyleNameFormatter,
|
|
24
|
+
defaultVariableNameFormatter,
|
|
25
|
+
} from "./value-resolver";
|
|
26
|
+
|
|
27
|
+
export interface CreatePipelineConfig {
|
|
28
|
+
shouldInferAutoLayout?: boolean;
|
|
29
|
+
shouldInferVariableName?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function createPipeline(options: CreatePipelineConfig = {}) {
|
|
33
|
+
const { shouldInferAutoLayout = true, shouldInferVariableName = true } = options;
|
|
34
|
+
|
|
35
|
+
const valueResolver = createValueResolver({
|
|
36
|
+
variableService,
|
|
37
|
+
variableNameFormatter: defaultVariableNameFormatter,
|
|
38
|
+
styleService,
|
|
39
|
+
styleNameFormatter: defaultStyleNameFormatter,
|
|
40
|
+
rawValueFormatters: defaultRawValueFormatters,
|
|
41
|
+
shouldInferVariableName,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const containerLayoutPropsConverter = createContainerLayoutPropsConverter(valueResolver);
|
|
45
|
+
const selfLayoutPropsConverter = createSelfLayoutPropsConverter(valueResolver);
|
|
46
|
+
const frameFillPropsConverter = createFrameFillPropsConverter(valueResolver);
|
|
47
|
+
const shapeFillPropsConverter = createShapeFillPropsConverter(valueResolver);
|
|
48
|
+
const textFillPropsConverter = createTextFillPropsConverter(valueResolver);
|
|
49
|
+
const radiusPropsConverter = createRadiusPropsConverter(valueResolver);
|
|
50
|
+
const strokePropsConverter = createStrokePropsConverter(valueResolver);
|
|
51
|
+
const typeStylePropsConverter = createTypeStylePropsConverter(valueResolver);
|
|
52
|
+
|
|
53
|
+
const propsConverters = {
|
|
54
|
+
containerLayout: containerLayoutPropsConverter,
|
|
55
|
+
selfLayout: selfLayoutPropsConverter,
|
|
56
|
+
frameFill: frameFillPropsConverter,
|
|
57
|
+
shapeFill: shapeFillPropsConverter,
|
|
58
|
+
textFill: textFillPropsConverter,
|
|
59
|
+
radius: radiusPropsConverter,
|
|
60
|
+
stroke: strokePropsConverter,
|
|
61
|
+
typeStyle: typeStylePropsConverter,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const frameTransformer = createFrameTransformer({
|
|
65
|
+
propsConverters,
|
|
66
|
+
});
|
|
67
|
+
const instanceTransformer = createInstanceTransformer({
|
|
68
|
+
frameTransformer,
|
|
69
|
+
});
|
|
70
|
+
const textTransformer = createTextTransformer({
|
|
71
|
+
propsConverters,
|
|
72
|
+
});
|
|
73
|
+
const rectangleTransformer = createRectangleTransformer({
|
|
74
|
+
propsConverters,
|
|
75
|
+
});
|
|
76
|
+
const vectorTransformer = createVectorTransformer({
|
|
77
|
+
propsConverters,
|
|
78
|
+
});
|
|
79
|
+
const booleanOperationTransformer = createBooleanOperationTransformer({
|
|
80
|
+
propsConverters,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const codegenTransformer = createCodeGenerator({
|
|
84
|
+
frameTransformer,
|
|
85
|
+
textTransformer,
|
|
86
|
+
rectangleTransformer,
|
|
87
|
+
instanceTransformer,
|
|
88
|
+
vectorTransformer,
|
|
89
|
+
booleanOperationTransformer,
|
|
90
|
+
shouldInferAutoLayout,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return codegenTransformer;
|
|
94
|
+
}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createPropsTransformer,
|
|
3
|
-
definePropsTransformer,
|
|
4
|
-
type PropsTransformer,
|
|
5
|
-
type ValueTransformer,
|
|
6
|
-
} from "@/codegen/core";
|
|
7
|
-
import type { StyleService } from "@/entities";
|
|
1
|
+
import { createPropsConverter, definePropsConverter, type PropsConverter } from "@/codegen/core";
|
|
8
2
|
import type {
|
|
9
3
|
NormalizedCornerTrait,
|
|
10
4
|
NormalizedHasChildrenTrait,
|
|
@@ -14,16 +8,17 @@ import type {
|
|
|
14
8
|
NormalizedIsLayerTrait,
|
|
15
9
|
NormalizedTypePropertiesTrait,
|
|
16
10
|
} from "@/normalizer";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
import type { FigmaValueResolver } from "./value-resolver";
|
|
12
|
+
|
|
13
|
+
export interface PropsConverters {
|
|
14
|
+
containerLayout: PropsConverter<ContainerLayoutTrait, ContainerLayoutProps>;
|
|
15
|
+
selfLayout: PropsConverter<SelfLayoutTrait, SelfLayoutProps>;
|
|
16
|
+
radius: PropsConverter<RadiusTrait, RadiusProps>;
|
|
17
|
+
frameFill: PropsConverter<FillTrait, FillProps>;
|
|
18
|
+
shapeFill: PropsConverter<FillTrait, FillProps>;
|
|
19
|
+
textFill: PropsConverter<FillTrait, FillProps>;
|
|
20
|
+
stroke: PropsConverter<StrokeTrait, StrokeProps>;
|
|
21
|
+
typeStyle: PropsConverter<TypeStyleTrait, TypeStyleProps>;
|
|
27
22
|
}
|
|
28
23
|
|
|
29
24
|
export type ContainerLayoutTrait = NormalizedHasFramePropertiesTrait &
|
|
@@ -55,12 +50,10 @@ export interface ContainerLayoutProps {
|
|
|
55
50
|
verticalPadding?: number | string; // string when variable
|
|
56
51
|
}
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
): PropsTransformer<ContainerLayoutTrait, ContainerLayoutProps> {
|
|
63
|
-
return createPropsTransformer({
|
|
53
|
+
export function createContainerLayoutPropsConverter(
|
|
54
|
+
valueResolver: FigmaValueResolver,
|
|
55
|
+
): PropsConverter<ContainerLayoutTrait, ContainerLayoutProps> {
|
|
56
|
+
return createPropsConverter({
|
|
64
57
|
_types: {
|
|
65
58
|
trait: {} as ContainerLayoutTrait,
|
|
66
59
|
props: {} as ContainerLayoutProps,
|
|
@@ -70,11 +63,11 @@ export function createContainerLayoutPropsTransformer(
|
|
|
70
63
|
primaryAxisAlignItems: ({ primaryAxisAlignItems }) => primaryAxisAlignItems,
|
|
71
64
|
counterAxisAlignItems: ({ counterAxisAlignItems }) => counterAxisAlignItems,
|
|
72
65
|
layoutWrap: ({ layoutWrap }) => layoutWrap,
|
|
73
|
-
itemSpacing: (
|
|
74
|
-
paddingTop: (node) =>
|
|
75
|
-
paddingBottom: (node) =>
|
|
76
|
-
paddingLeft: (node) =>
|
|
77
|
-
paddingRight: (node) =>
|
|
66
|
+
itemSpacing: (node) => valueResolver.getFormattedValue.itemSpacing(node),
|
|
67
|
+
paddingTop: (node) => valueResolver.getFormattedValue.paddingTop(node),
|
|
68
|
+
paddingBottom: (node) => valueResolver.getFormattedValue.paddingBottom(node),
|
|
69
|
+
paddingLeft: (node) => valueResolver.getFormattedValue.paddingLeft(node),
|
|
70
|
+
paddingRight: (node) => valueResolver.getFormattedValue.paddingRight(node),
|
|
78
71
|
},
|
|
79
72
|
shorthands: {
|
|
80
73
|
horizontalPadding: ["paddingLeft", "paddingRight"],
|
|
@@ -97,10 +90,10 @@ export interface SelfLayoutProps {
|
|
|
97
90
|
maxHeight?: string | number; // string when variable
|
|
98
91
|
}
|
|
99
92
|
|
|
100
|
-
export function
|
|
101
|
-
|
|
102
|
-
):
|
|
103
|
-
return
|
|
93
|
+
export function createSelfLayoutPropsConverter(
|
|
94
|
+
valueResolver: FigmaValueResolver,
|
|
95
|
+
): PropsConverter<SelfLayoutTrait, SelfLayoutProps> {
|
|
96
|
+
return createPropsConverter({
|
|
104
97
|
_types: {
|
|
105
98
|
trait: {} as SelfLayoutTrait,
|
|
106
99
|
props: {} as SelfLayoutProps,
|
|
@@ -110,12 +103,12 @@ export function createSelfLayoutPropsTransformer(
|
|
|
110
103
|
layoutAlign: ({ layoutAlign }) => layoutAlign,
|
|
111
104
|
layoutSizingVertical: ({ layoutSizingVertical }) => layoutSizingVertical,
|
|
112
105
|
layoutSizingHorizontal: ({ layoutSizingHorizontal }) => layoutSizingHorizontal,
|
|
113
|
-
width: (node) =>
|
|
114
|
-
height: (node) =>
|
|
115
|
-
minWidth: (node) =>
|
|
116
|
-
minHeight: (node) =>
|
|
117
|
-
maxWidth: (node) =>
|
|
118
|
-
maxHeight: (node) =>
|
|
106
|
+
width: (node) => valueResolver.getFormattedValue.width(node),
|
|
107
|
+
height: (node) => valueResolver.getFormattedValue.height(node),
|
|
108
|
+
minWidth: (node) => valueResolver.getFormattedValue.minWidth(node),
|
|
109
|
+
minHeight: (node) => valueResolver.getFormattedValue.minHeight(node),
|
|
110
|
+
maxWidth: (node) => valueResolver.getFormattedValue.maxWidth(node),
|
|
111
|
+
maxHeight: (node) => valueResolver.getFormattedValue.maxHeight(node),
|
|
119
112
|
},
|
|
120
113
|
defaults: {},
|
|
121
114
|
});
|
|
@@ -129,17 +122,17 @@ export interface RadiusProps {
|
|
|
129
122
|
bottomRightRadius?: number | string; // string when variable
|
|
130
123
|
}
|
|
131
124
|
|
|
132
|
-
export function
|
|
133
|
-
return
|
|
125
|
+
export function createRadiusPropsConverter(valueResolver: FigmaValueResolver) {
|
|
126
|
+
return createPropsConverter({
|
|
134
127
|
_types: {
|
|
135
128
|
trait: {} as RadiusTrait,
|
|
136
129
|
props: {} as RadiusProps,
|
|
137
130
|
},
|
|
138
131
|
handlers: {
|
|
139
|
-
topLeftRadius: (node) =>
|
|
140
|
-
topRightRadius: (node) =>
|
|
141
|
-
bottomLeftRadius: (node) =>
|
|
142
|
-
bottomRightRadius: (node) =>
|
|
132
|
+
topLeftRadius: (node) => valueResolver.getFormattedValue.topLeftRadius(node),
|
|
133
|
+
topRightRadius: (node) => valueResolver.getFormattedValue.topRightRadius(node),
|
|
134
|
+
bottomLeftRadius: (node) => valueResolver.getFormattedValue.bottomLeftRadius(node),
|
|
135
|
+
bottomRightRadius: (node) => valueResolver.getFormattedValue.bottomRightRadius(node),
|
|
143
136
|
},
|
|
144
137
|
shorthands: {
|
|
145
138
|
cornerRadius: ["topLeftRadius", "topRightRadius", "bottomLeftRadius", "bottomRightRadius"],
|
|
@@ -158,9 +151,9 @@ export interface FillProps {
|
|
|
158
151
|
fill?: string;
|
|
159
152
|
}
|
|
160
153
|
|
|
161
|
-
export function
|
|
162
|
-
return
|
|
163
|
-
const fill =
|
|
154
|
+
export function createFrameFillPropsConverter(valueResolver: FigmaValueResolver) {
|
|
155
|
+
return definePropsConverter<FillTrait, FillProps>((node: FillTrait) => {
|
|
156
|
+
const fill = valueResolver.getFormattedValue.frameFill(node);
|
|
164
157
|
|
|
165
158
|
return {
|
|
166
159
|
fill,
|
|
@@ -168,9 +161,9 @@ export function createFrameFillPropsTransformer(valueTransformer: FigmaValueTran
|
|
|
168
161
|
});
|
|
169
162
|
}
|
|
170
163
|
|
|
171
|
-
export function
|
|
172
|
-
return
|
|
173
|
-
const fill =
|
|
164
|
+
export function createShapeFillPropsConverter(valueResolver: FigmaValueResolver) {
|
|
165
|
+
return definePropsConverter<FillTrait, FillProps>((node: FillTrait) => {
|
|
166
|
+
const fill = valueResolver.getFormattedValue.shapeFill(node);
|
|
174
167
|
|
|
175
168
|
return {
|
|
176
169
|
fill,
|
|
@@ -178,9 +171,9 @@ export function createShapeFillPropsTransformer(valueTransformer: FigmaValueTran
|
|
|
178
171
|
});
|
|
179
172
|
}
|
|
180
173
|
|
|
181
|
-
export function
|
|
182
|
-
return
|
|
183
|
-
const fill =
|
|
174
|
+
export function createTextFillPropsConverter(valueResolver: FigmaValueResolver) {
|
|
175
|
+
return definePropsConverter<FillTrait, FillProps>((node: FillTrait) => {
|
|
176
|
+
const fill = valueResolver.getFormattedValue.textFill(node);
|
|
184
177
|
|
|
185
178
|
return {
|
|
186
179
|
fill,
|
|
@@ -193,11 +186,11 @@ export interface StrokeProps {
|
|
|
193
186
|
strokeWeight?: number;
|
|
194
187
|
}
|
|
195
188
|
|
|
196
|
-
export function
|
|
197
|
-
|
|
198
|
-
):
|
|
199
|
-
return
|
|
200
|
-
const stroke =
|
|
189
|
+
export function createStrokePropsConverter(
|
|
190
|
+
valueResolver: FigmaValueResolver,
|
|
191
|
+
): PropsConverter<StrokeTrait, StrokeProps> {
|
|
192
|
+
return definePropsConverter((node: StrokeTrait) => {
|
|
193
|
+
const stroke = valueResolver.getFormattedValue.stroke(node);
|
|
201
194
|
const strokeWeight = node.strokeWeight;
|
|
202
195
|
|
|
203
196
|
return {
|
|
@@ -215,15 +208,11 @@ export interface TypeStyleProps {
|
|
|
215
208
|
maxLines?: number;
|
|
216
209
|
}
|
|
217
210
|
|
|
218
|
-
export function
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
styleService: StyleService;
|
|
224
|
-
}): PropsTransformer<TypeStyleTrait, TypeStyleProps> {
|
|
225
|
-
return definePropsTransformer((node) => {
|
|
226
|
-
const styleName = node.textStyleKey ? styleService.getStyleName(node.textStyleKey) : undefined;
|
|
211
|
+
export function createTypeStylePropsConverter(
|
|
212
|
+
valueResolver: FigmaValueResolver,
|
|
213
|
+
): PropsConverter<TypeStyleTrait, TypeStyleProps> {
|
|
214
|
+
return definePropsConverter((node) => {
|
|
215
|
+
const styleName = valueResolver.getTextStyleValue(node);
|
|
227
216
|
const maxLines =
|
|
228
217
|
node.style.textTruncation === "ENDING" ? (node.style.maxLines ?? undefined) : undefined;
|
|
229
218
|
|
|
@@ -235,9 +224,9 @@ export function createTypeStylePropsTransformer({
|
|
|
235
224
|
}
|
|
236
225
|
|
|
237
226
|
return {
|
|
238
|
-
fontSize:
|
|
239
|
-
fontWeight:
|
|
240
|
-
lineHeight:
|
|
227
|
+
fontSize: valueResolver.getFormattedValue.fontSize(node),
|
|
228
|
+
fontWeight: valueResolver.getFormattedValue.fontWeight(node),
|
|
229
|
+
lineHeight: valueResolver.getFormattedValue.lineHeight(node),
|
|
241
230
|
maxLines,
|
|
242
231
|
};
|
|
243
232
|
});
|