Skip to content

Commit

Permalink
Friendly name for layers (onlook-dev#78)
Browse files Browse the repository at this point in the history
* Naming layers

* Update next plugin

* Update Babel plugin
  • Loading branch information
Kitenite authored Jul 22, 2024
1 parent b733ad8 commit ca25e81
Show file tree
Hide file tree
Showing 24 changed files with 161 additions and 94 deletions.
25 changes: 6 additions & 19 deletions app/common/helpers.ts → app/common/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
import { EditorAttributes } from './constants';
import { TemplateNode } from './models';
import { finder } from './selector';
import { EditorAttributes } from '../constants';
import { finder } from '../selector';

export function querySelectorCommand(selector: string) {
return `document.querySelector('${CSS.escape(selector)}')`;
}

export function compareTemplateNodes(node1: TemplateNode, node2: TemplateNode): number {
if (node1.startTag.start.line < node2.startTag.start.line) {
return -1;
} else if (node1.startTag.start.line > node2.startTag.start.line) {
return 1;
} else {
if (node1.startTag.start.column < node2.startTag.start.column) {
return -1;
} else if (node1.startTag.start.column > node2.startTag.start.column) {
return 1;
} else {
return 0;
}
}
}

export const getUniqueSelector = (el: HTMLElement, root?: Element | undefined): string => {
let selector = el.tagName.toLowerCase();
// If data-onlook-component-id exists, use that
Expand All @@ -45,3 +28,7 @@ export const getUniqueSelector = (el: HTMLElement, root?: Element | undefined):
}
return selector;
};

export function capitalizeFirstLetter(string: string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
50 changes: 50 additions & 0 deletions app/common/helpers/template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { compressSync, decompressSync, strFromU8, strToU8 } from 'fflate';
import { EditorAttributes } from '../constants';
import { TemplateNode } from '../models';

export function getTemplateNodeFromElement(element: Element): TemplateNode | undefined {
const dataOnlookId = element.getAttribute(EditorAttributes.DATA_ONLOOK_ID);
if (!dataOnlookId) {
return;
}
const templateNode = decodeTemplateNode(dataOnlookId);
return templateNode;
}

export function encodeTemplateNode(templateNode: TemplateNode) {
const buffer = strToU8(JSON.stringify(templateNode));
const compressed = compressSync(buffer);
const binaryString = Array.from(new Uint8Array(compressed))
.map((byte) => String.fromCharCode(byte))
.join('');
const base64 = btoa(binaryString);
return base64;
}

export function decodeTemplateNode(base64: string): TemplateNode {
const buffer = new Uint8Array(
atob(base64)
.split('')
.map((c) => c.charCodeAt(0)),
);
const decompressed = decompressSync(buffer);
const JsonString = strFromU8(decompressed);
const templateNode = JSON.parse(JsonString) as TemplateNode;
return templateNode;
}

export function compareTemplateNodes(node1: TemplateNode, node2: TemplateNode): number {
if (node1.startTag.start.line < node2.startTag.start.line) {
return -1;
} else if (node1.startTag.start.line > node2.startTag.start.line) {
return 1;
} else {
if (node1.startTag.start.column < node2.startTag.start.column) {
return -1;
} else if (node1.startTag.start.column > node2.startTag.start.column) {
return 1;
} else {
return 0;
}
}
}
1 change: 1 addition & 0 deletions app/common/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface TemplateNode {
startTag: TemplateTag;
endTag: TemplateTag;
commit: string;
name?: string;
}

export interface CodeResult {
Expand Down
2 changes: 1 addition & 1 deletion app/electron/main/code/files.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { shell } from 'electron';
import { promises as fs } from 'fs';
import * as path from 'path';
import { compareTemplateNodes } from '/common/helpers';
import { compareTemplateNodes } from '/common/helpers/template';
import { CodeResult, TemplateNode } from '/common/models';

export async function readFile(filePath: string): Promise<string> {
Expand Down
26 changes: 2 additions & 24 deletions app/src/lib/editor/engine/code/index.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
import { CssToTailwindTranslator, ResultCode } from 'css-to-tailwind-translator';
import { compressSync, decompressSync, strFromU8, strToU8 } from 'fflate';
import { twMerge } from 'tailwind-merge';
import { WebviewManager } from '../webviews';
import { EditorAttributes, MainChannels } from '/common/constants';
import { querySelectorCommand } from '/common/helpers';
import { decodeTemplateNode } from '/common/helpers/template';
import { CodeResult, TemplateNode, WriteStyleParams } from '/common/models';

export class CodeManager {
constructor(private webviewManager: WebviewManager) {}

compress(templateNode: TemplateNode) {
const buffer = strToU8(JSON.stringify(templateNode));
const compressed = compressSync(buffer);
const binaryString = Array.from(new Uint8Array(compressed))
.map((byte) => String.fromCharCode(byte))
.join('');
const base64 = btoa(binaryString);
return base64;
}

decompress(base64: string): TemplateNode {
const buffer = new Uint8Array(
atob(base64)
.split('')
.map((c) => c.charCodeAt(0)),
);
const decompressed = decompressSync(buffer);
const JsonString = strFromU8(decompressed);
const templateNode = JSON.parse(JsonString) as TemplateNode;
return templateNode;
}

viewInEditor(templateNode: TemplateNode) {
window.api.invoke(MainChannels.OPEN_CODE_BLOCK, templateNode);
}
Expand Down Expand Up @@ -68,7 +46,7 @@ export class CodeManager {
if (!writeParam) {
writeParam = {
selector: selectorName,
templateNode: this.decompress(dataOnlookId),
templateNode: decodeTemplateNode(dataOnlookId),
tailwind: resultVal,
};
} else {
Expand Down
24 changes: 20 additions & 4 deletions app/src/routes/project/LayersPanel/LayersTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { NodeApi, Tree, TreeApi } from 'react-arborist';
import { useEditorEngine } from '..';
import NodeIcon from './NodeIcon';
import { EditorAttributes, WebviewChannels } from '/common/constants';
import { getUniqueSelector } from '/common/helpers';
import { capitalizeFirstLetter, getUniqueSelector } from '/common/helpers';
import { getTemplateNodeFromElement } from '/common/helpers/template';

export const IGNORE_TAGS = ['SCRIPT', 'STYLE'];

Expand Down Expand Up @@ -129,9 +130,24 @@ const LayersTab = observer(() => {
element.tagName.toLowerCase() === 'body'
? 'body'
: getUniqueSelector(element as HTMLElement, element.ownerDocument.body);

const textContent = Array.from(element.childNodes)
.map((node) => {
if (node.nodeType === Node.TEXT_NODE) {
return node.textContent;
}
})
.join(' ')
.trim()
.slice(0, 50);

const templateNode = getTemplateNodeFromElement(element);
const name = (templateNode?.name ? templateNode.name : element.tagName.toLowerCase()) || '';
const displayName = capitalizeFirstLetter(textContent ? `${name} ${textContent}` : name);

return {
id: selector,
name: element.tagName.toLowerCase(),
name: displayName,
children: children,
type: element.nodeType,
tagName: element.tagName,
Expand All @@ -149,7 +165,7 @@ const LayersTab = observer(() => {
onClick={() => node.select()}
onMouseOver={() => handleHoverNode(node)}
className={clsx(
'flex flex-row items-center h-6 rounded-sm',
'flex flex-row items-center h-6 rounded-sm cursor-pointer',
node.isSelected ? 'bg-bg-active text-white' : 'hover:bg-bg',
)}
>
Expand All @@ -168,7 +184,7 @@ const LayersTab = observer(() => {
)}
</span>
<NodeIcon iconClass="w-3 h-3 ml-1 mr-2" node={node.data} />
<span>{node.data.name}</span>
<span className="w-full truncate">{node.data.name}</span>
</div>
);
}
Expand Down
1 change: 0 additions & 1 deletion app/src/routes/project/SharePopover/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export default function SharePopover() {
const webview = editorEngine.webviews.selected[0];
const isLocalhost = webview.getURL().includes('localhost');
if (!isLocalhost) {
console.log('Not localhost');
return;
}
const webviewUrl = new URL(webview.getURL());
Expand Down
3 changes: 2 additions & 1 deletion app/src/routes/project/TopBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useEditorEngine } from '..';
import PublishModal from '../PublishModal';
import SharePopover from '../SharePopover';
import ModeToggle from './ModeToggle';
import { decodeTemplateNode } from '/common/helpers/template';
import { TemplateNode } from '/common/models';

const EditorTopBar = observer(() => {
Expand All @@ -16,7 +17,7 @@ const EditorTopBar = observer(() => {
if (editorEngine.state.selected.length > 0) {
const dataOnlook = editorEngine.state.selected[0].dataOnlookId;
if (dataOnlook) {
const selectedNode = editorEngine.code.decompress(dataOnlook);
const selectedNode = decodeTemplateNode(dataOnlook);
setSelectedNode(selectedNode);
} else {
setSelectedNode(null);
Expand Down
Binary file modified demos/babel/bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion demos/babel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"scripts": {
"dev": "rm -rf node_modules/.cache && npm run start",
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"build": "rm -rf node_modules/.cache && react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
Expand Down
43 changes: 22 additions & 21 deletions demos/babel/public/index.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--

<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Expand All @@ -24,12 +22,14 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
<title>React App</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>

<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
Expand All @@ -39,5 +39,6 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
</body>

</html>
26 changes: 16 additions & 10 deletions demos/babel/src/App.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
import logo from './logo.svg';
import './App.css';
import logo from './logo.svg';

function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
Check <code className='underline'>config-override.js</code> to see how this was set up.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<ReadDocs />
</header>
</div>
);
}

function ReadDocs() {
return (
<a
className="App-link"
href="https://github.com/onlook-dev/studio"
target="_blank"
rel="noopener noreferrer"
>
Read Onlook docs
</a>
);
}

export default App;
Binary file modified demos/next/bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion demos/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@
"tailwindcss": "^3.3.2",
"typescript": "^4.9.5"
}
}
}
2 changes: 1 addition & 1 deletion demos/webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@babel/core": "^7.23.6",
"@babel/preset-env": "^7.23.6",
"@babel/preset-react": "^7.23.3",
"@onlook/babel-plugin-react": "^2.0.5",
"@onlook/babel-plugin-react": "latest",
"babel-loader": "^9.1.3",
"css-loader": "^6.8.1",
"html-webpack-plugin": "^5.6.0",
Expand Down
3 changes: 1 addition & 2 deletions docs/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { cn } from "@/lib/utils"
export default function Home() {
return (
<main className="flex flex-col gap-[32px] h-screen items-center justify-center overflow-auto m-10">
<div className="container max-w-[64rem] flex-col items-center gap-4 text-center grid">
<div className="container max-w-[64rem] flex-col items-center gap-4 text-center flex">
<Logo width={80} height={80} />
<h1 className="text-2xl font-semibold sm:text-5xl md:text-6xl lg:text-7xl bg-[#05001f] text-[#dadde2]">
{siteConfig.name}
Expand All @@ -21,7 +21,6 @@ export default function Home() {
<Link
href={siteConfig.links.quickstart}
className={cn(buttonVariants({ size: "default" }))}>

Get Started
</Link>
<ModeToggle />
Expand Down
2 changes: 1 addition & 1 deletion plugins/babel/build/bundle.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion plugins/babel/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onlook/babel-plugin-react",
"version": "2.0.5",
"version": "2.0.6",
"main": "build/bundle.cjs",
"type": "module",
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion plugins/babel/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function getDataOnlookId(path: any, filename: string, root: string): string {
path: filename,
startTag,
endTag,
name: path.node.openingElement.name.name,
};

return compress(domNode);
}
Loading

0 comments on commit ca25e81

Please sign in to comment.