inkbridge 0.1.0-beta.11 → 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.
Files changed (81) hide show
  1. package/README.md +11 -11
  2. package/bin/inkbridge.mjs +75 -11
  3. package/code.js +14429 -10710
  4. package/package.json +12 -9
  5. package/scanner/blob-placement-regression.ts +2 -2
  6. package/scanner/cli.ts +6 -6
  7. package/scanner/component-scanner.ts +953 -66
  8. package/scanner/css-token-reader-regression.ts +4 -4
  9. package/scanner/css-token-reader.ts +122 -3
  10. package/scanner/font-style-resolver-regression.ts +1 -1
  11. package/scanner/radial-gradient-regression.ts +1 -1
  12. package/scanner/tailwind-parser.ts +6 -0
  13. package/scanner/transform-math-regression.ts +1 -1
  14. package/src/{frame-cache.ts → cache/frame-cache.ts} +3 -1
  15. package/src/cache/index.ts +2 -0
  16. package/src/{component-defs.ts → components/component-defs.ts} +1 -1
  17. package/src/{component-gen.ts → components/component-gen.ts} +111 -46
  18. package/src/components/component-instance.ts +236 -0
  19. package/src/components/component-library.ts +52 -0
  20. package/src/components/component-lookup.ts +154 -0
  21. package/src/components/index.ts +6 -0
  22. package/src/{symbol-instance-policy.ts → components/symbol-instance-policy.ts} +1 -1
  23. package/src/{design-system.ts → design-system/design-system.ts} +93 -50
  24. package/src/design-system/index.ts +13 -0
  25. package/src/design-system/preview-builder.ts +731 -0
  26. package/src/{render-context.ts → design-system/render-context.ts} +19 -3
  27. package/src/design-system/story-builder-context.ts +37 -0
  28. package/src/design-system/story-builder.ts +3730 -0
  29. package/src/{story-layout.ts → design-system/story-layout.ts} +2 -2
  30. package/src/{ui-builder.ts → design-system/ui-builder.ts} +1493 -167
  31. package/src/{clip-path-decorative.ts → effects/clip-path-decorative.ts} +5 -4
  32. package/src/{icon-builder.ts → effects/icon-builder.ts} +18 -2
  33. package/src/effects/index.ts +5 -0
  34. package/src/effects/portal-panel.ts +365 -0
  35. package/src/{radial-gradient.ts → effects/radial-gradient.ts} +1 -1
  36. package/src/{github.ts → github/github.ts} +5 -6
  37. package/src/github/index.ts +1 -0
  38. package/src/layout/deferred-layout.ts +1007 -0
  39. package/src/layout/index.ts +6 -0
  40. package/src/{layout-parser.ts → layout/layout-parser.ts} +86 -13
  41. package/src/{layout-utils.ts → layout/layout-utils.ts} +14 -10
  42. package/src/layout/ring-utils.ts +173 -0
  43. package/src/layout/size-utils.ts +143 -0
  44. package/src/{width-solver.ts → layout/width-solver.ts} +158 -29
  45. package/src/main.ts +223 -160
  46. package/src/{config.ts → plugin/config.ts} +1 -1
  47. package/src/{dev-server.ts → plugin/dev-server.ts} +1 -1
  48. package/src/plugin/index.ts +3 -0
  49. package/src/plugin/packs/index.ts +2 -0
  50. package/src/{pack-provider.ts → plugin/packs/pack-provider.ts} +5 -5
  51. package/src/{packs.ts → plugin/packs/packs.ts} +6 -3
  52. package/src/render-engine-version.ts +2 -0
  53. package/src/tailwind/index.ts +8 -0
  54. package/src/tailwind/jsx-utils.ts +309 -0
  55. package/src/{node-ir.ts → tailwind/node-ir.ts} +8 -10
  56. package/src/{responsive-analyzer.ts → tailwind/responsive-analyzer.ts} +32 -2
  57. package/src/{state-analyzer.ts → tailwind/state-analyzer.ts} +67 -4
  58. package/src/{tailwind.ts → tailwind/tailwind.ts} +128 -621
  59. package/src/{utility-resolver.ts → tailwind/utility-resolver.ts} +12 -2
  60. package/src/text/index.ts +4 -0
  61. package/src/{inline-text.ts → text/inline-text.ts} +7 -7
  62. package/src/{text-builder.ts → text/text-builder.ts} +8 -4
  63. package/src/{text-line.ts → text/text-line.ts} +2 -2
  64. package/src/{change-detection.ts → tokens/change-detection.ts} +1 -1
  65. package/src/tokens/index.ts +6 -0
  66. package/src/{token-source.ts → tokens/token-source.ts} +3 -0
  67. package/src/{tokens.ts → tokens/tokens.ts} +15 -1
  68. package/src/{variables.ts → tokens/variables.ts} +357 -24
  69. package/templates/patch-tokens-route.ts +1 -1
  70. package/templates/scan-components-route.ts +1 -1
  71. package/ui.html +60 -4
  72. package/src/component-lookup.ts +0 -82
  73. package/src/story-builder.ts +0 -3188
  74. /package/src/{image-cache.ts → cache/image-cache.ts} +0 -0
  75. /package/src/{generated-node.ts → design-system/generated-node.ts} +0 -0
  76. /package/src/{blob-placement.ts → effects/blob-placement.ts} +0 -0
  77. /package/src/{class-utils.ts → tailwind/class-utils.ts} +0 -0
  78. /package/src/{transform-math.ts → tailwind/transform-math.ts} +0 -0
  79. /package/src/{font-style-resolver.ts → text/font-style-resolver.ts} +0 -0
  80. /package/src/{color-resolver.ts → tokens/color-resolver.ts} +0 -0
  81. /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/figma/scan-components/route.ts`
38
- - Creates the token patch API route at `src/app/api/figma/patch-tokens/route.ts`
39
- - Adds `figma:dev` and `figma:scan` scripts to your `package.json`
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 figma:dev
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 figma:dev`
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 figma:scan
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 figma:dev` is running
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 figma:dev`) so `/api/figma/patch-tokens` is available
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/figma/patch-tokens/route.ts` is up to date:
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/figma/scan-components
201
- → localhost:4000/api/figma/patch-tokens
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/figma/scan-components/route.ts");
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/figma/patch-tokens/route.ts");
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/figma/scan-components/route.ts");
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/figma/scan-components/route.ts");
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/figma/patch-tokens/route.ts");
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/figma/patch-tokens/route.ts");
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
- "figma:dev": "next dev",
115
- "figma:scan": "tsx node_modules/inkbridge/scanner/cli.ts",
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. Print manifest path
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 figma:dev (starts Next.js dev server for scan + token patch routes)");
141
- console.log(" pnpm figma:scan (manually re-scan components)");
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