Skip to content

Commit 2b41278

Browse files
committed
Add responsive resizer.
1 parent f1a6122 commit 2b41278

File tree

8 files changed

+100
-41
lines changed

8 files changed

+100
-41
lines changed

packages/backend/src/altNodes/altConversion.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const cloneNode = <T extends BaseNode>(node: T): T => {
1616
prop !== "verticalPadding" &&
1717
prop !== "mainComponent" &&
1818
prop !== "masterComponent" &&
19+
prop !== "variantProperties" &&
1920
prop !== "componentPropertyDefinitions" &&
2021
prop !== "exposedInstances"
2122
) {

packages/backend/src/altNodes/convertNodesOnRectangle.ts

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,39 +15,43 @@ export const convertNodesOnRectangle = (
1515
);
1616
}
1717

18-
const colliding = retrieveCollidingItems(node.children);
18+
// TODO Make a return?
19+
// const colliding = retrieveCollidingItems(node.children);
1920

20-
const parentsKeys = Object.keys(colliding);
21-
// start with all children. This is going to be filtered.
22-
let updatedChildren: Array<SceneNode> = [...node.children];
21+
// const parentsKeys = Object.keys(colliding);
22+
// // start with all children. This is going to be filtered.
23+
// let updatedChildren: Array<SceneNode> = [...node.children];
2324

24-
parentsKeys.forEach((key) => {
25-
// dangerous cast, but this is always true
26-
const parentNode = node.children.find((d) => d.id === key) as RectangleNode;
25+
// console.log("colliding are", parentsKeys);
2726

28-
// retrieve the position. Key should always be at the left side, so even when other items are removed, the index is kept the same.
29-
// const indexPosition = updatedChildren.findIndex((d) => d.id === key);
27+
// parentsKeys.forEach((key) => {
28+
// // dangerous cast, but this is always true
29+
// const parentNode = node.children.find((d) => d.id === key) as RectangleNode;
3030

31-
// filter the children to remove those that are being modified
32-
updatedChildren = updatedChildren.filter(
33-
(d) => !colliding[key].map((dd) => dd.id).includes(d.id) && key !== d.id
34-
);
31+
// // retrieve the position. Key should always be at the left side, so even when other items are removed, the index is kept the same.
32+
// // const indexPosition = updatedChildren.findIndex((d) => d.id === key);
3533

36-
const frameNode = convertRectangleToFrame(parentNode);
34+
// // filter the children to remove those that are being modified
35+
// updatedChildren = updatedChildren.filter(
36+
// (d) => !colliding[key].map((dd) => dd.id).includes(d.id) && key !== d.id
37+
// );
3738

38-
// todo when the soon-to-be-parent is larger than its parent, things get weird. Happens, for example, when a large image is used in the background. Should this be handled or is this something user should never do?
39+
// console.log("updatedChildren is now ", updatedChildren);
40+
// const frameNode = convertRectangleToFrame(parentNode);
3941

40-
Object.assign(frameNode, { children: [...colliding[key]] });
41-
colliding[key].forEach((d) => {
42-
Object.assign(d, { parent: frameNode });
43-
d.x = d.x - frameNode.x;
44-
d.y = d.y - frameNode.y;
45-
});
46-
});
42+
// // todo when the soon-to-be-parent is larger than its parent, things get weird. Happens, for example, when a large image is used in the background. Should this be handled or is this something user should never do?
43+
// overrideReadonlyProperty(frameNode, "children", [...colliding[key]]);
4744

48-
if (updatedChildren.length > 0) {
49-
Object.assign(node, { children: updatedChildren });
50-
}
45+
// colliding[key].forEach((d) => {
46+
// overrideReadonlyProperty(d, "parent", frameNode);
47+
// d.x = d.x - frameNode.x;
48+
// d.y = d.y - frameNode.y;
49+
// });
50+
// });
51+
52+
// if (updatedChildren.length > 0) {
53+
// overrideReadonlyProperty(node, "children", updatedChildren);
54+
// }
5155

5256
return node;
5357
};

packages/backend/src/flutter/flutterMain.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,5 +225,13 @@ const addSpacingIfNeeded = (node: SceneNode): string => {
225225
return "";
226226
};
227227

228-
export const flutterCodeGenTextStyles = () =>
229-
previousExecutionCache.map((style) => `${style}`).join("\n// ---\n");
228+
export const flutterCodeGenTextStyles = () => {
229+
const result = previousExecutionCache
230+
.map((style) => `${style}`)
231+
.join("\n// ---\n");
232+
233+
if (!result) {
234+
return "// No text styles in this selection";
235+
}
236+
return result;
237+
};

packages/backend/src/html/htmlDefaultBuilder.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ export class HtmlDefaultBuilder {
137137
position(node: SceneNode, optimizeLayout: boolean): this {
138138
if (commonIsAbsolutePosition(node, optimizeLayout)) {
139139
const { x, y } = getCommonPositionValue(node);
140+
140141
this.addStyles(
141142
formatWithJSX("left", this.isJSX, x),
142143
formatWithJSX("top", this.isJSX, y),

packages/backend/src/html/htmlMain.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,15 @@ export const htmlLine = (node: LineNode, isJsx: boolean): string => {
274274
};
275275

276276
export const htmlCodeGenTextStyles = (isJsx: boolean) => {
277-
return previousExecutionCache
277+
const result = previousExecutionCache
278278
.map(
279279
(style) =>
280280
`// ${style.text}\n${style.style.split(isJsx ? "," : ";").join(";\n")}`
281281
)
282282
.join("\n---\n");
283+
284+
if (!result) {
285+
return "// No text styles in this selection";
286+
}
287+
return result;
283288
};

packages/backend/src/swiftui/swiftuiMain.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,5 +274,12 @@ const widgetGeneratorWithLimits = (
274274
return strBuilder;
275275
};
276276

277-
export const swiftUICodeGenTextStyles = () =>
278-
previousExecutionCache.map((style) => `${style}`).join("\n// ---\n");
277+
export const swiftUICodeGenTextStyles = () => {
278+
const result = previousExecutionCache
279+
.map((style) => `${style}`)
280+
.join("\n// ---\n");
281+
if (!result) {
282+
return "// No text styles in this selection";
283+
}
284+
return result;
285+
};

packages/backend/src/tailwind/tailwindMain.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,13 @@ export const tailwindSection = (node: SectionNode, isJsx: boolean): string => {
249249
};
250250

251251
export const tailwindCodeGenTextStyles = () => {
252-
return previousExecutionCache
252+
const result = previousExecutionCache
253253
.map((style) => `// ${style.text}\n${style.style.split(" ").join("\n")}`)
254254
.join("\n---\n");
255+
256+
if (!result) {
257+
return "// No text styles in this selection";
258+
}
259+
260+
return result;
255261
};

packages/plugin-ui/src/PluginUI.tsx

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ type PluginUIProps = {
3939
};
4040

4141
export const PluginUI = (props: PluginUIProps) => {
42+
const [isResponsiveExpanded, setIsResponsiveExpanded] = useState(false);
43+
4244
return (
4345
<div className="flex flex-col h-full dark:text-white">
4446
<div className="p-2 grid grid-cols-4 sm:grid-cols-2 md:grid-cols-4 gap-1">
@@ -66,20 +68,25 @@ export const PluginUI = (props: PluginUIProps) => {
6668
}}
6769
></div>
6870
<div className="flex flex-col h-full overflow-y-auto">
69-
<div className="flex flex-col items-center px-2 py-2 gap-2 dark:bg-transparent">
71+
<div className="flex flex-col items-center px-4 py-2 gap-2 dark:bg-transparent">
7072
{/* <div className="flex flex-col items-center p-4 bg-neutral-50 dark:bg-neutral-800 rounded">
7173
<Description selected={props.selectedFramework} />
7274
</div> */}
7375

74-
{props.htmlPreview && <Preview htmlPreview={props.htmlPreview} />}
76+
{props.htmlPreview && (
77+
<Preview
78+
htmlPreview={props.htmlPreview}
79+
isResponsiveExpanded={isResponsiveExpanded}
80+
setIsResponsiveExpanded={setIsResponsiveExpanded}
81+
/>
82+
)}
7583
{/* <ResponsiveGrade /> */}
7684
{/* <div className="h-2"></div>
7785
<div className="flex justify-end w-full mb-1">
7886
<button className="px-4 py-2 text-sm font-semibold text-white bg-neutral-900 rounded-lg ring-1 ring-neutral-700 hover:bg-neutral-700 focus:outline-none">
7987
Copy
8088
</button>
8189
</div> */}
82-
{/* Code View */}
8390
<CodePanel
8491
code={props.code}
8592
selectedFramework={props.selectedFramework}
@@ -448,8 +455,6 @@ export const GradientsPanel = (props: {
448455
props.onColorClick(value);
449456
};
450457

451-
console.log(props.gradients);
452-
453458
return (
454459
<div className="bg-gray-100 dark:bg-neutral-900 w-full rounded-lg p-2 flex flex-col gap-2">
455460
<h2 className="text-gray-800 dark:text-gray-200 text-lg font-medium">
@@ -580,18 +585,28 @@ export const Preview: React.FC<{
580585
size: { width: number; height: number };
581586
content: string;
582587
};
588+
isResponsiveExpanded: boolean;
589+
setIsResponsiveExpanded: (value: boolean) => void;
583590
}> = (props) => {
584591
const previewWidths = [45, 80, 140];
585592
const labels = ["sm", "md", "lg"];
586593

587594
return (
588-
<div className="flex flex-col">
589-
<p className="px-4 py-1.5 text-lg font-medium text-center dark:text-white rounded-lg">
590-
Responsive Preview
591-
</p>
595+
<div className="flex flex-col w-full">
596+
<div className="py-1.5 flex gap-2 w-full text-lg font-medium text-center dark:text-white rounded-lg justify-between">
597+
<span>Responsive Preview</span>
598+
<button
599+
className={`px-2 py-1 text-sm font-semibold border border-green-500 rounded-md shadow-sm hover:bg-green-500 dark:hover:bg-green-600 hover:text-white hover:border-transparent transition-all duration-300 ${"bg-neutral-100 dark:bg-neutral-700 text-neutral-700 dark:text-neutral-200 border-neutral-300 dark:border-neutral-600"}`}
600+
onClick={() => {
601+
props.setIsResponsiveExpanded(!props.isResponsiveExpanded);
602+
}}
603+
>
604+
<ExpandIcon size={16} />
605+
</button>
606+
</div>
592607
<div className="flex gap-2 justify-center items-center">
593608
{previewWidths.map((targetWidth, index) => {
594-
const targetHeight = 80;
609+
const targetHeight = props.isResponsiveExpanded ? 260 : 120;
595610
const scaleFactor = Math.min(
596611
targetWidth / props.htmlPreview.size.width,
597612
targetHeight / props.htmlPreview.size.height
@@ -654,3 +669,15 @@ export const viewDocumentationWebsite = () => {
654669
</div>
655670
);
656671
};
672+
673+
const ExpandIcon = (props: { size: number }) => (
674+
<svg
675+
xmlns="http://www.w3.org/2000/svg"
676+
width={props.size}
677+
height={props.size}
678+
fill="currentColor"
679+
viewBox="0 0 256 256"
680+
>
681+
<path d="M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128ZM101.66,53.66,120,35.31V96a8,8,0,0,0,16,0V35.31l18.34,18.35a8,8,0,0,0,11.32-11.32l-32-32a8,8,0,0,0-11.32,0l-32,32a8,8,0,0,0,11.32,11.32Zm52.68,148.68L136,220.69V160a8,8,0,0,0-16,0v60.69l-18.34-18.35a8,8,0,0,0-11.32,11.32l32,32a8,8,0,0,0,11.32,0l32-32a8,8,0,0,0-11.32-11.32Z"></path>
682+
</svg>
683+
);

0 commit comments

Comments
 (0)