@seed-design/figma 0.0.22 → 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 +208 -215
- package/lib/codegen/index.d.ts +17 -16
- package/lib/codegen/index.js +209 -215
- package/lib/codegen/targets/react/index.cjs +26 -33
- package/lib/codegen/targets/react/index.d.ts +4 -7
- package/lib/codegen/targets/react/index.js +26 -33
- package/package.json +2 -2
- package/src/codegen/core/codegen.ts +6 -10
- package/src/codegen/core/index.ts +0 -2
- package/src/codegen/core/value-resolver.ts +2 -3
- package/src/codegen/targets/figma/pipeline.ts +26 -3
- package/src/codegen/targets/figma/value-resolver.ts +15 -18
- package/src/codegen/targets/react/pipeline.ts +20 -4
- package/src/codegen/targets/react/value-resolver.ts +26 -29
- package/src/codegen/core/context.ts +0 -20
package/lib/codegen/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { match } from 'ts-pattern';
|
|
2
2
|
import 'change-case';
|
|
3
|
-
import { AsyncLocalStorage } from 'async_hooks';
|
|
4
3
|
import * as index_js from './targets/react/index.js';
|
|
5
4
|
export { index_js as react };
|
|
6
5
|
|
|
@@ -98,15 +97,6 @@ function stringifyElement(element, options = {}) {
|
|
|
98
97
|
return recursive(element, 0);
|
|
99
98
|
}
|
|
100
99
|
|
|
101
|
-
const codegenOptionsContext = new AsyncLocalStorage();
|
|
102
|
-
function useCodegenOptions() {
|
|
103
|
-
const options = codegenOptionsContext.getStore();
|
|
104
|
-
if (!options) {
|
|
105
|
-
throw new Error("Trying to get codegen options outside of codegen context. Did you forget to call `codegenOptionsContext.run`?");
|
|
106
|
-
}
|
|
107
|
-
return options;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
100
|
// --- Helper Functions ---
|
|
111
101
|
function getCollectiveBoundingBox(nodes) {
|
|
112
102
|
if (nodes.length === 0) {
|
|
@@ -414,12 +404,11 @@ function applyInferredLayout(parentNode, result) {
|
|
|
414
404
|
};
|
|
415
405
|
}
|
|
416
406
|
|
|
417
|
-
function createCodeGenerator({ frameTransformer, textTransformer, rectangleTransformer, instanceTransformer, vectorTransformer, booleanOperationTransformer }) {
|
|
407
|
+
function createCodeGenerator({ frameTransformer, textTransformer, rectangleTransformer, instanceTransformer, vectorTransformer, booleanOperationTransformer, shouldInferAutoLayout }) {
|
|
418
408
|
function traverse(node) {
|
|
419
409
|
if ("visible" in node && !node.visible) {
|
|
420
410
|
return;
|
|
421
411
|
}
|
|
422
|
-
const { shouldInferAutoLayout } = useCodegenOptions();
|
|
423
412
|
const result = match(node).with({
|
|
424
413
|
type: "FRAME"
|
|
425
414
|
}, (node)=>shouldInferAutoLayout ? frameTransformer(applyInferredLayout(node, inferLayout(node)), traverse) : frameTransformer(node, traverse)).with({
|
|
@@ -443,11 +432,11 @@ function createCodeGenerator({ frameTransformer, textTransformer, rectangleTrans
|
|
|
443
432
|
}
|
|
444
433
|
return;
|
|
445
434
|
}
|
|
446
|
-
function generateJsxTree(node
|
|
447
|
-
return
|
|
435
|
+
function generateJsxTree(node) {
|
|
436
|
+
return traverse(node);
|
|
448
437
|
}
|
|
449
438
|
function generateCode(node, options) {
|
|
450
|
-
const jsxTree = generateJsxTree(node
|
|
439
|
+
const jsxTree = generateJsxTree(node);
|
|
451
440
|
return jsxTree ? stringifyElement(jsxTree, {
|
|
452
441
|
printSource: options.shouldPrintSource
|
|
453
442
|
}) : undefined;
|
|
@@ -519,7 +508,7 @@ function getFirstStrokeVariable(node) {
|
|
|
519
508
|
return node.boundVariables?.strokes?.[0];
|
|
520
509
|
}
|
|
521
510
|
|
|
522
|
-
function createValueResolver({ variableService, variableNameFormatter, styleService, styleNameFormatter, rawValueFormatters }) {
|
|
511
|
+
function createValueResolver({ variableService, variableNameFormatter, styleService, styleNameFormatter, rawValueFormatters, shouldInferVariableName }) {
|
|
523
512
|
function getVariableName(key) {
|
|
524
513
|
const slug = variableService.getSlug(key);
|
|
525
514
|
if (!slug) {
|
|
@@ -530,7 +519,6 @@ function createValueResolver({ variableService, variableNameFormatter, styleServ
|
|
|
530
519
|
});
|
|
531
520
|
}
|
|
532
521
|
function inferVariableName(value, scope) {
|
|
533
|
-
const { shouldInferVariableName } = useCodegenOptions();
|
|
534
522
|
if (!shouldInferVariableName) {
|
|
535
523
|
return undefined;
|
|
536
524
|
}
|
|
@@ -632,189 +620,6 @@ function createValueResolver({ variableService, variableNameFormatter, styleServ
|
|
|
632
620
|
};
|
|
633
621
|
}
|
|
634
622
|
|
|
635
|
-
function createFrameTransformer({ propsConverters }) {
|
|
636
|
-
return defineElementTransformer((node, traverse)=>{
|
|
637
|
-
const children = node.children;
|
|
638
|
-
const props = {
|
|
639
|
-
...propsConverters.radius(node),
|
|
640
|
-
...propsConverters.containerLayout(node),
|
|
641
|
-
...propsConverters.selfLayout(node),
|
|
642
|
-
...propsConverters.frameFill(node),
|
|
643
|
-
...propsConverters.stroke(node)
|
|
644
|
-
};
|
|
645
|
-
return createElement("Frame", props, children.map((child)=>traverse(child)));
|
|
646
|
-
});
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
function createInstanceTransformer({ frameTransformer }) {
|
|
650
|
-
const transform = defineElementTransformer((node, traverse)=>{
|
|
651
|
-
return frameTransformer(node, traverse);
|
|
652
|
-
});
|
|
653
|
-
return transform;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
function createContainerLayoutPropsConverter(valueResolver) {
|
|
657
|
-
return createPropsConverter({
|
|
658
|
-
handlers: {
|
|
659
|
-
layoutMode: ({ layoutMode })=>layoutMode ?? "NONE",
|
|
660
|
-
primaryAxisAlignItems: ({ primaryAxisAlignItems })=>primaryAxisAlignItems,
|
|
661
|
-
counterAxisAlignItems: ({ counterAxisAlignItems })=>counterAxisAlignItems,
|
|
662
|
-
layoutWrap: ({ layoutWrap })=>layoutWrap,
|
|
663
|
-
itemSpacing: (node)=>valueResolver.getFormattedValue.itemSpacing(node),
|
|
664
|
-
paddingTop: (node)=>valueResolver.getFormattedValue.paddingTop(node),
|
|
665
|
-
paddingBottom: (node)=>valueResolver.getFormattedValue.paddingBottom(node),
|
|
666
|
-
paddingLeft: (node)=>valueResolver.getFormattedValue.paddingLeft(node),
|
|
667
|
-
paddingRight: (node)=>valueResolver.getFormattedValue.paddingRight(node)
|
|
668
|
-
},
|
|
669
|
-
shorthands: {
|
|
670
|
-
horizontalPadding: [
|
|
671
|
-
"paddingLeft",
|
|
672
|
-
"paddingRight"
|
|
673
|
-
],
|
|
674
|
-
verticalPadding: [
|
|
675
|
-
"paddingTop",
|
|
676
|
-
"paddingBottom"
|
|
677
|
-
]
|
|
678
|
-
},
|
|
679
|
-
defaults: {}
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
function createSelfLayoutPropsConverter(valueResolver) {
|
|
683
|
-
return createPropsConverter({
|
|
684
|
-
handlers: {
|
|
685
|
-
layoutGrow: ({ layoutGrow })=>layoutGrow,
|
|
686
|
-
layoutAlign: ({ layoutAlign })=>layoutAlign,
|
|
687
|
-
layoutSizingVertical: ({ layoutSizingVertical })=>layoutSizingVertical,
|
|
688
|
-
layoutSizingHorizontal: ({ layoutSizingHorizontal })=>layoutSizingHorizontal,
|
|
689
|
-
width: (node)=>valueResolver.getFormattedValue.width(node),
|
|
690
|
-
height: (node)=>valueResolver.getFormattedValue.height(node),
|
|
691
|
-
minWidth: (node)=>valueResolver.getFormattedValue.minWidth(node),
|
|
692
|
-
minHeight: (node)=>valueResolver.getFormattedValue.minHeight(node),
|
|
693
|
-
maxWidth: (node)=>valueResolver.getFormattedValue.maxWidth(node),
|
|
694
|
-
maxHeight: (node)=>valueResolver.getFormattedValue.maxHeight(node)
|
|
695
|
-
},
|
|
696
|
-
defaults: {}
|
|
697
|
-
});
|
|
698
|
-
}
|
|
699
|
-
function createRadiusPropsConverter(valueResolver) {
|
|
700
|
-
return createPropsConverter({
|
|
701
|
-
handlers: {
|
|
702
|
-
topLeftRadius: (node)=>valueResolver.getFormattedValue.topLeftRadius(node),
|
|
703
|
-
topRightRadius: (node)=>valueResolver.getFormattedValue.topRightRadius(node),
|
|
704
|
-
bottomLeftRadius: (node)=>valueResolver.getFormattedValue.bottomLeftRadius(node),
|
|
705
|
-
bottomRightRadius: (node)=>valueResolver.getFormattedValue.bottomRightRadius(node)
|
|
706
|
-
},
|
|
707
|
-
shorthands: {
|
|
708
|
-
cornerRadius: [
|
|
709
|
-
"topLeftRadius",
|
|
710
|
-
"topRightRadius",
|
|
711
|
-
"bottomLeftRadius",
|
|
712
|
-
"bottomRightRadius"
|
|
713
|
-
]
|
|
714
|
-
},
|
|
715
|
-
defaults: {
|
|
716
|
-
cornerRadius: 0,
|
|
717
|
-
topLeftRadius: 0,
|
|
718
|
-
topRightRadius: 0,
|
|
719
|
-
bottomLeftRadius: 0,
|
|
720
|
-
bottomRightRadius: 0
|
|
721
|
-
}
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
function createFrameFillPropsConverter(valueResolver) {
|
|
725
|
-
return definePropsConverter((node)=>{
|
|
726
|
-
const fill = valueResolver.getFormattedValue.frameFill(node);
|
|
727
|
-
return {
|
|
728
|
-
fill
|
|
729
|
-
};
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
|
-
function createShapeFillPropsConverter(valueResolver) {
|
|
733
|
-
return definePropsConverter((node)=>{
|
|
734
|
-
const fill = valueResolver.getFormattedValue.shapeFill(node);
|
|
735
|
-
return {
|
|
736
|
-
fill
|
|
737
|
-
};
|
|
738
|
-
});
|
|
739
|
-
}
|
|
740
|
-
function createTextFillPropsConverter(valueResolver) {
|
|
741
|
-
return definePropsConverter((node)=>{
|
|
742
|
-
const fill = valueResolver.getFormattedValue.textFill(node);
|
|
743
|
-
return {
|
|
744
|
-
fill
|
|
745
|
-
};
|
|
746
|
-
});
|
|
747
|
-
}
|
|
748
|
-
function createStrokePropsConverter(valueResolver) {
|
|
749
|
-
return definePropsConverter((node)=>{
|
|
750
|
-
const stroke = valueResolver.getFormattedValue.stroke(node);
|
|
751
|
-
const strokeWeight = node.strokeWeight;
|
|
752
|
-
return {
|
|
753
|
-
stroke,
|
|
754
|
-
strokeWeight
|
|
755
|
-
};
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
function createTypeStylePropsConverter(valueResolver) {
|
|
759
|
-
return definePropsConverter((node)=>{
|
|
760
|
-
const styleName = valueResolver.getTextStyleValue(node);
|
|
761
|
-
const maxLines = node.style.textTruncation === "ENDING" ? node.style.maxLines ?? undefined : undefined;
|
|
762
|
-
if (styleName) {
|
|
763
|
-
return {
|
|
764
|
-
textStyle: styleName,
|
|
765
|
-
maxLines
|
|
766
|
-
};
|
|
767
|
-
}
|
|
768
|
-
return {
|
|
769
|
-
fontSize: valueResolver.getFormattedValue.fontSize(node),
|
|
770
|
-
fontWeight: valueResolver.getFormattedValue.fontWeight(node),
|
|
771
|
-
lineHeight: valueResolver.getFormattedValue.lineHeight(node),
|
|
772
|
-
maxLines
|
|
773
|
-
};
|
|
774
|
-
});
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
function createRectangleTransformer({ propsConverters }) {
|
|
778
|
-
return defineElementTransformer((node)=>{
|
|
779
|
-
return createElement("Rectangle", {
|
|
780
|
-
...propsConverters.selfLayout(node)
|
|
781
|
-
});
|
|
782
|
-
});
|
|
783
|
-
}
|
|
784
|
-
function createVectorTransformer({ propsConverters }) {
|
|
785
|
-
return defineElementTransformer((node)=>{
|
|
786
|
-
return createElement("Vector", {
|
|
787
|
-
...propsConverters.selfLayout(node),
|
|
788
|
-
...propsConverters.radius(node),
|
|
789
|
-
...propsConverters.stroke(node),
|
|
790
|
-
...propsConverters.shapeFill(node)
|
|
791
|
-
}, [], "Vector Node Placeholder");
|
|
792
|
-
});
|
|
793
|
-
}
|
|
794
|
-
function createBooleanOperationTransformer({ propsConverters }) {
|
|
795
|
-
return defineElementTransformer((node, traverse)=>{
|
|
796
|
-
return createElement("BooleanOperation", {
|
|
797
|
-
...propsConverters.selfLayout(node),
|
|
798
|
-
...propsConverters.radius(node),
|
|
799
|
-
...propsConverters.stroke(node),
|
|
800
|
-
...propsConverters.shapeFill(node)
|
|
801
|
-
}, node.children.map(traverse));
|
|
802
|
-
});
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
function createTextTransformer({ propsConverters }) {
|
|
806
|
-
return defineElementTransformer((node)=>{
|
|
807
|
-
const hasMultipleFills = node.fills.length > 1;
|
|
808
|
-
const fillProps = propsConverters.textFill(node);
|
|
809
|
-
const typeStyleProps = propsConverters.typeStyle(node);
|
|
810
|
-
const props = compactObject({
|
|
811
|
-
...typeStyleProps,
|
|
812
|
-
...fillProps
|
|
813
|
-
});
|
|
814
|
-
return createElement("Text", props, node.characters, hasMultipleFills ? "Multiple fills in Text node encountered, only the first fill is used." : "");
|
|
815
|
-
});
|
|
816
|
-
}
|
|
817
|
-
|
|
818
623
|
const FIGMA_TEXT_STYLES = [
|
|
819
624
|
{
|
|
820
625
|
styleType: "TEXT",
|
|
@@ -7899,6 +7704,189 @@ const variableService = createVariableService({
|
|
|
7899
7704
|
}
|
|
7900
7705
|
});
|
|
7901
7706
|
|
|
7707
|
+
function createFrameTransformer({ propsConverters }) {
|
|
7708
|
+
return defineElementTransformer((node, traverse)=>{
|
|
7709
|
+
const children = node.children;
|
|
7710
|
+
const props = {
|
|
7711
|
+
...propsConverters.radius(node),
|
|
7712
|
+
...propsConverters.containerLayout(node),
|
|
7713
|
+
...propsConverters.selfLayout(node),
|
|
7714
|
+
...propsConverters.frameFill(node),
|
|
7715
|
+
...propsConverters.stroke(node)
|
|
7716
|
+
};
|
|
7717
|
+
return createElement("Frame", props, children.map((child)=>traverse(child)));
|
|
7718
|
+
});
|
|
7719
|
+
}
|
|
7720
|
+
|
|
7721
|
+
function createInstanceTransformer({ frameTransformer }) {
|
|
7722
|
+
const transform = defineElementTransformer((node, traverse)=>{
|
|
7723
|
+
return frameTransformer(node, traverse);
|
|
7724
|
+
});
|
|
7725
|
+
return transform;
|
|
7726
|
+
}
|
|
7727
|
+
|
|
7728
|
+
function createContainerLayoutPropsConverter(valueResolver) {
|
|
7729
|
+
return createPropsConverter({
|
|
7730
|
+
handlers: {
|
|
7731
|
+
layoutMode: ({ layoutMode })=>layoutMode ?? "NONE",
|
|
7732
|
+
primaryAxisAlignItems: ({ primaryAxisAlignItems })=>primaryAxisAlignItems,
|
|
7733
|
+
counterAxisAlignItems: ({ counterAxisAlignItems })=>counterAxisAlignItems,
|
|
7734
|
+
layoutWrap: ({ layoutWrap })=>layoutWrap,
|
|
7735
|
+
itemSpacing: (node)=>valueResolver.getFormattedValue.itemSpacing(node),
|
|
7736
|
+
paddingTop: (node)=>valueResolver.getFormattedValue.paddingTop(node),
|
|
7737
|
+
paddingBottom: (node)=>valueResolver.getFormattedValue.paddingBottom(node),
|
|
7738
|
+
paddingLeft: (node)=>valueResolver.getFormattedValue.paddingLeft(node),
|
|
7739
|
+
paddingRight: (node)=>valueResolver.getFormattedValue.paddingRight(node)
|
|
7740
|
+
},
|
|
7741
|
+
shorthands: {
|
|
7742
|
+
horizontalPadding: [
|
|
7743
|
+
"paddingLeft",
|
|
7744
|
+
"paddingRight"
|
|
7745
|
+
],
|
|
7746
|
+
verticalPadding: [
|
|
7747
|
+
"paddingTop",
|
|
7748
|
+
"paddingBottom"
|
|
7749
|
+
]
|
|
7750
|
+
},
|
|
7751
|
+
defaults: {}
|
|
7752
|
+
});
|
|
7753
|
+
}
|
|
7754
|
+
function createSelfLayoutPropsConverter(valueResolver) {
|
|
7755
|
+
return createPropsConverter({
|
|
7756
|
+
handlers: {
|
|
7757
|
+
layoutGrow: ({ layoutGrow })=>layoutGrow,
|
|
7758
|
+
layoutAlign: ({ layoutAlign })=>layoutAlign,
|
|
7759
|
+
layoutSizingVertical: ({ layoutSizingVertical })=>layoutSizingVertical,
|
|
7760
|
+
layoutSizingHorizontal: ({ layoutSizingHorizontal })=>layoutSizingHorizontal,
|
|
7761
|
+
width: (node)=>valueResolver.getFormattedValue.width(node),
|
|
7762
|
+
height: (node)=>valueResolver.getFormattedValue.height(node),
|
|
7763
|
+
minWidth: (node)=>valueResolver.getFormattedValue.minWidth(node),
|
|
7764
|
+
minHeight: (node)=>valueResolver.getFormattedValue.minHeight(node),
|
|
7765
|
+
maxWidth: (node)=>valueResolver.getFormattedValue.maxWidth(node),
|
|
7766
|
+
maxHeight: (node)=>valueResolver.getFormattedValue.maxHeight(node)
|
|
7767
|
+
},
|
|
7768
|
+
defaults: {}
|
|
7769
|
+
});
|
|
7770
|
+
}
|
|
7771
|
+
function createRadiusPropsConverter(valueResolver) {
|
|
7772
|
+
return createPropsConverter({
|
|
7773
|
+
handlers: {
|
|
7774
|
+
topLeftRadius: (node)=>valueResolver.getFormattedValue.topLeftRadius(node),
|
|
7775
|
+
topRightRadius: (node)=>valueResolver.getFormattedValue.topRightRadius(node),
|
|
7776
|
+
bottomLeftRadius: (node)=>valueResolver.getFormattedValue.bottomLeftRadius(node),
|
|
7777
|
+
bottomRightRadius: (node)=>valueResolver.getFormattedValue.bottomRightRadius(node)
|
|
7778
|
+
},
|
|
7779
|
+
shorthands: {
|
|
7780
|
+
cornerRadius: [
|
|
7781
|
+
"topLeftRadius",
|
|
7782
|
+
"topRightRadius",
|
|
7783
|
+
"bottomLeftRadius",
|
|
7784
|
+
"bottomRightRadius"
|
|
7785
|
+
]
|
|
7786
|
+
},
|
|
7787
|
+
defaults: {
|
|
7788
|
+
cornerRadius: 0,
|
|
7789
|
+
topLeftRadius: 0,
|
|
7790
|
+
topRightRadius: 0,
|
|
7791
|
+
bottomLeftRadius: 0,
|
|
7792
|
+
bottomRightRadius: 0
|
|
7793
|
+
}
|
|
7794
|
+
});
|
|
7795
|
+
}
|
|
7796
|
+
function createFrameFillPropsConverter(valueResolver) {
|
|
7797
|
+
return definePropsConverter((node)=>{
|
|
7798
|
+
const fill = valueResolver.getFormattedValue.frameFill(node);
|
|
7799
|
+
return {
|
|
7800
|
+
fill
|
|
7801
|
+
};
|
|
7802
|
+
});
|
|
7803
|
+
}
|
|
7804
|
+
function createShapeFillPropsConverter(valueResolver) {
|
|
7805
|
+
return definePropsConverter((node)=>{
|
|
7806
|
+
const fill = valueResolver.getFormattedValue.shapeFill(node);
|
|
7807
|
+
return {
|
|
7808
|
+
fill
|
|
7809
|
+
};
|
|
7810
|
+
});
|
|
7811
|
+
}
|
|
7812
|
+
function createTextFillPropsConverter(valueResolver) {
|
|
7813
|
+
return definePropsConverter((node)=>{
|
|
7814
|
+
const fill = valueResolver.getFormattedValue.textFill(node);
|
|
7815
|
+
return {
|
|
7816
|
+
fill
|
|
7817
|
+
};
|
|
7818
|
+
});
|
|
7819
|
+
}
|
|
7820
|
+
function createStrokePropsConverter(valueResolver) {
|
|
7821
|
+
return definePropsConverter((node)=>{
|
|
7822
|
+
const stroke = valueResolver.getFormattedValue.stroke(node);
|
|
7823
|
+
const strokeWeight = node.strokeWeight;
|
|
7824
|
+
return {
|
|
7825
|
+
stroke,
|
|
7826
|
+
strokeWeight
|
|
7827
|
+
};
|
|
7828
|
+
});
|
|
7829
|
+
}
|
|
7830
|
+
function createTypeStylePropsConverter(valueResolver) {
|
|
7831
|
+
return definePropsConverter((node)=>{
|
|
7832
|
+
const styleName = valueResolver.getTextStyleValue(node);
|
|
7833
|
+
const maxLines = node.style.textTruncation === "ENDING" ? node.style.maxLines ?? undefined : undefined;
|
|
7834
|
+
if (styleName) {
|
|
7835
|
+
return {
|
|
7836
|
+
textStyle: styleName,
|
|
7837
|
+
maxLines
|
|
7838
|
+
};
|
|
7839
|
+
}
|
|
7840
|
+
return {
|
|
7841
|
+
fontSize: valueResolver.getFormattedValue.fontSize(node),
|
|
7842
|
+
fontWeight: valueResolver.getFormattedValue.fontWeight(node),
|
|
7843
|
+
lineHeight: valueResolver.getFormattedValue.lineHeight(node),
|
|
7844
|
+
maxLines
|
|
7845
|
+
};
|
|
7846
|
+
});
|
|
7847
|
+
}
|
|
7848
|
+
|
|
7849
|
+
function createRectangleTransformer({ propsConverters }) {
|
|
7850
|
+
return defineElementTransformer((node)=>{
|
|
7851
|
+
return createElement("Rectangle", {
|
|
7852
|
+
...propsConverters.selfLayout(node)
|
|
7853
|
+
});
|
|
7854
|
+
});
|
|
7855
|
+
}
|
|
7856
|
+
function createVectorTransformer({ propsConverters }) {
|
|
7857
|
+
return defineElementTransformer((node)=>{
|
|
7858
|
+
return createElement("Vector", {
|
|
7859
|
+
...propsConverters.selfLayout(node),
|
|
7860
|
+
...propsConverters.radius(node),
|
|
7861
|
+
...propsConverters.stroke(node),
|
|
7862
|
+
...propsConverters.shapeFill(node)
|
|
7863
|
+
}, [], "Vector Node Placeholder");
|
|
7864
|
+
});
|
|
7865
|
+
}
|
|
7866
|
+
function createBooleanOperationTransformer({ propsConverters }) {
|
|
7867
|
+
return defineElementTransformer((node, traverse)=>{
|
|
7868
|
+
return createElement("BooleanOperation", {
|
|
7869
|
+
...propsConverters.selfLayout(node),
|
|
7870
|
+
...propsConverters.radius(node),
|
|
7871
|
+
...propsConverters.stroke(node),
|
|
7872
|
+
...propsConverters.shapeFill(node)
|
|
7873
|
+
}, node.children.map(traverse));
|
|
7874
|
+
});
|
|
7875
|
+
}
|
|
7876
|
+
|
|
7877
|
+
function createTextTransformer({ propsConverters }) {
|
|
7878
|
+
return defineElementTransformer((node)=>{
|
|
7879
|
+
const hasMultipleFills = node.fills.length > 1;
|
|
7880
|
+
const fillProps = propsConverters.textFill(node);
|
|
7881
|
+
const typeStyleProps = propsConverters.typeStyle(node);
|
|
7882
|
+
const props = compactObject({
|
|
7883
|
+
...typeStyleProps,
|
|
7884
|
+
...fillProps
|
|
7885
|
+
});
|
|
7886
|
+
return createElement("Text", props, node.characters, hasMultipleFills ? "Multiple fills in Text node encountered, only the first fill is used." : "");
|
|
7887
|
+
});
|
|
7888
|
+
}
|
|
7889
|
+
|
|
7902
7890
|
function toCssRgba(color) {
|
|
7903
7891
|
if (color.a === 1) {
|
|
7904
7892
|
return `rgb(${Math.round(color.r * 255)}, ${Math.round(color.g * 255)}, ${Math.round(color.b * 255)})`;
|
|
@@ -7906,20 +7894,25 @@ function toCssRgba(color) {
|
|
|
7906
7894
|
return `rgba(${Math.round(color.r * 255)}, ${Math.round(color.g * 255)}, ${Math.round(color.b * 255)}, ${color.a})`;
|
|
7907
7895
|
}
|
|
7908
7896
|
|
|
7909
|
-
const
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
fontDimension: (value)=>value,
|
|
7918
|
-
fontWeight: (value)=>value
|
|
7919
|
-
}
|
|
7920
|
-
});
|
|
7897
|
+
const defaultVariableNameFormatter = ({ slug })=>slug.filter((s)=>s !== "dimension").map((s)=>s.replaceAll(",", "_")).join("/");
|
|
7898
|
+
const defaultStyleNameFormatter = ({ slug })=>slug[slug.length - 1];
|
|
7899
|
+
const defaultRawValueFormatters = {
|
|
7900
|
+
color: (value)=>toCssRgba(value),
|
|
7901
|
+
dimension: (value)=>value,
|
|
7902
|
+
fontDimension: (value)=>value,
|
|
7903
|
+
fontWeight: (value)=>value
|
|
7904
|
+
};
|
|
7921
7905
|
|
|
7922
|
-
function createPipeline() {
|
|
7906
|
+
function createPipeline(options = {}) {
|
|
7907
|
+
const { shouldInferAutoLayout = true, shouldInferVariableName = true } = options;
|
|
7908
|
+
const valueResolver = createValueResolver({
|
|
7909
|
+
variableService,
|
|
7910
|
+
variableNameFormatter: defaultVariableNameFormatter,
|
|
7911
|
+
styleService,
|
|
7912
|
+
styleNameFormatter: defaultStyleNameFormatter,
|
|
7913
|
+
rawValueFormatters: defaultRawValueFormatters,
|
|
7914
|
+
shouldInferVariableName
|
|
7915
|
+
});
|
|
7923
7916
|
const containerLayoutPropsConverter = createContainerLayoutPropsConverter(valueResolver);
|
|
7924
7917
|
const selfLayoutPropsConverter = createSelfLayoutPropsConverter(valueResolver);
|
|
7925
7918
|
const frameFillPropsConverter = createFrameFillPropsConverter(valueResolver);
|
|
@@ -7962,7 +7955,8 @@ function createPipeline() {
|
|
|
7962
7955
|
rectangleTransformer,
|
|
7963
7956
|
instanceTransformer,
|
|
7964
7957
|
vectorTransformer,
|
|
7965
|
-
booleanOperationTransformer
|
|
7958
|
+
booleanOperationTransformer,
|
|
7959
|
+
shouldInferAutoLayout
|
|
7966
7960
|
});
|
|
7967
7961
|
return codegenTransformer;
|
|
7968
7962
|
}
|
|
@@ -7986,4 +7980,4 @@ var index = {
|
|
|
7986
7980
|
createVectorTransformer: createVectorTransformer
|
|
7987
7981
|
};
|
|
7988
7982
|
|
|
7989
|
-
export { cloneElement, createCodeGenerator, createElement, createPropsConverter, createValueResolver, defineComponentHandler, defineElementTransformer, definePropsConverter, index as figma, inferLayout
|
|
7983
|
+
export { cloneElement, createCodeGenerator, createElement, createPropsConverter, createValueResolver, defineComponentHandler, defineElementTransformer, definePropsConverter, index as figma, inferLayout };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
var tsPattern = require('ts-pattern');
|
|
2
2
|
var changeCase = require('change-case');
|
|
3
|
-
var async_hooks = require('async_hooks');
|
|
4
3
|
|
|
5
4
|
function ensureArray(maybeArray) {
|
|
6
5
|
if (Array.isArray(maybeArray)) {
|
|
@@ -105,15 +104,6 @@ function stringifyElement(element, options = {}) {
|
|
|
105
104
|
return recursive(element, 0);
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
const codegenOptionsContext = new async_hooks.AsyncLocalStorage();
|
|
109
|
-
function useCodegenOptions() {
|
|
110
|
-
const options = codegenOptionsContext.getStore();
|
|
111
|
-
if (!options) {
|
|
112
|
-
throw new Error("Trying to get codegen options outside of codegen context. Did you forget to call `codegenOptionsContext.run`?");
|
|
113
|
-
}
|
|
114
|
-
return options;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
107
|
// --- Helper Functions ---
|
|
118
108
|
function getCollectiveBoundingBox(nodes) {
|
|
119
109
|
if (nodes.length === 0) {
|
|
@@ -421,12 +411,11 @@ function applyInferredLayout(parentNode, result) {
|
|
|
421
411
|
};
|
|
422
412
|
}
|
|
423
413
|
|
|
424
|
-
function createCodeGenerator({ frameTransformer, textTransformer, rectangleTransformer, instanceTransformer, vectorTransformer, booleanOperationTransformer }) {
|
|
414
|
+
function createCodeGenerator({ frameTransformer, textTransformer, rectangleTransformer, instanceTransformer, vectorTransformer, booleanOperationTransformer, shouldInferAutoLayout }) {
|
|
425
415
|
function traverse(node) {
|
|
426
416
|
if ("visible" in node && !node.visible) {
|
|
427
417
|
return;
|
|
428
418
|
}
|
|
429
|
-
const { shouldInferAutoLayout } = useCodegenOptions();
|
|
430
419
|
const result = tsPattern.match(node).with({
|
|
431
420
|
type: "FRAME"
|
|
432
421
|
}, (node)=>shouldInferAutoLayout ? frameTransformer(applyInferredLayout(node, inferLayout(node)), traverse) : frameTransformer(node, traverse)).with({
|
|
@@ -450,11 +439,11 @@ function createCodeGenerator({ frameTransformer, textTransformer, rectangleTrans
|
|
|
450
439
|
}
|
|
451
440
|
return;
|
|
452
441
|
}
|
|
453
|
-
function generateJsxTree(node
|
|
454
|
-
return
|
|
442
|
+
function generateJsxTree(node) {
|
|
443
|
+
return traverse(node);
|
|
455
444
|
}
|
|
456
445
|
function generateCode(node, options) {
|
|
457
|
-
const jsxTree = generateJsxTree(node
|
|
446
|
+
const jsxTree = generateJsxTree(node);
|
|
458
447
|
return jsxTree ? stringifyElement(jsxTree, {
|
|
459
448
|
printSource: options.shouldPrintSource
|
|
460
449
|
}) : undefined;
|
|
@@ -554,7 +543,7 @@ function getFirstStrokeVariable(node) {
|
|
|
554
543
|
return node.boundVariables?.strokes?.[0];
|
|
555
544
|
}
|
|
556
545
|
|
|
557
|
-
function createValueResolver({ variableService, variableNameFormatter, styleService, styleNameFormatter, rawValueFormatters }) {
|
|
546
|
+
function createValueResolver({ variableService, variableNameFormatter, styleService, styleNameFormatter, rawValueFormatters, shouldInferVariableName }) {
|
|
558
547
|
function getVariableName(key) {
|
|
559
548
|
const slug = variableService.getSlug(key);
|
|
560
549
|
if (!slug) {
|
|
@@ -565,7 +554,6 @@ function createValueResolver({ variableService, variableNameFormatter, styleServ
|
|
|
565
554
|
});
|
|
566
555
|
}
|
|
567
556
|
function inferVariableName(value, scope) {
|
|
568
|
-
const { shouldInferVariableName } = useCodegenOptions();
|
|
569
557
|
if (!shouldInferVariableName) {
|
|
570
558
|
return undefined;
|
|
571
559
|
}
|
|
@@ -12102,26 +12090,30 @@ function toCssRgba(color) {
|
|
|
12102
12090
|
return `rgba(${Math.round(color.r * 255)}, ${Math.round(color.g * 255)}, ${Math.round(color.b * 255)}, ${color.a})`;
|
|
12103
12091
|
}
|
|
12104
12092
|
|
|
12105
|
-
const
|
|
12106
|
-
|
|
12107
|
-
|
|
12108
|
-
|
|
12109
|
-
|
|
12110
|
-
|
|
12111
|
-
|
|
12112
|
-
|
|
12113
|
-
|
|
12114
|
-
|
|
12115
|
-
fontDimension: (value)=>toCssPixel(value),
|
|
12116
|
-
fontWeight: (value)=>value
|
|
12117
|
-
}
|
|
12118
|
-
});
|
|
12093
|
+
const defaultVariableNameFormatter = ({ slug })=>slug.filter((s)=>!(s === "dimension" || s === "radius" || s === "font-size" || s === "font-weight" || s === "line-height")).map((s)=>s.replaceAll(",", "_")).map(camelCasePreserveUnderscoreBetweenNumbers).join(".");
|
|
12094
|
+
const defaultStyleNameFormatter = ({ slug })=>changeCase.camelCase(slug[slug.length - 1], {
|
|
12095
|
+
mergeAmbiguousCharacters: true
|
|
12096
|
+
});
|
|
12097
|
+
const defaultRawValueFormatters = {
|
|
12098
|
+
color: (value)=>toCssRgba(value),
|
|
12099
|
+
dimension: (value)=>toCssPixel(value),
|
|
12100
|
+
fontDimension: (value)=>toCssPixel(value),
|
|
12101
|
+
fontWeight: (value)=>value
|
|
12102
|
+
};
|
|
12119
12103
|
|
|
12120
12104
|
const iconHandler = createIconHandler({
|
|
12121
12105
|
iconService
|
|
12122
12106
|
});
|
|
12123
12107
|
function createPipeline(options = {}) {
|
|
12124
|
-
const { extend = {} } = options;
|
|
12108
|
+
const { shouldInferAutoLayout = true, shouldInferVariableName = true, extend = {} } = options;
|
|
12109
|
+
const valueResolver = createValueResolver({
|
|
12110
|
+
variableService,
|
|
12111
|
+
variableNameFormatter: defaultVariableNameFormatter,
|
|
12112
|
+
styleService,
|
|
12113
|
+
styleNameFormatter: defaultStyleNameFormatter,
|
|
12114
|
+
rawValueFormatters: defaultRawValueFormatters,
|
|
12115
|
+
shouldInferVariableName
|
|
12116
|
+
});
|
|
12125
12117
|
const containerLayoutPropsConverter = createContainerLayoutPropsConverter(valueResolver);
|
|
12126
12118
|
const selfLayoutPropsConverter = createSelfLayoutPropsConverter(valueResolver);
|
|
12127
12119
|
const iconSelfLayoutPropsConverter = createIconSelfLayoutPropsConverter(valueResolver);
|
|
@@ -12179,7 +12171,8 @@ function createPipeline(options = {}) {
|
|
|
12179
12171
|
rectangleTransformer,
|
|
12180
12172
|
instanceTransformer,
|
|
12181
12173
|
vectorTransformer,
|
|
12182
|
-
booleanOperationTransformer
|
|
12174
|
+
booleanOperationTransformer,
|
|
12175
|
+
shouldInferAutoLayout
|
|
12183
12176
|
});
|
|
12184
12177
|
return codeGenerator;
|
|
12185
12178
|
}
|
|
@@ -68,11 +68,6 @@ interface NormalizedUnhandledNode {
|
|
|
68
68
|
}
|
|
69
69
|
type NormalizedSceneNode = NormalizedFrameNode | NormalizedRectangleNode | NormalizedTextNode | NormalizedComponentNode | NormalizedInstanceNode | NormalizedVectorNode | NormalizedBooleanOperationNode | NormalizedUnhandledNode;
|
|
70
70
|
|
|
71
|
-
interface CodegenOptions {
|
|
72
|
-
shouldInferAutoLayout: boolean;
|
|
73
|
-
shouldInferVariableName: boolean;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
71
|
interface ElementNode {
|
|
77
72
|
__IS_JSX_ELEMENT_NODE: true;
|
|
78
73
|
tag: string;
|
|
@@ -255,13 +250,15 @@ declare function bindComponentHandler<T extends NormalizedInstanceNode["componen
|
|
|
255
250
|
declare const unboundSeedComponentHandlers: Array<UnboundComponentHandler<any>>;
|
|
256
251
|
|
|
257
252
|
interface CreatePipelineConfig {
|
|
253
|
+
shouldInferAutoLayout?: boolean;
|
|
254
|
+
shouldInferVariableName?: boolean;
|
|
258
255
|
extend?: {
|
|
259
256
|
componentHandlers?: Array<UnboundComponentHandler<any>>;
|
|
260
257
|
};
|
|
261
258
|
}
|
|
262
259
|
declare function createPipeline(options?: CreatePipelineConfig): {
|
|
263
|
-
generateJsxTree: (node: NormalizedSceneNode
|
|
264
|
-
generateCode: (node: NormalizedSceneNode, options:
|
|
260
|
+
generateJsxTree: (node: NormalizedSceneNode) => ElementNode | undefined;
|
|
261
|
+
generateCode: (node: NormalizedSceneNode, options: {
|
|
265
262
|
shouldPrintSource: boolean;
|
|
266
263
|
}) => string | undefined;
|
|
267
264
|
};
|