inkbridge 0.1.0-beta.12 → 0.1.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/bin/inkbridge.mjs +75 -11
- package/code.js +14141 -12192
- package/package.json +19 -15
- package/scanner/blob-placement-regression.ts +2 -2
- package/scanner/cli.ts +6 -6
- package/scanner/component-scanner.ts +719 -56
- package/scanner/css-token-reader-regression.ts +4 -4
- package/scanner/css-token-reader.ts +122 -3
- package/scanner/font-style-resolver-regression.ts +1 -1
- package/scanner/radial-gradient-regression.ts +1 -1
- package/scanner/transform-math-regression.ts +1 -1
- package/src/cache/index.ts +2 -0
- package/src/{component-defs.ts → components/component-defs.ts} +1 -1
- package/src/{component-gen.ts → components/component-gen.ts} +21 -9
- package/src/components/component-instance.ts +236 -0
- package/src/components/component-library.ts +52 -0
- package/src/{component-lookup.ts → components/component-lookup.ts} +1 -1
- package/src/components/index.ts +6 -0
- package/src/{symbol-instance-policy.ts → components/symbol-instance-policy.ts} +1 -1
- package/src/{design-system.ts → design-system/design-system.ts} +83 -43
- package/src/design-system/index.ts +13 -0
- package/src/design-system/preview-builder.ts +731 -0
- package/src/{render-context.ts → design-system/render-context.ts} +15 -3
- package/src/design-system/story-builder-context.ts +37 -0
- package/src/{story-builder.ts → design-system/story-builder.ts} +847 -1408
- package/src/{story-layout.ts → design-system/story-layout.ts} +2 -2
- package/src/{ui-builder.ts → design-system/ui-builder.ts} +953 -108
- package/src/{clip-path-decorative.ts → effects/clip-path-decorative.ts} +5 -4
- package/src/{icon-builder.ts → effects/icon-builder.ts} +18 -2
- package/src/effects/index.ts +5 -0
- package/src/effects/portal-panel.ts +365 -0
- package/src/{radial-gradient.ts → effects/radial-gradient.ts} +1 -1
- package/src/{github.ts → github/github.ts} +5 -6
- package/src/github/index.ts +1 -0
- package/src/layout/deferred-layout.ts +1007 -0
- package/src/layout/index.ts +6 -0
- package/src/{layout-parser.ts → layout/layout-parser.ts} +86 -13
- package/src/{layout-utils.ts → layout/layout-utils.ts} +14 -10
- package/src/{ring-utils.ts → layout/ring-utils.ts} +2 -2
- package/src/layout/size-utils.ts +143 -0
- package/src/{width-solver.ts → layout/width-solver.ts} +77 -22
- package/src/main.ts +101 -22
- package/src/{config.ts → plugin/config.ts} +1 -1
- package/src/{dev-server.ts → plugin/dev-server.ts} +1 -1
- package/src/plugin/index.ts +3 -0
- package/src/plugin/packs/index.ts +2 -0
- package/src/{pack-provider.ts → plugin/packs/pack-provider.ts} +5 -5
- package/src/{packs.ts → plugin/packs/packs.ts} +5 -4
- package/src/render-engine-version.ts +1 -1
- package/src/tailwind/index.ts +8 -0
- package/src/{jsx-utils.ts → tailwind/jsx-utils.ts} +109 -2
- package/src/{node-ir.ts → tailwind/node-ir.ts} +8 -10
- package/src/{responsive-analyzer.ts → tailwind/responsive-analyzer.ts} +32 -2
- package/src/{tailwind.ts → tailwind/tailwind.ts} +105 -628
- package/src/{utility-resolver.ts → tailwind/utility-resolver.ts} +1 -1
- package/src/text/index.ts +4 -0
- package/src/{inline-text.ts → text/inline-text.ts} +7 -7
- package/src/{text-builder.ts → text/text-builder.ts} +8 -4
- package/src/{text-line.ts → text/text-line.ts} +2 -2
- package/src/{change-detection.ts → tokens/change-detection.ts} +1 -1
- package/src/tokens/index.ts +6 -0
- package/src/{token-source.ts → tokens/token-source.ts} +3 -0
- package/src/{tokens.ts → tokens/tokens.ts} +15 -1
- package/src/{variables.ts → tokens/variables.ts} +357 -24
- package/templates/patch-tokens-route.ts +1 -1
- package/templates/scan-components-route.ts +1 -1
- package/ui.html +60 -4
- package/src/size-utils.ts +0 -71
- /package/src/{frame-cache.ts → cache/frame-cache.ts} +0 -0
- /package/src/{image-cache.ts → cache/image-cache.ts} +0 -0
- /package/src/{generated-node.ts → design-system/generated-node.ts} +0 -0
- /package/src/{blob-placement.ts → effects/blob-placement.ts} +0 -0
- /package/src/{class-utils.ts → tailwind/class-utils.ts} +0 -0
- /package/src/{state-analyzer.ts → tailwind/state-analyzer.ts} +0 -0
- /package/src/{transform-math.ts → tailwind/transform-math.ts} +0 -0
- /package/src/{font-style-resolver.ts → text/font-style-resolver.ts} +0 -0
- /package/src/{color-resolver.ts → tokens/color-resolver.ts} +0 -0
- /package/src/{colors.ts → tokens/colors.ts} +0 -0
package/README.md
CHANGED
|
@@ -34,9 +34,9 @@ pnpm exec inkbridge setup
|
|
|
34
34
|
|
|
35
35
|
`setup` does three things automatically:
|
|
36
36
|
- Creates `inkbridge.config.json` in your project root (auto-detects component paths from `.storybook/main.ts`)
|
|
37
|
-
- Creates the scanner API route at `src/app/api/
|
|
38
|
-
- Creates the token patch API route at `src/app/api/
|
|
39
|
-
- Adds `
|
|
37
|
+
- Creates the scanner API route at `src/app/api/inkbridge/scan-components/route.ts`
|
|
38
|
+
- Creates the token patch API route at `src/app/api/inkbridge/patch-tokens/route.ts`
|
|
39
|
+
- Adds `inkbridge:dev` and `inkbridge:scan` scripts to your `package.json`
|
|
40
40
|
|
|
41
41
|
### 2. Load the plugin in Figma Desktop
|
|
42
42
|
|
|
@@ -49,7 +49,7 @@ Figma remembers this path — you only do this once.
|
|
|
49
49
|
### 3. Start your dev server
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
pnpm
|
|
52
|
+
pnpm inkbridge:dev
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
The plugin auto-discovers your server on ports `4000`, `3000`, and `5173`.
|
|
@@ -62,7 +62,7 @@ The plugin auto-discovers your server on ports `4000`, `3000`, and `5173`.
|
|
|
62
62
|
|
|
63
63
|
### Generate Design System Page
|
|
64
64
|
|
|
65
|
-
1. Start dev server: `pnpm
|
|
65
|
+
1. Start dev server: `pnpm inkbridge:dev`
|
|
66
66
|
2. Open any Figma file
|
|
67
67
|
3. **Plugins → Development → Inkbridge → Generate Design System Page**
|
|
68
68
|
4. The plugin scans your Storybook stories and builds a "Design System" page with token tables, themed columns, grouped component sections, and responsive/state preview blocks where relevant
|
|
@@ -80,7 +80,7 @@ When a story instance uses non-default style/behavior props (for example `classN
|
|
|
80
80
|
### Manual scan
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
pnpm
|
|
83
|
+
pnpm inkbridge:scan
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
Writes `.inkbridge/component-definitions.json`. Useful for debugging scanner output.
|
|
@@ -137,19 +137,19 @@ The scanner re-reads this file on every scan — no server restart needed.
|
|
|
137
137
|
|
|
138
138
|
The plugin cannot connect to `localhost:4000`, `:3000`, or `:5173`.
|
|
139
139
|
|
|
140
|
-
- Make sure `pnpm
|
|
140
|
+
- Make sure `pnpm inkbridge:dev` is running
|
|
141
141
|
- Check the terminal for errors in the Next.js server
|
|
142
142
|
- Make sure you're using **Figma Desktop** — the browser version blocks localhost
|
|
143
143
|
|
|
144
144
|
### "Create Pull Request" does nothing / no PR opens
|
|
145
145
|
|
|
146
|
-
- Restart your dev server (`pnpm
|
|
146
|
+
- Restart your dev server (`pnpm inkbridge:dev`) so `/api/inkbridge/patch-tokens` is available
|
|
147
147
|
- Re-import the plugin from `node_modules/inkbridge/manifest.json` after updating
|
|
148
148
|
- Re-open the plugin and retry **Push Tokens to Code**
|
|
149
149
|
|
|
150
150
|
### Theme rename/new theme only commits one changed token
|
|
151
151
|
|
|
152
|
-
- Ensure your project route `src/app/api/
|
|
152
|
+
- Ensure your project route `src/app/api/inkbridge/patch-tokens/route.ts` is up to date:
|
|
153
153
|
|
|
154
154
|
```bash
|
|
155
155
|
pnpm exec inkbridge setup
|
|
@@ -197,8 +197,8 @@ Figma plugin (sandboxed)
|
|
|
197
197
|
└── code.js Main logic — cannot make network requests directly
|
|
198
198
|
└── ui.html Hidden iframe — relays all network requests to code.js
|
|
199
199
|
|
|
200
|
-
code.js → ui.html → localhost:4000/api/
|
|
201
|
-
→ localhost:4000/api/
|
|
200
|
+
code.js → ui.html → localhost:4000/api/inkbridge/scan-components
|
|
201
|
+
→ localhost:4000/api/inkbridge/patch-tokens
|
|
202
202
|
→ https://api.github.com
|
|
203
203
|
```
|
|
204
204
|
|
package/bin/inkbridge.mjs
CHANGED
|
@@ -38,6 +38,67 @@ function detectStorybookPaths(root) {
|
|
|
38
38
|
return [];
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Patch next.config.* to allow the Figma plugin UI (null origin) to fetch
|
|
43
|
+
// assets from the dev server. Without this, <Image> srcs, SVGs, etc. fail CORS.
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
async function patchNextConfig(root) {
|
|
46
|
+
const candidates = ["next.config.ts", "next.config.js", "next.config.mjs", "next.config.cjs"];
|
|
47
|
+
let configPath = null;
|
|
48
|
+
for (const candidate of candidates) {
|
|
49
|
+
const full = join(root, candidate);
|
|
50
|
+
if (existsSync(full)) { configPath = full; break; }
|
|
51
|
+
}
|
|
52
|
+
if (!configPath) {
|
|
53
|
+
console.log(" ~ next.config not found — skipping CORS headers patch");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const source = await readFile(configPath, "utf8");
|
|
58
|
+
if (source.includes("Access-Control-Allow-Origin")) {
|
|
59
|
+
console.log(" ~ next.config already exposes CORS headers, skipping");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const headersBlock = `
|
|
64
|
+
// Allow Figma plugin UI iframe (null origin) to fetch static assets
|
|
65
|
+
async headers() {
|
|
66
|
+
return [
|
|
67
|
+
{
|
|
68
|
+
source: "/:path*",
|
|
69
|
+
headers: [
|
|
70
|
+
{ key: "Access-Control-Allow-Origin", value: "*" },
|
|
71
|
+
{ key: "Access-Control-Allow-Methods", value: "GET" },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
},`;
|
|
76
|
+
|
|
77
|
+
// Inject right after the opening `{` of the config object. Matches either
|
|
78
|
+
// `const nextConfig: NextConfig = {` or `const nextConfig = {` or `module.exports = {`.
|
|
79
|
+
const patterns = [
|
|
80
|
+
/(const\s+\w+\s*(?::\s*\w+\s*)?=\s*)\{/,
|
|
81
|
+
/(module\.exports\s*=\s*)\{/,
|
|
82
|
+
/(export\s+default\s*)\{/,
|
|
83
|
+
];
|
|
84
|
+
let patched = null;
|
|
85
|
+
for (const re of patterns) {
|
|
86
|
+
const match = source.match(re);
|
|
87
|
+
if (!match) continue;
|
|
88
|
+
const idx = match.index + match[0].length;
|
|
89
|
+
patched = source.slice(0, idx) + headersBlock + source.slice(idx);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!patched) {
|
|
94
|
+
console.log(" ! could not locate config object in " + configPath + " — add CORS headers manually");
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
await writeFile(configPath, patched, "utf8");
|
|
99
|
+
console.log(" ✓ patched " + configPath.replace(root + "/", "") + " with CORS headers");
|
|
100
|
+
}
|
|
101
|
+
|
|
41
102
|
// ---------------------------------------------------------------------------
|
|
42
103
|
// postinstall — called automatically after `pnpm add -D inkbridge`
|
|
43
104
|
// ---------------------------------------------------------------------------
|
|
@@ -61,9 +122,9 @@ async function postinstall() {
|
|
|
61
122
|
// setup — patches package.json + creates scanner route
|
|
62
123
|
// ---------------------------------------------------------------------------
|
|
63
124
|
async function setup() {
|
|
64
|
-
const scanRouteDest = join(PROJECT_ROOT, "src/app/api/
|
|
125
|
+
const scanRouteDest = join(PROJECT_ROOT, "src/app/api/inkbridge/scan-components/route.ts");
|
|
65
126
|
const scanRouteSrc = join(PACKAGE_DIR, "templates/scan-components-route.ts");
|
|
66
|
-
const patchRouteDest = join(PROJECT_ROOT, "src/app/api/
|
|
127
|
+
const patchRouteDest = join(PROJECT_ROOT, "src/app/api/inkbridge/patch-tokens/route.ts");
|
|
67
128
|
const patchRouteSrc = join(PACKAGE_DIR, "templates/patch-tokens-route.ts");
|
|
68
129
|
const pkgPath = join(PROJECT_ROOT, "package.json");
|
|
69
130
|
|
|
@@ -89,19 +150,19 @@ async function setup() {
|
|
|
89
150
|
|
|
90
151
|
// 3. Copy scanner route
|
|
91
152
|
if (existsSync(scanRouteDest)) {
|
|
92
|
-
console.log(" ~ scanner route already exists, skipping: src/app/api/
|
|
153
|
+
console.log(" ~ scanner route already exists, skipping: src/app/api/inkbridge/scan-components/route.ts");
|
|
93
154
|
} else {
|
|
94
155
|
await mkdir(dirname(scanRouteDest), { recursive: true });
|
|
95
156
|
await copyFile(scanRouteSrc, scanRouteDest);
|
|
96
|
-
console.log(" ✓ created src/app/api/
|
|
157
|
+
console.log(" ✓ created src/app/api/inkbridge/scan-components/route.ts");
|
|
97
158
|
}
|
|
98
159
|
|
|
99
160
|
if (existsSync(patchRouteDest)) {
|
|
100
|
-
console.log(" ~ token patch route already exists, skipping: src/app/api/
|
|
161
|
+
console.log(" ~ token patch route already exists, skipping: src/app/api/inkbridge/patch-tokens/route.ts");
|
|
101
162
|
} else {
|
|
102
163
|
await mkdir(dirname(patchRouteDest), { recursive: true });
|
|
103
164
|
await copyFile(patchRouteSrc, patchRouteDest);
|
|
104
|
-
console.log(" ✓ created src/app/api/
|
|
165
|
+
console.log(" ✓ created src/app/api/inkbridge/patch-tokens/route.ts");
|
|
105
166
|
}
|
|
106
167
|
|
|
107
168
|
// 4. Patch package.json scripts
|
|
@@ -111,8 +172,8 @@ async function setup() {
|
|
|
111
172
|
const pkg = JSON.parse(await readFile(pkgPath, "utf8"));
|
|
112
173
|
pkg.scripts = pkg.scripts || {};
|
|
113
174
|
const toAdd = {
|
|
114
|
-
"
|
|
115
|
-
"
|
|
175
|
+
"inkbridge:dev": "next dev",
|
|
176
|
+
"inkbridge:scan": "tsx node_modules/inkbridge/scanner/cli.ts",
|
|
116
177
|
};
|
|
117
178
|
const added = [];
|
|
118
179
|
for (const [k, v] of Object.entries(toAdd)) {
|
|
@@ -129,7 +190,10 @@ async function setup() {
|
|
|
129
190
|
}
|
|
130
191
|
}
|
|
131
192
|
|
|
132
|
-
// 5.
|
|
193
|
+
// 5. Patch next.config to expose CORS headers for the Figma plugin iframe
|
|
194
|
+
await patchNextConfig(PROJECT_ROOT);
|
|
195
|
+
|
|
196
|
+
// 6. Print manifest path
|
|
133
197
|
const manifestPath = resolve(PROJECT_ROOT, "node_modules/inkbridge/manifest.json");
|
|
134
198
|
console.log("");
|
|
135
199
|
console.log(" Setup complete. Load the plugin in Figma Desktop:");
|
|
@@ -137,8 +201,8 @@ async function setup() {
|
|
|
137
201
|
console.log(` ${manifestPath}`);
|
|
138
202
|
console.log("");
|
|
139
203
|
console.log(" Start developing:");
|
|
140
|
-
console.log(" pnpm
|
|
141
|
-
console.log(" pnpm
|
|
204
|
+
console.log(" pnpm inkbridge:dev (starts Next.js dev server for scan + token patch routes)");
|
|
205
|
+
console.log(" pnpm inkbridge:scan (manually re-scan components)");
|
|
142
206
|
console.log("");
|
|
143
207
|
}
|
|
144
208
|
|