Skip to content

Commit e3a246f

Browse files
committed
Add blendMode. Fix border.
1 parent 5d5b716 commit e3a246f

File tree

15 files changed

+761
-539
lines changed

15 files changed

+761
-539
lines changed

apps/debug/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@
1111
},
1212
"dependencies": {
1313
"backend": "workspace:*",
14-
"next": "^13.4.15",
14+
"next": "^13.4.19",
1515
"plugin-ui": "workspace:*",
1616
"react": "^18.2.0",
1717
"react-dom": "^18.2.0"
1818
},
1919
"devDependencies": {
20-
"@types/node": "^20.5.0",
21-
"@types/react": "^18.2.20",
20+
"@types/node": "^20.6.0",
21+
"@types/react": "^18.2.21",
2222
"@types/react-dom": "^18.2.7",
2323
"autoprefixer": "^10.4.15",
2424
"eslint-config-custom": "workspace:*",
25-
"postcss": "^8.4.27",
25+
"postcss": "^8.4.29",
2626
"tailwindcss": "3.3.3",
2727
"tsconfig": "workspace:*",
28-
"typescript": "^5.1.6"
28+
"typescript": "^5.2.2"
2929
}
3030
}

apps/plugin/package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,30 @@
1010
"dev": "pnpm build:watch"
1111
},
1212
"dependencies": {
13-
"@figma/plugin-typings": "github:figma/plugin-typings#readonly-preview",
13+
"@figma/plugin-typings": "^1.76.0",
1414
"backend": "workspace:*",
1515
"plugin-ui": "workspace:*",
1616
"react": "^18.2.0",
1717
"react-dom": "^18.2.0"
1818
},
1919
"devDependencies": {
20-
"@types/node": "^20.5.0",
21-
"@types/react": "^18.2.20",
20+
"@types/node": "^20.6.0",
21+
"@types/react": "^18.2.21",
2222
"@types/react-dom": "^18.2.7",
23-
"@typescript-eslint/eslint-plugin": "^6.4.0",
24-
"@typescript-eslint/parser": "^6.4.0",
23+
"@typescript-eslint/eslint-plugin": "^6.7.0",
24+
"@typescript-eslint/parser": "^6.7.0",
2525
"@vitejs/plugin-react": "^4.0.4",
2626
"@vitejs/plugin-react-swc": "^3.3.2",
2727
"autoprefixer": "^10.4.15",
28-
"concurrently": "^8.2.0",
28+
"concurrently": "^8.2.1",
2929
"esbuild": "^0.19.2",
3030
"eslint-config-custom": "workspace:*",
3131
"eslint-plugin-react-hooks": "^4.6.0",
3232
"eslint-plugin-react-refresh": "^0.4.3",
33-
"postcss": "^8.4.27",
33+
"postcss": "^8.4.29",
3434
"tailwindcss": "3.3.3",
3535
"tsconfig": "workspace:*",
36-
"typescript": "^5.1.6",
36+
"typescript": "^5.2.2",
3737
"vite": "^4.4.9",
3838
"vite-plugin-singlefile": "^0.13.5"
3939
}

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
"format": "prettier --write \"**/*.{ts,tsx,md}\""
99
},
1010
"devDependencies": {
11-
"eslint": "^8.47.0",
11+
"eslint": "^8.49.0",
1212
"eslint-config-custom": "workspace:*",
13-
"prettier": "^3.0.1",
14-
"turbo": "^1.10.12"
13+
"prettier": "^3.0.3",
14+
"turbo": "^1.10.13"
1515
},
16-
"packageManager": "pnpm@7.15.0"
16+
"packageManager": "pnpm@8.7.5"
1717
}

packages/backend/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
"test": "jest"
1515
},
1616
"dependencies": {
17-
"@figma/plugin-typings": "github:figma/plugin-typings#readonly-preview",
17+
"@figma/plugin-typings": "^1.76.0",
1818
"react": "18.2.0",
1919
"react-dom": "18.2.0"
2020
},
2121
"devDependencies": {
22-
"@types/react": "^18.2.20",
22+
"@types/react": "^18.2.21",
2323
"@types/react-dom": "^18.2.7",
24-
"eslint": "^8.47.0",
24+
"eslint": "^8.49.0",
2525
"eslint-config-custom": "workspace:*",
2626
"tsconfig": "workspace:*",
2727
"tsup": "^7.2.0",
28-
"typescript": "^5.1.6"
28+
"typescript": "^5.2.2"
2929
}
3030
}

packages/backend/src/common/commonStroke.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ type BorderSideType =
77
bottom: number;
88
};
99

10-
export const commonStroke = (node: SceneNode): BorderSideType | null => {
10+
export const commonStroke = (node: SceneNode, divideBy: number = 1): BorderSideType | null => {
1111
if (!("strokes" in node) || !node.strokes || node.strokes.length === 0) {
1212
return null;
1313
}
@@ -18,17 +18,17 @@ export const commonStroke = (node: SceneNode): BorderSideType | null => {
1818
node.strokeTopWeight === node.strokeLeftWeight &&
1919
node.strokeTopWeight === node.strokeRightWeight
2020
) {
21-
return { all: node.strokeTopWeight / 2 };
21+
return { all: node.strokeTopWeight / divideBy };
2222
}
2323

2424
return {
25-
left: node.strokeLeftWeight / 2,
26-
top: node.strokeTopWeight / 2,
27-
right: node.strokeRightWeight / 2,
28-
bottom: node.strokeBottomWeight / 2,
25+
left: node.strokeLeftWeight / divideBy,
26+
top: node.strokeTopWeight / divideBy,
27+
right: node.strokeRightWeight / divideBy,
28+
bottom: node.strokeBottomWeight / divideBy,
2929
};
3030
} else if (node.strokeWeight !== figma.mixed && node.strokeWeight !== 0) {
31-
return { all: node.strokeWeight / 2 };
31+
return { all: node.strokeWeight / divideBy };
3232
}
3333

3434
return null;

packages/backend/src/html/builderImpl/htmlBlend.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,64 @@ export const htmlOpacity = (
2323
return "";
2424
};
2525

26+
export const htmlBlendMode = (node: MinimalBlendMixin, isJsx: boolean): string => {
27+
if (node.blendMode !== "NORMAL" && node.blendMode !== "PASS_THROUGH") {
28+
let blendMode = "";
29+
switch (node.blendMode) {
30+
case "MULTIPLY":
31+
blendMode = "multiply";
32+
break;
33+
case "SCREEN":
34+
blendMode = "screen";
35+
break;
36+
case "OVERLAY":
37+
blendMode = "overlay";
38+
break;
39+
case "DARKEN":
40+
blendMode = "darken";
41+
break;
42+
case "LIGHTEN":
43+
blendMode = "lighten";
44+
break;
45+
case "COLOR_DODGE":
46+
blendMode = "color-dodge";
47+
break;
48+
case "COLOR_BURN":
49+
blendMode = "color-burn";
50+
break;
51+
case "HARD_LIGHT":
52+
blendMode = "hard-light";
53+
break;
54+
case "SOFT_LIGHT":
55+
blendMode = "soft-light";
56+
break;
57+
case "DIFFERENCE":
58+
blendMode = "difference";
59+
break;
60+
case "EXCLUSION":
61+
blendMode = "exclusion";
62+
break;
63+
case "HUE":
64+
blendMode = "hue";
65+
break;
66+
case "SATURATION":
67+
blendMode = "saturation";
68+
break;
69+
case "COLOR":
70+
blendMode = "color";
71+
break;
72+
case "LUMINOSITY":
73+
blendMode = "luminosity";
74+
break;
75+
}
76+
77+
if (blendMode) {
78+
return formatWithJSX("mix-blend-mode", isJsx, blendMode);
79+
}
80+
}
81+
return "";
82+
};
83+
2684
/**
2785
* https://tailwindcss.com/docs/visibility/
2886
* example: invisible

packages/backend/src/html/htmlDefaultBuilder.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
htmlVisibility,
55
htmlRotation,
66
htmlOpacity,
7+
htmlBlendMode,
78
} from "./builderImpl/htmlBlend";
89
import {
910
htmlColor,
@@ -65,7 +66,8 @@ export class HtmlDefaultBuilder {
6566
this.addStyles(
6667
htmlVisibility(node, this.isJSX),
6768
...htmlRotation(node, this.isJSX),
68-
htmlOpacity(node, this.isJSX)
69+
htmlOpacity(node, this.isJSX),
70+
htmlBlendMode(node, this.isJSX)
6971
);
7072
return this;
7173
}

packages/backend/src/swiftui/builderImpl/swiftuiBorder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const swiftUIStroke = (node: SceneNode): number => {
99
return 0;
1010
}
1111

12-
const stroke = commonStroke(node);
12+
const stroke = commonStroke(node, 2);
1313

1414
if (!stroke) {
1515
return 0;

packages/backend/src/tailwind/builderImpl/tailwindBlend.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,54 @@ import { exactValue, nearestOpacity, nearestValue } from "../conversionTables";
77
* if opacity was changed, let it be visible. Therefore, 98% => 75
88
* node.opacity is between [0, 1]; output will be [0, 100]
99
*/
10-
export const tailwindOpacity = (node: BlendMixin): string => {
10+
export const tailwindOpacity = (node: MinimalBlendMixin): string => {
1111
// [when testing] node.opacity can be undefined
1212
if (node.opacity !== undefined && node.opacity !== 1) {
1313
return `opacity-${nearestOpacity(node.opacity)}`;
1414
}
1515
return "";
1616
};
1717

18+
// https://tailwindcss.com/docs/mix-blend-mode
19+
export const tailwindBlendMode = (node: MinimalBlendMixin): string => {
20+
if (node.blendMode !== "NORMAL" && node.blendMode !== "PASS_THROUGH") {
21+
switch (node.blendMode) {
22+
case "MULTIPLY":
23+
return "mix-blend-multiply";
24+
case "SCREEN":
25+
return "mix-blend-screen";
26+
case "OVERLAY":
27+
return "mix-blend-overlay";
28+
case "DARKEN":
29+
return "mix-blend-darken";
30+
case "LIGHTEN":
31+
return "mix-blend-lighten";
32+
case "COLOR_DODGE":
33+
return "mix-blend-color-dodge";
34+
case "COLOR_BURN":
35+
return "mix-blend-color-burn";
36+
case "HARD_LIGHT":
37+
return "mix-blend-hard-light";
38+
case "SOFT_LIGHT":
39+
return "mix-blend-soft-light";
40+
case "DIFFERENCE":
41+
return "mix-blend-difference";
42+
case "EXCLUSION":
43+
return "mix-blend-exclusion";
44+
case "HUE":
45+
return "mix-blend-hue";
46+
case "SATURATION":
47+
return "mix-blend-saturation";
48+
case "COLOR":
49+
return "mix-blend-color";
50+
case "LUMINOSITY":
51+
return "mix-blend-luminosity";
52+
}
53+
return "";
54+
}
55+
return "";
56+
};
57+
1858
/**
1959
* https://tailwindcss.com/docs/visibility/
2060
* example: invisible

packages/backend/src/tailwind/builderImpl/tailwindBorder.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ export const tailwindBorderWidth = (node: SceneNode): string => {
1515

1616
const getBorder = (weight: number, kind: string) => {
1717
const allowedValues = [1, 2, 4, 8];
18+
console.log("weight", weight);
1819
const nearest = nearestValue(weight, allowedValues);
20+
console.log("nearest", nearest);
21+
1922
if (nearest === 1) {
2023
// special case
2124
return `border${kind}`;

0 commit comments

Comments
 (0)