@seed-design/figma 0.0.20 → 0.0.22
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 +8019 -0
- package/lib/codegen/index.d.ts +1827 -0
- package/lib/codegen/index.js +7989 -0
- package/lib/codegen/targets/react/index.cjs +12205 -0
- package/lib/codegen/targets/react/index.d.ts +270 -0
- package/lib/codegen/targets/react/index.js +12187 -0
- package/lib/index.cjs +86 -2741
- package/lib/index.d.ts +18 -1933
- package/lib/index.js +68 -2715
- package/package.json +18 -9
- package/src/codegen/{targets/react/component/properties.type.ts → component-properties.ts} +43 -43
- package/src/codegen/core/codegen.ts +24 -9
- 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/context.ts +20 -0
- package/src/codegen/core/index.ts +16 -14
- package/src/codegen/core/infer-layout.test.ts +17 -16
- package/src/codegen/core/infer-layout.ts +1 -1
- package/src/codegen/core/{props.ts → props-converter.ts} +10 -13
- package/src/codegen/core/{value.ts → value-resolver.ts} +90 -52
- 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 +71 -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 +22 -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 +108 -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 +35 -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/normalizer/from-plugin.ts +3 -0
- package/src/normalizer/from-rest.ts +6 -0
- package/src/normalizer/types.ts +4 -1
- 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
|
@@ -9,14 +9,14 @@ import {
|
|
|
9
9
|
defineElementTransformer,
|
|
10
10
|
type ElementTransformer,
|
|
11
11
|
} from "../../core";
|
|
12
|
-
import type { ContainerLayoutProps,
|
|
12
|
+
import type { ContainerLayoutProps, PropsConverters } from "./props";
|
|
13
13
|
|
|
14
14
|
export interface FrameTransformerDeps {
|
|
15
|
-
|
|
15
|
+
propsConverters: PropsConverters;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export function createFrameTransformer({
|
|
19
|
-
|
|
19
|
+
propsConverters,
|
|
20
20
|
}: FrameTransformerDeps): ElementTransformer<
|
|
21
21
|
NormalizedFrameNode | NormalizedInstanceNode | NormalizedComponentNode
|
|
22
22
|
> {
|
|
@@ -39,11 +39,11 @@ export function createFrameTransformer({
|
|
|
39
39
|
const isFlex = node.layoutMode === "HORIZONTAL" || node.layoutMode === "VERTICAL";
|
|
40
40
|
|
|
41
41
|
const props = {
|
|
42
|
-
...
|
|
43
|
-
...(isFlex ?
|
|
44
|
-
...
|
|
45
|
-
...
|
|
46
|
-
...
|
|
42
|
+
...propsConverters.radius(node),
|
|
43
|
+
...(isFlex ? propsConverters.containerLayout(node) : {}),
|
|
44
|
+
...propsConverters.selfLayout(node),
|
|
45
|
+
...propsConverters.frameFill(node),
|
|
46
|
+
...propsConverters.stroke(node),
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
const isStretch = props.align === undefined || props.align === "stretch";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { IconService } from "@/entities";
|
|
2
|
+
import { pascalCase } from "change-case";
|
|
3
|
+
import { type ElementNode, createElement } from "../../core";
|
|
4
|
+
|
|
5
|
+
export interface IconHandler {
|
|
6
|
+
isIconInstance: (node: { componentKey: string }) => boolean;
|
|
7
|
+
transform: (node: { componentKey: string }) => ElementNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface IconHandlerDeps {
|
|
11
|
+
iconService: IconService;
|
|
12
|
+
iconNameFormatter?: (props: { name: string; weight?: string }) => string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const defaultIconNameFormatter = ({ name, weight }: { name: string; weight?: string }) =>
|
|
16
|
+
pascalCase(`${name}${weight ? weight : ""}`);
|
|
17
|
+
|
|
18
|
+
export function createIconHandler({
|
|
19
|
+
iconService,
|
|
20
|
+
iconNameFormatter = defaultIconNameFormatter,
|
|
21
|
+
}: IconHandlerDeps): IconHandler {
|
|
22
|
+
function isIconInstance(node: { componentKey: string }): boolean {
|
|
23
|
+
const key = node.componentKey;
|
|
24
|
+
|
|
25
|
+
if (!key) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return iconService.isAvailable(key);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function transform(node: { componentKey: string }): ElementNode {
|
|
33
|
+
const key = node.componentKey;
|
|
34
|
+
const iconData = iconService.getOne(key);
|
|
35
|
+
if (!iconData) {
|
|
36
|
+
return createElement("UnknownIcon");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const { name, weight } = iconData;
|
|
40
|
+
|
|
41
|
+
const tagName = iconNameFormatter({ name, weight });
|
|
42
|
+
|
|
43
|
+
return createElement(tagName);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
isIconInstance,
|
|
48
|
+
transform,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -1,74 +1,43 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { NormalizedFrameTrait, NormalizedInstanceNode } from "@/normalizer";
|
|
1
|
+
import type { NormalizedInstanceNode } from "@/normalizer";
|
|
3
2
|
import {
|
|
4
3
|
createElement,
|
|
5
4
|
defineElementTransformer,
|
|
6
|
-
|
|
7
|
-
type ComponentTransformer,
|
|
5
|
+
type ComponentHandler,
|
|
8
6
|
type ElementTransformer,
|
|
9
7
|
} from "../../core";
|
|
10
|
-
import type {
|
|
8
|
+
import type { IconHandler } from "./icon";
|
|
9
|
+
import type { PropsConverters } from "./props";
|
|
11
10
|
|
|
12
11
|
export interface InstanceTransformerDeps {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
componentTransformers: Record<string, ComponentTransformer>;
|
|
12
|
+
iconHandler?: IconHandler;
|
|
13
|
+
propsConverters: PropsConverters;
|
|
14
|
+
componentHandlers: Record<string, ComponentHandler>;
|
|
17
15
|
frameTransformer: ElementTransformer<NormalizedInstanceNode>;
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
export function createInstanceTransformer({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
componentTransformers,
|
|
19
|
+
iconHandler,
|
|
20
|
+
propsConverters,
|
|
21
|
+
componentHandlers,
|
|
25
22
|
frameTransformer,
|
|
26
23
|
}: InstanceTransformerDeps): ElementTransformer<NormalizedInstanceNode> {
|
|
27
|
-
const transformIconColorProps = definePropsTransformer((node: NormalizedFrameTrait, traverse) => {
|
|
28
|
-
if (node.children.length === 0) {
|
|
29
|
-
throw new Error("Node has no children");
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const vectors = node.children.filter(
|
|
33
|
-
(child) => child.type === "VECTOR" || child.type === "BOOLEAN_OPERATION",
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const colorProps = vectors.map((vector) => propsTransformers.shapeFill(vector, traverse));
|
|
37
|
-
|
|
38
|
-
const fills = new Set(
|
|
39
|
-
colorProps.map((props) => props.color).filter((color) => color !== undefined),
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
// If there are more than 1 color, colors are likely pre-defined in the icon component; we should ignore the color prop.
|
|
43
|
-
if (fills.size > 1) {
|
|
44
|
-
return {};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return { color: fills.values().next().value };
|
|
48
|
-
});
|
|
49
|
-
|
|
50
24
|
const transform = defineElementTransformer((node: NormalizedInstanceNode, traverse) => {
|
|
51
25
|
const { componentKey, componentSetKey } = node;
|
|
52
26
|
|
|
53
|
-
if (
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (iconService?.isIconComponent(componentKey)) {
|
|
58
|
-
const tagName = iconService.createIconTagName(componentKey);
|
|
27
|
+
if (iconHandler?.isIconInstance(node)) {
|
|
59
28
|
const props = {
|
|
60
|
-
...
|
|
61
|
-
...
|
|
29
|
+
...propsConverters.iconSelfLayout(node),
|
|
30
|
+
...propsConverters.vectorChildrenFill(node),
|
|
62
31
|
};
|
|
63
|
-
return createElement("Icon", { svg:
|
|
32
|
+
return createElement("Icon", { svg: iconHandler.transform(node), ...props });
|
|
64
33
|
}
|
|
65
34
|
|
|
66
|
-
const
|
|
67
|
-
?
|
|
68
|
-
:
|
|
35
|
+
const componentHandler = componentSetKey
|
|
36
|
+
? componentHandlers[componentSetKey]
|
|
37
|
+
: componentHandlers[componentKey];
|
|
69
38
|
|
|
70
|
-
if (
|
|
71
|
-
return
|
|
39
|
+
if (componentHandler) {
|
|
40
|
+
return componentHandler.transform(node);
|
|
72
41
|
}
|
|
73
42
|
|
|
74
43
|
return frameTransformer(node, traverse);
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { createCodeGenerator } from "@/codegen/core";
|
|
2
|
+
import { iconService } from "@/codegen/default-services";
|
|
3
|
+
import {
|
|
4
|
+
type UnboundComponentHandler,
|
|
5
|
+
bindComponentHandler,
|
|
6
|
+
unboundSeedComponentHandlers,
|
|
7
|
+
} from "./component";
|
|
8
|
+
import { createFrameTransformer } from "./frame";
|
|
9
|
+
import { createIconHandler } from "./icon";
|
|
10
|
+
import { createInstanceTransformer } from "./instance";
|
|
11
|
+
import {
|
|
12
|
+
createContainerLayoutPropsConverter,
|
|
13
|
+
createFrameFillPropsConverter,
|
|
14
|
+
createIconSelfLayoutPropsConverter,
|
|
15
|
+
createRadiusPropsConverter,
|
|
16
|
+
createSelfLayoutPropsConverter,
|
|
17
|
+
createShapeFillPropsConverter,
|
|
18
|
+
createStrokePropsConverter,
|
|
19
|
+
createTextFillPropsConverter,
|
|
20
|
+
createTypeStylePropsConverter,
|
|
21
|
+
createVectorChildrenFillPropsConverter,
|
|
22
|
+
} from "./props";
|
|
23
|
+
import {
|
|
24
|
+
createBooleanOperationTransformer,
|
|
25
|
+
createRectangleTransformer,
|
|
26
|
+
createVectorTransformer,
|
|
27
|
+
} from "./shape";
|
|
28
|
+
import { createTextTransformer } from "./text";
|
|
29
|
+
import { valueResolver } from "./value-resolver";
|
|
30
|
+
|
|
31
|
+
export interface CreatePipelineConfig {
|
|
32
|
+
extend?: {
|
|
33
|
+
componentHandlers?: Array<UnboundComponentHandler<any>>;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const iconHandler = createIconHandler({
|
|
38
|
+
iconService,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export function createPipeline(options: CreatePipelineConfig = {}) {
|
|
42
|
+
const { extend = {} } = options;
|
|
43
|
+
|
|
44
|
+
const containerLayoutPropsConverter = createContainerLayoutPropsConverter(valueResolver);
|
|
45
|
+
const selfLayoutPropsConverter = createSelfLayoutPropsConverter(valueResolver);
|
|
46
|
+
const iconSelfLayoutPropsConverter = createIconSelfLayoutPropsConverter(valueResolver);
|
|
47
|
+
const frameFillPropsConverter = createFrameFillPropsConverter(valueResolver);
|
|
48
|
+
const shapeFillPropsConverter = createShapeFillPropsConverter(valueResolver);
|
|
49
|
+
const textFillPropsConverter = createTextFillPropsConverter(valueResolver);
|
|
50
|
+
const vectorChildrenFillPropsConverter = createVectorChildrenFillPropsConverter(valueResolver);
|
|
51
|
+
const radiusPropsConverter = createRadiusPropsConverter(valueResolver);
|
|
52
|
+
const strokePropsConverter = createStrokePropsConverter(valueResolver);
|
|
53
|
+
const typeStylePropsConverter = createTypeStylePropsConverter({
|
|
54
|
+
valueResolver,
|
|
55
|
+
});
|
|
56
|
+
const propsConverters = {
|
|
57
|
+
containerLayout: containerLayoutPropsConverter,
|
|
58
|
+
selfLayout: selfLayoutPropsConverter,
|
|
59
|
+
iconSelfLayout: iconSelfLayoutPropsConverter,
|
|
60
|
+
frameFill: frameFillPropsConverter,
|
|
61
|
+
shapeFill: shapeFillPropsConverter,
|
|
62
|
+
textFill: textFillPropsConverter,
|
|
63
|
+
vectorChildrenFill: vectorChildrenFillPropsConverter,
|
|
64
|
+
radius: radiusPropsConverter,
|
|
65
|
+
stroke: strokePropsConverter,
|
|
66
|
+
typeStyle: typeStylePropsConverter,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const componentHandlers = Object.fromEntries(
|
|
70
|
+
[...unboundSeedComponentHandlers, ...(extend.componentHandlers ?? [])]
|
|
71
|
+
.map((h) =>
|
|
72
|
+
bindComponentHandler(h, {
|
|
73
|
+
valueResolver,
|
|
74
|
+
iconHandler,
|
|
75
|
+
}),
|
|
76
|
+
)
|
|
77
|
+
.map((t) => [t.key, t]),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const frameTransformer = createFrameTransformer({
|
|
81
|
+
propsConverters,
|
|
82
|
+
});
|
|
83
|
+
const instanceTransformer = createInstanceTransformer({
|
|
84
|
+
iconHandler,
|
|
85
|
+
propsConverters,
|
|
86
|
+
componentHandlers,
|
|
87
|
+
frameTransformer,
|
|
88
|
+
});
|
|
89
|
+
const textTransformer = createTextTransformer({
|
|
90
|
+
propsConverters,
|
|
91
|
+
});
|
|
92
|
+
const rectangleTransformer = createRectangleTransformer({
|
|
93
|
+
propsConverters,
|
|
94
|
+
});
|
|
95
|
+
const vectorTransformer = createVectorTransformer();
|
|
96
|
+
const booleanOperationTransformer = createBooleanOperationTransformer();
|
|
97
|
+
|
|
98
|
+
const codeGenerator = createCodeGenerator({
|
|
99
|
+
frameTransformer,
|
|
100
|
+
textTransformer,
|
|
101
|
+
rectangleTransformer,
|
|
102
|
+
instanceTransformer,
|
|
103
|
+
vectorTransformer,
|
|
104
|
+
booleanOperationTransformer,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
return codeGenerator;
|
|
108
|
+
}
|
|
@@ -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,
|
|
@@ -15,17 +9,19 @@ import type {
|
|
|
15
9
|
NormalizedTypePropertiesTrait,
|
|
16
10
|
} from "@/normalizer";
|
|
17
11
|
import { match } from "ts-pattern";
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
12
|
+
import type { ReactValueResolver } from "./value-resolver";
|
|
13
|
+
|
|
14
|
+
export interface PropsConverters {
|
|
15
|
+
containerLayout: PropsConverter<ContainerLayoutTrait, ContainerLayoutProps>;
|
|
16
|
+
selfLayout: PropsConverter<SelfLayoutTrait, SelfLayoutProps>;
|
|
17
|
+
iconSelfLayout: PropsConverter<SelfLayoutTrait, IconSelfLayoutProps>;
|
|
18
|
+
radius: PropsConverter<RadiusTrait, RadiusProps>;
|
|
19
|
+
frameFill: PropsConverter<FillTrait, FrameFillProps>;
|
|
20
|
+
shapeFill: PropsConverter<FillTrait, ShapeFillProps>;
|
|
21
|
+
textFill: PropsConverter<FillTrait, TextFillProps>;
|
|
22
|
+
vectorChildrenFill: PropsConverter<ContainerLayoutTrait, VectorChildrenFillProps>;
|
|
23
|
+
stroke: PropsConverter<StrokeTrait, StrokeProps>;
|
|
24
|
+
typeStyle: PropsConverter<TypeStyleTrait, TypeStyleProps>;
|
|
29
25
|
}
|
|
30
26
|
|
|
31
27
|
export type ContainerLayoutTrait = NormalizedHasFramePropertiesTrait &
|
|
@@ -58,12 +54,10 @@ export interface ContainerLayoutProps {
|
|
|
58
54
|
p?: string | 0;
|
|
59
55
|
}
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
): PropsTransformer<ContainerLayoutTrait, ContainerLayoutProps> {
|
|
66
|
-
return createPropsTransformer({
|
|
57
|
+
export function createContainerLayoutPropsConverter(
|
|
58
|
+
valueResolver: ReactValueResolver,
|
|
59
|
+
): PropsConverter<ContainerLayoutTrait, ContainerLayoutProps> {
|
|
60
|
+
return createPropsConverter({
|
|
67
61
|
_types: {
|
|
68
62
|
trait: {} as ContainerLayoutTrait,
|
|
69
63
|
props: {} as ContainerLayoutProps,
|
|
@@ -120,12 +114,12 @@ export function createContainerLayoutPropsTransformer(
|
|
|
120
114
|
return undefined;
|
|
121
115
|
}
|
|
122
116
|
|
|
123
|
-
return
|
|
117
|
+
return valueResolver.getFormattedValue.itemSpacing(node);
|
|
124
118
|
},
|
|
125
|
-
pt: (node) =>
|
|
126
|
-
pb: (node) =>
|
|
127
|
-
pl: (node) =>
|
|
128
|
-
pr: (node) =>
|
|
119
|
+
pt: (node) => valueResolver.getFormattedValue.paddingTop(node),
|
|
120
|
+
pb: (node) => valueResolver.getFormattedValue.paddingBottom(node),
|
|
121
|
+
pl: (node) => valueResolver.getFormattedValue.paddingLeft(node),
|
|
122
|
+
pr: (node) => valueResolver.getFormattedValue.paddingRight(node),
|
|
129
123
|
},
|
|
130
124
|
shorthands: {
|
|
131
125
|
p: ["pt", "pb", "pl", "pr"],
|
|
@@ -159,10 +153,10 @@ export interface SelfLayoutProps {
|
|
|
159
153
|
maxHeight?: string | number;
|
|
160
154
|
}
|
|
161
155
|
|
|
162
|
-
export function
|
|
163
|
-
|
|
164
|
-
):
|
|
165
|
-
return
|
|
156
|
+
export function createSelfLayoutPropsConverter(
|
|
157
|
+
valueResolver: ReactValueResolver,
|
|
158
|
+
): PropsConverter<SelfLayoutTrait, SelfLayoutProps> {
|
|
159
|
+
return createPropsConverter({
|
|
166
160
|
_types: {
|
|
167
161
|
trait: {} as SelfLayoutTrait,
|
|
168
162
|
props: {} as SelfLayoutProps,
|
|
@@ -180,27 +174,27 @@ export function createSelfLayoutPropsTransformer(
|
|
|
180
174
|
.exhaustive(),
|
|
181
175
|
height: (node) =>
|
|
182
176
|
node.layoutSizingVertical === "FIXED"
|
|
183
|
-
?
|
|
177
|
+
? valueResolver.getFormattedValue.height(node)
|
|
184
178
|
: undefined,
|
|
185
179
|
width: (node) =>
|
|
186
180
|
node.layoutSizingHorizontal === "FIXED"
|
|
187
|
-
?
|
|
181
|
+
? valueResolver.getFormattedValue.width(node)
|
|
188
182
|
: undefined,
|
|
189
183
|
minHeight: (node) =>
|
|
190
184
|
node.layoutSizingVertical === "HUG"
|
|
191
|
-
?
|
|
185
|
+
? valueResolver.getFormattedValue.minHeight(node)
|
|
192
186
|
: undefined,
|
|
193
187
|
maxHeight: (node) =>
|
|
194
188
|
node.layoutSizingVertical === "HUG"
|
|
195
|
-
?
|
|
189
|
+
? valueResolver.getFormattedValue.maxHeight(node)
|
|
196
190
|
: undefined,
|
|
197
191
|
minWidth: (node) =>
|
|
198
192
|
node.layoutSizingHorizontal === "HUG"
|
|
199
|
-
?
|
|
193
|
+
? valueResolver.getFormattedValue.minWidth(node)
|
|
200
194
|
: undefined,
|
|
201
195
|
maxWidth: (node) =>
|
|
202
196
|
node.layoutSizingHorizontal === "HUG"
|
|
203
|
-
?
|
|
197
|
+
? valueResolver.getFormattedValue.maxWidth(node)
|
|
204
198
|
: undefined,
|
|
205
199
|
},
|
|
206
200
|
defaults: {
|
|
@@ -213,14 +207,14 @@ export interface IconSelfLayoutProps {
|
|
|
213
207
|
size?: string | number;
|
|
214
208
|
}
|
|
215
209
|
|
|
216
|
-
export function
|
|
217
|
-
return
|
|
210
|
+
export function createIconSelfLayoutPropsConverter(valueResolver: ReactValueResolver) {
|
|
211
|
+
return createPropsConverter({
|
|
218
212
|
_types: {
|
|
219
213
|
trait: {} as SelfLayoutTrait,
|
|
220
214
|
props: {} as IconSelfLayoutProps,
|
|
221
215
|
},
|
|
222
216
|
handlers: {
|
|
223
|
-
size: (node) =>
|
|
217
|
+
size: (node) => valueResolver.getFormattedValue.width(node),
|
|
224
218
|
},
|
|
225
219
|
});
|
|
226
220
|
}
|
|
@@ -233,17 +227,17 @@ export interface RadiusProps {
|
|
|
233
227
|
borderBottomRightRadius?: string | 0;
|
|
234
228
|
}
|
|
235
229
|
|
|
236
|
-
export function
|
|
237
|
-
return
|
|
230
|
+
export function createRadiusPropsConverter(valueResolver: ReactValueResolver) {
|
|
231
|
+
return createPropsConverter({
|
|
238
232
|
_types: {
|
|
239
233
|
trait: {} as RadiusTrait,
|
|
240
234
|
props: {} as RadiusProps,
|
|
241
235
|
},
|
|
242
236
|
handlers: {
|
|
243
|
-
borderTopLeftRadius: (node) =>
|
|
244
|
-
borderTopRightRadius: (node) =>
|
|
245
|
-
borderBottomLeftRadius: (node) =>
|
|
246
|
-
borderBottomRightRadius: (node) =>
|
|
237
|
+
borderTopLeftRadius: (node) => valueResolver.getFormattedValue.topLeftRadius(node),
|
|
238
|
+
borderTopRightRadius: (node) => valueResolver.getFormattedValue.topRightRadius(node),
|
|
239
|
+
borderBottomLeftRadius: (node) => valueResolver.getFormattedValue.bottomLeftRadius(node),
|
|
240
|
+
borderBottomRightRadius: (node) => valueResolver.getFormattedValue.bottomRightRadius(node),
|
|
247
241
|
},
|
|
248
242
|
shorthands: {
|
|
249
243
|
borderRadius: [
|
|
@@ -271,15 +265,13 @@ export interface TypeStyleProps {
|
|
|
271
265
|
maxLines?: number;
|
|
272
266
|
}
|
|
273
267
|
|
|
274
|
-
export function
|
|
275
|
-
|
|
276
|
-
styleService,
|
|
268
|
+
export function createTypeStylePropsConverter({
|
|
269
|
+
valueResolver,
|
|
277
270
|
}: {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
const styleName = node.textStyleKey ? styleService.getStyleName(node.textStyleKey) : undefined;
|
|
271
|
+
valueResolver: ReactValueResolver;
|
|
272
|
+
}): PropsConverter<TypeStyleTrait, TypeStyleProps> {
|
|
273
|
+
return definePropsConverter((node) => {
|
|
274
|
+
const styleName = valueResolver.getTextStyleValue(node);
|
|
283
275
|
const maxLines =
|
|
284
276
|
node.style.textTruncation === "ENDING" ? (node.style.maxLines ?? undefined) : undefined;
|
|
285
277
|
|
|
@@ -291,9 +283,9 @@ export function createTypeStylePropsTransformer({
|
|
|
291
283
|
}
|
|
292
284
|
|
|
293
285
|
return {
|
|
294
|
-
fontSize:
|
|
295
|
-
fontWeight:
|
|
296
|
-
lineHeight:
|
|
286
|
+
fontSize: valueResolver.getFormattedValue.fontSize(node),
|
|
287
|
+
fontWeight: valueResolver.getFormattedValue.fontWeight(node),
|
|
288
|
+
lineHeight: valueResolver.getFormattedValue.lineHeight(node),
|
|
297
289
|
maxLines,
|
|
298
290
|
};
|
|
299
291
|
});
|
|
@@ -303,9 +295,9 @@ export interface FrameFillProps {
|
|
|
303
295
|
bg?: string;
|
|
304
296
|
}
|
|
305
297
|
|
|
306
|
-
export function
|
|
307
|
-
return
|
|
308
|
-
const bg =
|
|
298
|
+
export function createFrameFillPropsConverter(valueResolver: ReactValueResolver) {
|
|
299
|
+
return definePropsConverter<FillTrait, FrameFillProps>((node) => {
|
|
300
|
+
const bg = valueResolver.getFormattedValue.frameFill(node);
|
|
309
301
|
|
|
310
302
|
return {
|
|
311
303
|
bg,
|
|
@@ -317,9 +309,9 @@ export interface ShapeFillProps {
|
|
|
317
309
|
color?: string;
|
|
318
310
|
}
|
|
319
311
|
|
|
320
|
-
export function
|
|
321
|
-
return
|
|
322
|
-
const color =
|
|
312
|
+
export function createShapeFillPropsConverter(valueResolver: ReactValueResolver) {
|
|
313
|
+
return definePropsConverter<FillTrait, ShapeFillProps>((node) => {
|
|
314
|
+
const color = valueResolver.getFormattedValue.shapeFill(node);
|
|
323
315
|
|
|
324
316
|
return {
|
|
325
317
|
color,
|
|
@@ -331,9 +323,9 @@ export interface TextFillProps {
|
|
|
331
323
|
color?: string;
|
|
332
324
|
}
|
|
333
325
|
|
|
334
|
-
export function
|
|
335
|
-
return
|
|
336
|
-
const color =
|
|
326
|
+
export function createTextFillPropsConverter(valueResolver: ReactValueResolver) {
|
|
327
|
+
return definePropsConverter<FillTrait, TextFillProps>((node) => {
|
|
328
|
+
const color = valueResolver.getFormattedValue.textFill(node);
|
|
337
329
|
|
|
338
330
|
return {
|
|
339
331
|
color,
|
|
@@ -341,16 +333,46 @@ export function createTextFillPropsTransformer(valueTransformer: ReactValueTrans
|
|
|
341
333
|
});
|
|
342
334
|
}
|
|
343
335
|
|
|
336
|
+
export interface VectorChildrenFillProps {
|
|
337
|
+
color?: string;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export function createVectorChildrenFillPropsConverter(valueResolver: ReactValueResolver) {
|
|
341
|
+
return definePropsConverter<ContainerLayoutTrait, VectorChildrenFillProps>((node) => {
|
|
342
|
+
if (node.children.length === 0) {
|
|
343
|
+
console.warn(
|
|
344
|
+
`createVectorChildrenFillPropsConverter: Node has no children. Name:${node.name}, ID:${node.id}`,
|
|
345
|
+
);
|
|
346
|
+
return {};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const vectors = node.children.filter(
|
|
350
|
+
(child) => child.type === "VECTOR" || child.type === "BOOLEAN_OPERATION",
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
const colors = vectors.map((vector) => valueResolver.getFormattedValue.shapeFill(vector));
|
|
354
|
+
|
|
355
|
+
const fills = new Set(colors.filter((color) => color !== undefined));
|
|
356
|
+
|
|
357
|
+
// If there are more than 1 color, colors are likely pre-defined in the icon component; we should ignore the color prop.
|
|
358
|
+
if (fills.size > 1) {
|
|
359
|
+
return {};
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return { color: fills.values().next().value };
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
|
|
344
366
|
export interface StrokeProps {
|
|
345
367
|
borderWidth?: number;
|
|
346
368
|
borderColor?: string;
|
|
347
369
|
}
|
|
348
370
|
|
|
349
|
-
export function
|
|
350
|
-
|
|
351
|
-
):
|
|
352
|
-
return
|
|
353
|
-
const borderColor =
|
|
371
|
+
export function createStrokePropsConverter(
|
|
372
|
+
valueResolver: ReactValueResolver,
|
|
373
|
+
): PropsConverter<StrokeTrait, StrokeProps> {
|
|
374
|
+
return definePropsConverter((node) => {
|
|
375
|
+
const borderColor = valueResolver.getFormattedValue.stroke(node);
|
|
354
376
|
const borderWidth = borderColor ? node.strokeWeight : undefined;
|
|
355
377
|
|
|
356
378
|
return {
|
|
@@ -4,19 +4,19 @@ import type {
|
|
|
4
4
|
NormalizedVectorNode,
|
|
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 RectangleTransformerDeps {
|
|
10
|
-
|
|
10
|
+
propsConverters: PropsConverters;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function createRectangleTransformer({
|
|
14
|
-
|
|
14
|
+
propsConverters,
|
|
15
15
|
}: RectangleTransformerDeps): ElementTransformer<NormalizedRectangleNode> {
|
|
16
|
-
return defineElementTransformer((node: NormalizedRectangleNode
|
|
16
|
+
return defineElementTransformer((node: NormalizedRectangleNode) => {
|
|
17
17
|
return createElement(
|
|
18
18
|
"Box",
|
|
19
|
-
{ ...
|
|
19
|
+
{ ...propsConverters.selfLayout(node), background: "palette.gray200" },
|
|
20
20
|
undefined,
|
|
21
21
|
"Rectangle Node Placeholder",
|
|
22
22
|
);
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import type { NormalizedTextNode } from "@/normalizer";
|
|
2
2
|
import { compactObject } from "@/utils/common";
|
|
3
3
|
import { createElement, defineElementTransformer, type ElementTransformer } from "../../core";
|
|
4
|
-
import type {
|
|
4
|
+
import type { PropsConverters } from "./props";
|
|
5
5
|
|
|
6
6
|
export interface TextTransformerDeps {
|
|
7
|
-
|
|
7
|
+
propsConverters: PropsConverters;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export function createTextTransformer({
|
|
11
|
-
|
|
11
|
+
propsConverters,
|
|
12
12
|
}: TextTransformerDeps): ElementTransformer<NormalizedTextNode> {
|
|
13
|
-
return defineElementTransformer((node: NormalizedTextNode
|
|
13
|
+
return defineElementTransformer((node: NormalizedTextNode) => {
|
|
14
14
|
const hasMultipleFills = node.fills.length > 1;
|
|
15
15
|
|
|
16
|
-
const fillProps =
|
|
17
|
-
const typeStyleProps =
|
|
16
|
+
const fillProps = propsConverters.textFill(node);
|
|
17
|
+
const typeStyleProps = propsConverters.typeStyle(node);
|
|
18
18
|
|
|
19
19
|
const props = compactObject({
|
|
20
20
|
...typeStyleProps,
|