diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cf9ef6b..caa1c73 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -95,7 +95,7 @@ jobs:
set -euo pipefail
VERSION="${{ needs.ci.outputs.version }}"
- PLUGIN_DIR="figma-plugin"
+ PLUGIN_DIR="src/figma-plugin"
echo "Publishing Figma plugin v${VERSION} (plugin id: ${FIGMA_PLUGIN_ID})"
diff --git a/README.md b/README.md
index 7751c85..8141492 100644
--- a/README.md
+++ b/README.md
@@ -455,7 +455,7 @@ $ pnpm i
1. `pnpm run build-figma`
2. In Figma: Plugins → Development → Import plugin from manifest…
-3. Select `figma-plugin/manifest.json`
+3. Select `src/figma-plugin/manifest.json`
## Validation
diff --git a/package.json b/package.json
index 2560f3e..f82ffad 100644
--- a/package.json
+++ b/package.json
@@ -105,7 +105,7 @@
"local-release": "pnpm run lgtm && changeset version && changeset publish",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
- "build-figma": "vite build --config figma-plugin/vite.config.ts && tsup --config figma-plugin/tsup.config.ts",
+ "build-figma": "vite build --config src/figma-plugin/vite.config.ts && tsup --config src/figma-plugin/tsup.config.ts",
"chromatic": "chromatic --project-token $CHROMATIC_PROJECT_TOKEN",
"prepare": "pnpm run pretest && husky",
"changeset": "pnpm exec changeset"
diff --git a/figma-plugin/src/code.ts b/src/figma-plugin/code.ts
similarity index 72%
rename from figma-plugin/src/code.ts
rename to src/figma-plugin/code.ts
index 53d42f5..9f9aa0e 100644
--- a/figma-plugin/src/code.ts
+++ b/src/figma-plugin/code.ts
@@ -1,6 +1,6 @@
///
-import type { FigmaVariable } from "../../src/lib/builder";
+import type { FigmaVariable, FigmaVariableValue } from "../lib/builder";
import { COLLECTION_NAME } from "./constants";
// ─── Plugin entry point ─────────────────────────────────────────────────
@@ -37,14 +37,18 @@ async function findOrCreateCollection(name: string) {
function ensureModes(collection: VariableCollection, ...modeNames: string[]) {
const result: Record = {};
for (let i = 0; i < modeNames.length; i++) {
- const existing = collection.modes.find((m) => m.name === modeNames[i]);
+ const name = modeNames[i];
+ if (!name) continue;
+ const existing = collection.modes.find((m) => m.name === name);
if (existing) {
- result[modeNames[i]] = existing.modeId;
+ result[name] = existing.modeId;
} else if (i === 0 && collection.modes.length === 1) {
- collection.renameMode(collection.modes[0].modeId, modeNames[i]);
- result[modeNames[i]] = collection.modes[0].modeId;
+ const first = collection.modes[0];
+ if (!first) continue;
+ collection.renameMode(first.modeId, name);
+ result[name] = first.modeId;
} else {
- result[modeNames[i]] = collection.addMode(modeNames[i]);
+ result[name] = collection.addMode(name);
}
}
return result;
@@ -64,6 +68,28 @@ async function findOrCreateVariable(
// ─── Sync logic ─────────────────────────────────────────────────────────
+function setModeValue(
+ variable: Variable,
+ modeId: string,
+ value: FigmaVariableValue,
+ varMap: Record,
+) {
+ if ("alias" in value) {
+ const target = varMap[value.alias];
+ if (target) {
+ variable.setValueForMode(
+ modeId,
+ figma.variables.createVariableAlias(target),
+ );
+ } else {
+ console.warn(`Alias target not found: ${value.alias}`);
+ variable.setValueForMode(modeId, { r: 0, g: 0, b: 0, a: 1 });
+ }
+ } else {
+ variable.setValueForMode(modeId, value);
+ }
+}
+
async function syncVariables(variables: FigmaVariable[]) {
const collection = await findOrCreateCollection(COLLECTION_NAME);
const modes = ensureModes(collection, "Light", "Dark");
@@ -77,28 +103,14 @@ async function syncVariables(variables: FigmaVariable[]) {
// Set values and metadata
for (const v of variables) {
const variable = varMap[v.path];
+ if (!variable) continue;
if (v.description) variable.description = v.description;
if (v.scopes) variable.scopes = v.scopes as VariableScope[];
for (const [modeName, modeId] of Object.entries(modes)) {
const value = v.values[modeName];
- if (!value) continue;
-
- if ("alias" in value) {
- const target = varMap[value.alias];
- if (target) {
- variable.setValueForMode(
- modeId,
- figma.variables.createVariableAlias(target),
- );
- } else {
- console.warn(`Alias target not found: ${value.alias}`);
- variable.setValueForMode(modeId, { r: 0, g: 0, b: 0, a: 1 });
- }
- } else {
- variable.setValueForMode(modeId, value);
- }
+ if (value) setModeValue(variable, modeId, value, varMap);
}
}
diff --git a/figma-plugin/src/constants.ts b/src/figma-plugin/constants.ts
similarity index 100%
rename from figma-plugin/src/constants.ts
rename to src/figma-plugin/constants.ts
diff --git a/figma-plugin/src/index.html b/src/figma-plugin/index.html
similarity index 100%
rename from figma-plugin/src/index.html
rename to src/figma-plugin/index.html
diff --git a/figma-plugin/src/main.css b/src/figma-plugin/main.css
similarity index 100%
rename from figma-plugin/src/main.css
rename to src/figma-plugin/main.css
diff --git a/figma-plugin/src/main.tsx b/src/figma-plugin/main.tsx
similarity index 80%
rename from figma-plugin/src/main.tsx
rename to src/figma-plugin/main.tsx
index 22fbeaf..f695310 100644
--- a/figma-plugin/src/main.tsx
+++ b/src/figma-plugin/main.tsx
@@ -1,13 +1,13 @@
import { useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
-import { Fab } from "../../src/components/m3/Fab";
-import { FlowfieldSt } from "../../src/Flowfield.stories";
-import { FlowfieldScene } from "../../src/Flowfield.stories.helpers";
-import { Mcu } from "../../src/Mcu";
-import { useMcu } from "../../src/Mcu.context";
+import { Fab } from "../components/m3/Fab";
+import { FlowfieldSt } from "../Flowfield.stories";
+import { FlowfieldScene } from "../Flowfield.stories.helpers";
+import { Mcu } from "../Mcu";
+import { useMcu } from "../Mcu.context";
-import { TooltipProvider } from "../../src/components/ui/tooltip";
-import "../../src/styles/globals.css";
+import { TooltipProvider } from "../components/ui/tooltip";
+import "../styles/globals.css";
import "./main.css";
function SyncButton() {
@@ -73,4 +73,5 @@ function App() {
);
}
-createRoot(document.getElementById("root")!).render();
+const root = document.getElementById("root");
+if (root) createRoot(root).render();
diff --git a/figma-plugin/manifest.json b/src/figma-plugin/manifest.json
similarity index 100%
rename from figma-plugin/manifest.json
rename to src/figma-plugin/manifest.json
diff --git a/figma-plugin/tsup.config.ts b/src/figma-plugin/tsup.config.ts
similarity index 69%
rename from figma-plugin/tsup.config.ts
rename to src/figma-plugin/tsup.config.ts
index b8673a1..3f37c4e 100644
--- a/figma-plugin/tsup.config.ts
+++ b/src/figma-plugin/tsup.config.ts
@@ -1,11 +1,11 @@
import { defineConfig } from "tsup";
export default defineConfig({
- entryPoints: ["figma-plugin/src/code.ts"],
+ entryPoints: ["src/figma-plugin/code.ts"],
format: ["iife"],
target: "es2015",
dts: false,
- outDir: "figma-plugin/dist",
+ outDir: "src/figma-plugin/dist",
clean: false,
outExtension: () => ({ js: ".js" }),
});
diff --git a/figma-plugin/vite.config.ts b/src/figma-plugin/vite.config.ts
similarity index 84%
rename from figma-plugin/vite.config.ts
rename to src/figma-plugin/vite.config.ts
index 960fcf4..a166326 100644
--- a/figma-plugin/vite.config.ts
+++ b/src/figma-plugin/vite.config.ts
@@ -7,11 +7,11 @@ import tsconfigPaths from "vite-tsconfig-paths";
const dir = import.meta.dirname;
export default defineConfig({
- root: resolve(dir, "src"),
+ root: dir,
plugins: [
react(),
viteSingleFile(),
- tsconfigPaths({ root: resolve(dir, "..") }),
+ tsconfigPaths({ root: resolve(dir, "../..") }),
],
build: {
outDir: resolve(dir, "dist"),