Skip to content

Commit 2c9445d

Browse files
committed
Fix radius
1 parent 42150da commit 2c9445d

7 files changed

Lines changed: 123 additions & 67 deletions

File tree

packages/backend/src/altNodes/altNodeUtils.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ export const renderAndAttachSVG = async (node: any) => {
5656
// const nodeName = `${node.type}:${node.id}`;
5757
// console.log(altNode);
5858
if (node.canBeFlattened) {
59-
console.log("altNode is", node);
60-
6159
if (node.svg) {
6260
// console.log(`SVG already rendered for ${nodeName}`);
6361
return node;

packages/backend/src/common/commonRadius.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
import { CornerRadius } from "types";
22

33
export const getCommonRadius = (node: SceneNode): CornerRadius => {
4+
if ("rectangleCornerRadii" in node) {
5+
const [topLeft, topRight, bottomRight, bottomLeft] =
6+
node.rectangleCornerRadii as any;
7+
if (
8+
topLeft === topRight &&
9+
topLeft === bottomRight &&
10+
topLeft === bottomLeft
11+
) {
12+
return { all: topLeft };
13+
}
14+
15+
return {
16+
topLeft,
17+
topRight,
18+
bottomRight,
19+
bottomLeft,
20+
};
21+
}
22+
423
if (
524
"cornerRadius" in node &&
625
node.cornerRadius !== figma.mixed &&

packages/backend/src/common/exportAsyncProxy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const exportAsyncProxy = async <
2222
}
2323

2424
const figmaNode = (await figma.getNodeByIdAsync(node.id)) as ExportMixin;
25-
console.log("getting figma id for", figmaNode);
25+
// console.log("getting figma id for", figmaNode);
2626

2727
if (figmaNode.exportAsync === undefined) {
2828
// console.log(node);

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

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { getCommonRadius } from "../../common/commonRadius";
22
import { formatWithJSX } from "../../common/parseJSX";
33

44
export const htmlBorderRadius = (node: SceneNode, isJsx: boolean): string[] => {
5-
const radius = getCommonRadius(node);
65
if (node.type === "ELLIPSE") {
76
return [formatWithJSX("border-radius", isJsx, 9999)];
87
}
98

9+
const radius = getCommonRadius(node);
10+
1011
let comp: string[] = [];
11-
let cornerValues: number[] = [0, 0, 0, 0];
1212
let singleCorner: number = 0;
1313

1414
if ("all" in radius) {
@@ -17,21 +17,28 @@ export const htmlBorderRadius = (node: SceneNode, isJsx: boolean): string[] => {
1717
}
1818
singleCorner = radius.all;
1919
comp.push(formatWithJSX("border-radius", isJsx, radius.all));
20-
} else if ("topLeftRadius" in node) {
21-
cornerValues = handleIndividualRadius(node);
22-
comp.push(
23-
...cornerValues
24-
.filter((d) => d > 0)
25-
.map((value, index) => {
26-
const property = [
27-
"border-top-left-radius",
28-
"border-top-right-radius",
29-
"border-bottom-right-radius",
30-
"border-bottom-left-radius",
31-
][index];
32-
return formatWithJSX(property, isJsx, value);
33-
}),
34-
);
20+
} else {
21+
const cornerValues = [
22+
radius.topLeft,
23+
radius.topRight,
24+
radius.bottomRight,
25+
radius.bottomLeft,
26+
];
27+
28+
// Map each corner value to its corresponding CSS property
29+
const cornerProperties = [
30+
"border-top-left-radius",
31+
"border-top-right-radius",
32+
"border-bottom-right-radius",
33+
"border-bottom-left-radius",
34+
];
35+
36+
// Add CSS properties for non-zero corner values
37+
for (let i = 0; i < 4; i++) {
38+
if (cornerValues[i] > 0) {
39+
comp.push(formatWithJSX(cornerProperties[i], isJsx, cornerValues[i]));
40+
}
41+
}
3542
}
3643

3744
if (
@@ -45,13 +52,3 @@ export const htmlBorderRadius = (node: SceneNode, isJsx: boolean): string[] => {
4552

4653
return comp;
4754
};
48-
49-
const handleIndividualRadius = (node: RectangleCornerMixin): number[] => {
50-
const cornerValues = [
51-
node.topLeftRadius,
52-
node.topRightRadius,
53-
node.bottomRightRadius,
54-
node.bottomLeftRadius,
55-
];
56-
return cornerValues;
57-
};

packages/backend/src/html/htmlDefaultBuilder.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,8 @@ export class HtmlDefaultBuilder {
223223
position(): this {
224224
const { node, optimizeLayout, isJSX } = this;
225225
const isAbsolutePosition = commonIsAbsolutePosition(node, optimizeLayout);
226-
console.log("isAbsolutePosition", isAbsolutePosition, "for node", node);
227226
if (isAbsolutePosition) {
228227
const { x, y } = getCommonPositionValue(node);
229-
console.log("x, y, are", x, y);
230228

231229
this.addStyles(
232230
formatWithJSX("left", isJSX, x),

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export const tailwindBorderRadius = (node: SceneNode): string => {
142142
return `rounded${getRadius(radius.all)}`;
143143
}
144144

145-
// todo optimize for tr/tl/br/bl instead of t/r/l/b
145+
// todo optimize for t/r/l/b instead of tr/tl/br/bl
146146
let comp: string[] = [];
147147
if (radius.topLeft !== 0) {
148148
comp.push(`rounded-tl${getRadius(radius.topLeft)}`);

packages/plugin-ui/src/components/Preview.tsx

Lines changed: 78 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ import {
66
MonitorSmartphone,
77
Smartphone,
88
Circle,
9+
Ruler,
10+
MonitorIcon,
911
} from "lucide-react";
1012

1113
const Preview: React.FC<{
1214
htmlPreview: HTMLPreview;
1315
}> = (props) => {
1416
const [expanded, setExpanded] = useState(false);
15-
const [viewMode, setViewMode] = useState<"desktop" | "mobile">("desktop");
17+
const [viewMode, setViewMode] = useState<"desktop" | "mobile" | "precision">(
18+
"desktop",
19+
);
1620
const [animationClass, setAnimationClass] = useState<string>("");
1721
const [bgColor, setBgColor] = useState<"white" | "black">("white");
1822

@@ -22,27 +26,26 @@ const Preview: React.FC<{
2226

2327
// Calculate content dimensions based on view mode
2428
const contentWidth =
25-
viewMode === "desktop" ? containerWidth : Math.floor(containerWidth * 0.4); // Narrower for mobile
26-
27-
// Adjust scale factor based on view mode
28-
const scaleFactor =
2929
viewMode === "desktop"
30-
? Math.min(
31-
containerWidth / props.htmlPreview.size.width,
32-
containerHeight / props.htmlPreview.size.height,
33-
)
34-
: Math.min(
35-
contentWidth / props.htmlPreview.size.width,
36-
containerHeight / props.htmlPreview.size.height,
37-
);
30+
? containerWidth
31+
: viewMode === "mobile"
32+
? Math.floor(containerWidth * 0.4) // Narrower for mobile
33+
: containerWidth; // For precision, use container width for the outer frame
34+
35+
const scaleFactor = Math.min(
36+
containerWidth / props.htmlPreview.size.width,
37+
containerHeight / props.htmlPreview.size.height,
38+
);
3839

3940
// Add animation when changing view mode
4041
useEffect(() => {
41-
setAnimationClass(
42-
viewMode === "desktop"
43-
? "animate-slide-in-left"
44-
: "animate-slide-in-right",
45-
);
42+
if (viewMode === "desktop") {
43+
setAnimationClass("animate-slide-in-left");
44+
} else if (viewMode === "mobile") {
45+
setAnimationClass("animate-slide-in-right");
46+
} else {
47+
setAnimationClass("animate-fade-in");
48+
}
4649
const timer = setTimeout(() => setAnimationClass(""), 300); // Remove animation class after it completes
4750
return () => clearTimeout(timer);
4851
}, [viewMode]);
@@ -65,15 +68,19 @@ const Preview: React.FC<{
6568
Preview
6669
</h3>
6770
<div className="flex items-center gap-1">
68-
{/* Background Color Toggle */}
69-
<button
70-
onClick={() => setBgColor(bgColor === "white" ? "black" : "white")}
71-
className="p-1.5 mr-1 rounded hover:bg-neutral-100 dark:hover:bg-neutral-700 text-neutral-500 dark:text-neutral-400 transition-colors"
72-
aria-label={`Switch the preview to ${bgColor === "white" ? "black" : "white"} background.\nUseful to avoid black text on black background.`}
73-
title={`Switch the preview to ${bgColor === "white" ? "black" : "white"} background.\nUseful to avoid black text on black background.`}
74-
>
75-
<Circle size={14} fill={bgColor} className="stroke-current" />
76-
</button>
71+
{/* Background Color Toggle - Only show in desktop and mobile modes */}
72+
{viewMode !== "precision" && (
73+
<button
74+
onClick={() =>
75+
setBgColor(bgColor === "white" ? "black" : "white")
76+
}
77+
className="p-1.5 mr-1 rounded hover:bg-neutral-100 dark:hover:bg-neutral-700 text-neutral-500 dark:text-neutral-400 transition-colors"
78+
aria-label={`Switch the preview to ${bgColor === "white" ? "black" : "white"} background.\nUseful to avoid black text on black background.`}
79+
title={`Switch the preview to ${bgColor === "white" ? "black" : "white"} background.\nUseful to avoid black text on black background.`}
80+
>
81+
<Circle size={14} fill={bgColor} className="stroke-current" />
82+
</button>
83+
)}
7784

7885
{/* View Mode Toggle */}
7986
<div className="mr-1 flex bg-neutral-100 dark:bg-neutral-700 rounded-md p-0.5">
@@ -101,6 +108,18 @@ const Preview: React.FC<{
101108
>
102109
<Smartphone size={14} />
103110
</button>
111+
<button
112+
onClick={() => setViewMode("precision")}
113+
className={`p-1 rounded text-xs ${
114+
viewMode === "precision"
115+
? "bg-white dark:bg-neutral-600 shadow-sm text-neutral-800 dark:text-white"
116+
: "text-neutral-500 dark:text-neutral-400 hover:text-neutral-800 dark:hover:text-white"
117+
} transition-colors duration-200`}
118+
aria-label="Precision view (exact dimensions)"
119+
title="Precision view (exact dimensions)"
120+
>
121+
<Ruler size={14} />
122+
</button>
104123
</div>
105124

106125
{/* Expand/Collapse Button */}
@@ -134,26 +153,46 @@ const Preview: React.FC<{
134153
height:
135154
viewMode === "mobile"
136155
? Math.min(containerHeight * 0.9, containerHeight)
137-
: containerHeight,
156+
: containerHeight, // Use full container height for both desktop and precision
138157
transition: "width 0.3s ease, height 0.3s ease",
139158
}}
140159
>
141-
{/* Device frame - just a border for mobile, no status bar or home indicator */}
160+
{/* Device frame - no background for precision mode */}
142161
<div
143162
className={`w-full h-full flex justify-center items-center overflow-hidden ${
144-
bgColor === "white" ? "bg-white" : "bg-black"
163+
viewMode === "precision"
164+
? "" // No background in precision mode
165+
: bgColor === "white"
166+
? "bg-white"
167+
: "bg-black"
145168
} ${
146169
viewMode === "desktop"
147170
? "border border-neutral-300 dark:border-neutral-600 rounded shadow-sm"
148-
: "border-2 border-neutral-400 dark:border-neutral-500 rounded-xl shadow-sm"
171+
: viewMode === "mobile"
172+
? "border-2 border-neutral-400 dark:border-neutral-500 rounded-xl shadow-sm"
173+
: "border border-indigo-400 dark:border-indigo-500 rounded shadow-sm" // Precision mode uses indigo border with rounded corners
149174
} transition-all duration-300 ease-in-out`}
150175
>
151-
{/* Content - no padding needed anymore */}
176+
{/* Content */}
152177
<div className="w-full h-full flex justify-center items-center">
153178
<div
154-
className="w-full"
155179
style={{
156180
zoom: scaleFactor,
181+
width:
182+
viewMode === "precision"
183+
? props.htmlPreview.size.width
184+
: "100%",
185+
height:
186+
viewMode === "precision"
187+
? props.htmlPreview.size.height
188+
: "100%",
189+
transformOrigin: "center",
190+
maxWidth: "100%",
191+
maxHeight: "100%",
192+
aspectRatio:
193+
viewMode === "precision"
194+
? `${props.htmlPreview.size.width} / ${props.htmlPreview.size.height}`
195+
: undefined,
157196
transition: "all 0.3s ease",
158197
}}
159198
dangerouslySetInnerHTML={{
@@ -178,9 +217,14 @@ const Preview: React.FC<{
178217
<Smartphone size={10} />
179218
<span>Mobile view</span>
180219
</span>
220+
) : viewMode === "precision" ? (
221+
<span className="flex items-center gap-1">
222+
<Ruler size={10} />
223+
<span>Precision view</span>
224+
</span>
181225
) : (
182226
<span className="flex items-center gap-1">
183-
<MonitorSmartphone size={10} />
227+
<MonitorIcon size={10} />
184228
<span>Desktop view</span>
185229
</span>
186230
)}

0 commit comments

Comments
 (0)