Skip to content

Commit

Permalink
feat(docs-figma-widget): init
Browse files Browse the repository at this point in the history
  • Loading branch information
junghyeonsu committed Mar 28, 2024
1 parent 01710ea commit d2bd0bd
Show file tree
Hide file tree
Showing 73 changed files with 1,582 additions and 5 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-7934e3c202-8.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"workspaces": [
"packages/*",
"packages/machines/*",
"docs"
"docs",
"tools/*"
],
"scripts": {
"build": "ultra -r build",
Expand Down
29 changes: 29 additions & 0 deletions tools/docs-figma-widget/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# figma-widget-template

## Description

A template for creating Figma widgets.

- UI (Plugin): React + Vite
- Main (Widget): TypeScript
- Linter: Biome

## Install

```bash
yarn install
```

## Usage

Development

```bash
yarn dev
```

Build

```bash
yarn build
```
126 changes: 126 additions & 0 deletions tools/docs-figma-widget/dist/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
"use strict";
(() => {
// ../../node_modules/@create-figma-plugin/utilities/lib/events.js
var eventHandlers = {};
var currentId = 0;
function on(name, handler) {
const id = `${currentId}`;
currentId += 1;
eventHandlers[id] = { handler, name };
return function() {
delete eventHandlers[id];
};
}
var emit = typeof window === "undefined" ? function(name, ...args) {
figma.ui.postMessage([name, ...args]);
} : function(name, ...args) {
window.parent.postMessage({
pluginMessage: [name, ...args]
}, "*");
};
function invokeEventHandler(name, args) {
let invoked = false;
for (const id in eventHandlers) {
if (eventHandlers[id].name === name) {
eventHandlers[id].handler.apply(null, args);
invoked = true;
}
}
if (invoked === false) {
throw new Error(`No event handler with name \`${name}\``);
}
}
if (typeof window === "undefined") {
figma.ui.onmessage = function(args) {
if (!Array.isArray(args)) {
return;
}
const [name, ...rest] = args;
if (typeof name !== "string") {
return;
}
invokeEventHandler(name, rest);
};
} else {
window.onmessage = function(event) {
if (typeof event.data.pluginMessage === "undefined") {
return;
}
const args = event.data.pluginMessage;
if (!Array.isArray(args)) {
return;
}
const [name, ...rest] = event.data.pluginMessage;
if (typeof name !== "string") {
return;
}
invokeEventHandler(name, rest);
};
}

// node_modules/@figmazing/resizable/dist/main.mjs
var o = "FIGMAZING:windowSize";
var r = () => on("FIGMAZING:RESIZE_WINDOW", (e, n) => {
figma.ui.resize(e, n), figma.clientStorage.setAsync(o, { w: e, h: n });
});
r();

// main/code.tsx
var { widget } = figma;
var { AutoLayout, Text, Input, SVG, useSyncedState, usePropertyMenu } = widget;
var ShevronRight = `
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5756 20.4241C11.3413 20.1898 11.3413 19.8099 11.5756 19.5756L18.5513 12.5999H3.99985C3.66848 12.5999 3.39985 12.3312 3.39985 11.9999C3.39985 11.6685 3.66848 11.3999 3.99985 11.3999H18.5513L11.5756 4.42412C11.3413 4.1898 11.3413 3.8099 11.5756 3.57559C11.8099 3.34127 12.1898 3.34127 12.4241 3.57559L20.4241 11.5756C20.6584 11.8099 20.6584 12.1898 20.4241 12.4241L12.4241 20.4241C12.1898 20.6584 11.8099 20.6584 11.5756 20.4241Z" fill="#212124"/>
</svg>
`;
var Widget = () => {
const [url, setUrl] = useSyncedState("url", "");
const [open, setOpen] = useSyncedState("open", false);
usePropertyMenu(
[
{
itemType: "toggle",
isToggled: open,
propertyName: "open",
tooltip: "\uC8FC\uC18C \uBCC0\uACBD\uD558\uAE30"
}
],
({ propertyName, propertyValue }) => {
if (propertyName === "open") {
setOpen(!open);
}
}
);
const handleTextEditEnd = (event) => {
setUrl(event.characters);
};
const openPluginWithUrl = () => {
figma.showUI(__html__, { width: 500, height: 500 });
emit("OPEN", { url });
};
return /* @__PURE__ */ figma.widget.h(AutoLayout, { direction: "vertical", verticalAlignItems: "center" }, /* @__PURE__ */ figma.widget.h(
AutoLayout,
{
direction: "horizontal",
horizontalAlignItems: "center",
verticalAlignItems: "center",
padding: 8,
onClick: () => new Promise(() => {
openPluginWithUrl();
})
},
/* @__PURE__ */ figma.widget.h(
Text,
{
fontSize: 20,
textDecoration: "underline",
fontFamily: "Noto Sans KR",
fontWeight: 400
},
"\uD53C\uADF8\uB9C8\uC5D0\uC11C \uAC00\uC774\uB4DC\uB77C\uC778 \uBCF4\uAE30"
),
/* @__PURE__ */ figma.widget.h(SVG, { src: ShevronRight })
), open && /* @__PURE__ */ figma.widget.h(AutoLayout, { direction: "vertical" }, /* @__PURE__ */ figma.widget.h(Input, { value: url, placeholder: "seed design url", onTextEditEnd: handleTextEditEnd, fontSize: 14 })));
};
widget.register(Widget);
})();
45 changes: 45 additions & 0 deletions tools/docs-figma-widget/dist/index.html

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions tools/docs-figma-widget/main/code.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* @see https://yuanqing.github.io/create-figma-plugin/utilities/
*/
import { emit, type EventHandler } from "@create-figma-plugin/utilities";
import "@figmazing/resizable/main";

/**
* @see https://www.figma.com/widget-docs/api/api-reference/
*/
const { widget } = figma;
const { AutoLayout, Text, Input, SVG, useSyncedState, usePropertyMenu } = widget;

export interface OpenHandler extends EventHandler {
name: "OPEN";
handler: ({ url }: { url: string }) => void;
}

const ShevronRight = `
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5756 20.4241C11.3413 20.1898 11.3413 19.8099 11.5756 19.5756L18.5513 12.5999H3.99985C3.66848 12.5999 3.39985 12.3312 3.39985 11.9999C3.39985 11.6685 3.66848 11.3999 3.99985 11.3999H18.5513L11.5756 4.42412C11.3413 4.1898 11.3413 3.8099 11.5756 3.57559C11.8099 3.34127 12.1898 3.34127 12.4241 3.57559L20.4241 11.5756C20.6584 11.8099 20.6584 12.1898 20.4241 12.4241L12.4241 20.4241C12.1898 20.6584 11.8099 20.6584 11.5756 20.4241Z" fill="#212124"/>
</svg>
`;

const Widget = () => {
const [url, setUrl] = useSyncedState("url", "");
const [open, setOpen] = useSyncedState("open", false);

usePropertyMenu(
[
{
itemType: "toggle",
isToggled: open,
propertyName: "open",
tooltip: "주소 변경하기",
},
],
({ propertyName, propertyValue }) => {
if (propertyName === "open") {
setOpen(!open);
}
},
);

const handleTextEditEnd = (event: TextEditEvent) => {
setUrl(event.characters);
};

const openPluginWithUrl = () => {
figma.showUI(__html__, { width: 500, height: 500 });
emit<OpenHandler>("OPEN", { url });
};

return (
<AutoLayout direction="vertical" verticalAlignItems="center">
<AutoLayout
direction="horizontal"
horizontalAlignItems="center"
verticalAlignItems="center"
padding={8}
onClick={() =>
new Promise(() => {
openPluginWithUrl();
})
}>
<Text
fontSize={20}
textDecoration="underline"
fontFamily="Noto Sans KR"
fontWeight={400}
>
피그마에서 가이드라인 보기
</Text>
<SVG src={ShevronRight} />
</AutoLayout>

{open && (
<AutoLayout direction="vertical">
<Input value={url} placeholder="seed design url" onTextEditEnd={handleTextEditEnd} fontSize={14} />
</AutoLayout>
)}
</AutoLayout>
);
};

widget.register(Widget);
17 changes: 17 additions & 0 deletions tools/docs-figma-widget/main/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "figma.widget.h",
"jsxFragmentFactory": "figma.widget.Fragment",
"target": "es2016",
"moduleResolution": "node",
"lib": [
"es2016"
],
"strict": true,
"types": [
"@figma/plugin-typings",
"@figma/widget-typings"
]
}
}
14 changes: 14 additions & 0 deletions tools/docs-figma-widget/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "Seed Docs Widget",
"id": "1355071316556147549",
"api": "1.0.0",
"widgetApi": "1.0.0",
"editorType": ["figma", "figjam"],
"containsWidget": true,
"main": "./dist/code.js",
"ui": "./dist/index.html",
"documentAccess": "dynamic-page",
"networkAccess": {
"allowedDomains": ["https://seed-design.io"]
}
}
38 changes: 38 additions & 0 deletions tools/docs-figma-widget/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@seed-design/docs-figma-widget",
"version": "1.0.0",
"private": true,
"author": "junghyeonsu <[email protected]>",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/daangn/seed-design",
"directory": "tools/docs-figma-widget"
},
"scripts": {
"dev": "concurrently \"yarn watch:ui\" \"yarn watch:main\"",
"build": "yarn build:ui && yarn build:main",
"watch:ui": "vite build --mode dev --watch --emptyOutDir=false",
"watch:main": "esbuild main/code.tsx --watch --bundle --outfile=dist/code.js --target=es6",
"build:ui": "vite build --mode prod --minify esbuild --emptyOutDir=false",
"build:main": "esbuild main/code.tsx --bundle --outfile=dist/code.js --target=es6"
},
"devDependencies": {
"@figma/plugin-typings": "^1.88.0",
"@figma/widget-typings": "^1.9.1",
"@types/react": "^18.2.72",
"@types/react-dom": "^18.2.22",
"@vitejs/plugin-react-refresh": "^1.3.6",
"concurrently": "^8.2.2",
"esbuild": "^0.20.2",
"typescript": "^5.4.3"
},
"dependencies": {
"@create-figma-plugin/utilities": "^3.1.0",
"@figmazing/resizable": "^0.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"vite": "^5.2.6",
"vite-plugin-singlefile": "^2.0.1"
}
}
30 changes: 30 additions & 0 deletions tools/docs-figma-widget/ui/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as React from "react";
import { Resizable } from "@figmazing/resizable";

export const App = () => {
const [url, setUrl] = React.useState("");

window.onmessage = (event) => {
const [type, data] = event.data.pluginMessage;
if (type === "OPEN") {
setUrl(data.url);
}
};

return (
<>
<iframe src={url} title={url} style={{ width: "100%", height: "100%" }} />
<Resizable
style={{
position: "fixed",
bottom: "1px",
right: "1px",
width: "16px",
height: "16px",
zIndex: 9999,
cursor: "nwse-resize",
}}
/>
</>
)
};
11 changes: 11 additions & 0 deletions tools/docs-figma-widget/ui/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
13 changes: 13 additions & 0 deletions tools/docs-figma-widget/ui/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import "./styles/reset.css";

import * as React from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App";

// biome-ignore lint/style/noNonNullAssertion: <explanation>
const root = createRoot(document.getElementById("root")!);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
Loading

0 comments on commit d2bd0bd

Please sign in to comment.