inkbridge 0.1.0-beta.2 → 0.1.0-beta.20

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 (171) hide show
  1. package/README.md +107 -25
  2. package/bin/inkbridge.mjs +299 -83
  3. package/code.js +40 -11802
  4. package/manifest.json +1 -0
  5. package/package.json +68 -23
  6. package/scanner/aspect-percent-position-regression.ts +237 -0
  7. package/scanner/aspect-ratio-regression.ts +90 -0
  8. package/scanner/blob-placement-regression.ts +2 -2
  9. package/scanner/block-cache-regression.ts +195 -0
  10. package/scanner/bundle-size-regression.ts +50 -0
  11. package/scanner/child-sizing-matrix-regression.ts +303 -0
  12. package/scanner/cli.ts +342 -13
  13. package/scanner/component-scanner.ts +1832 -155
  14. package/scanner/component-sections-regression.ts +198 -0
  15. package/scanner/compound-classes-lookup-regression.ts +163 -0
  16. package/scanner/css-token-reader-regression.ts +7 -6
  17. package/scanner/css-token-reader.ts +152 -31
  18. package/scanner/cva-jsx-child-fallback-regression.ts +98 -0
  19. package/scanner/cva-master-icon-regression.ts +315 -0
  20. package/scanner/data-attr-prop-alias-regression.ts +129 -0
  21. package/scanner/explicit-size-root-regression.ts +102 -0
  22. package/scanner/font-style-resolver-regression.ts +1 -1
  23. package/scanner/framework-adapter-shadcn-regression.ts +385 -0
  24. package/scanner/full-width-matrix-regression.ts +338 -0
  25. package/scanner/image-src-collector-regression.ts +204 -0
  26. package/scanner/inline-flex-regression.ts +235 -0
  27. package/scanner/instance-rendering-regression.ts +224 -0
  28. package/scanner/jsx-text-regression.ts +178 -0
  29. package/scanner/layout-alignment-regression.ts +108 -0
  30. package/scanner/layout-flex-regression.ts +90 -0
  31. package/scanner/layout-mode-regression.ts +71 -0
  32. package/scanner/layout-sizing-regression.ts +227 -0
  33. package/scanner/layout-spacing-regression.ts +135 -0
  34. package/scanner/percent-position-regression.ts +105 -0
  35. package/scanner/provider-cascade-regression.ts +224 -0
  36. package/scanner/provider-flatten-regression.ts +235 -0
  37. package/scanner/radial-gradient-regression.ts +1 -1
  38. package/scanner/render-prop-parser-regression.ts +161 -0
  39. package/scanner/ring-utility-regression.ts +132 -0
  40. package/scanner/sandbox-spread-regression.ts +125 -0
  41. package/scanner/selection-pressed-regression.ts +241 -0
  42. package/scanner/size-full-normalization-regression.ts +127 -0
  43. package/scanner/state-classification-regression.ts +137 -0
  44. package/scanner/story-diagnostics-regression.ts +216 -0
  45. package/scanner/story-dimensioning-regression.ts +298 -0
  46. package/scanner/story-render-strategy-regression.ts +205 -0
  47. package/scanner/stretch-to-parent-width-regression.ts +113 -0
  48. package/scanner/svg-fill-parent-regression.ts +98 -0
  49. package/scanner/svg-group-inheritance-regression.ts +166 -0
  50. package/scanner/svg-marker-inline-regression.ts +211 -0
  51. package/scanner/svg-marker-regression.ts +116 -0
  52. package/scanner/tailwind-parser.ts +8 -2
  53. package/scanner/text-resize-matrix-regression.ts +173 -0
  54. package/scanner/transform-math-regression.ts +1 -1
  55. package/scanner/types.ts +26 -2
  56. package/src/cache/frame-cache.ts +150 -0
  57. package/src/cache/index.ts +2 -0
  58. package/src/{component-defs.ts → components/component-defs.ts} +25 -10
  59. package/src/{component-gen.ts → components/component-gen.ts} +123 -56
  60. package/src/components/component-instance.ts +386 -0
  61. package/src/components/component-library.ts +44 -0
  62. package/src/components/component-lookup.ts +161 -0
  63. package/src/components/index.ts +7 -0
  64. package/src/components/scanner-types.ts +39 -0
  65. package/src/components/symbol-instance-policy.ts +312 -0
  66. package/src/design-system/block-cache.ts +130 -0
  67. package/src/design-system/component-sections.ts +107 -0
  68. package/src/design-system/cva-inference.ts +187 -0
  69. package/src/design-system/cva-master.ts +423 -0
  70. package/src/design-system/cva-utils.ts +29 -0
  71. package/src/design-system/design-system.ts +326 -0
  72. package/src/design-system/frame-stabilizers.ts +191 -0
  73. package/src/design-system/frame-utils.ts +46 -0
  74. package/src/design-system/generated-node.ts +84 -0
  75. package/src/design-system/icon-rendering.ts +229 -0
  76. package/src/design-system/index.ts +13 -0
  77. package/src/design-system/instance-rendering.ts +307 -0
  78. package/src/design-system/master-shared.ts +133 -0
  79. package/src/design-system/node-helpers.ts +223 -0
  80. package/src/design-system/node-variants.ts +196 -0
  81. package/src/design-system/non-cva-master.ts +104 -0
  82. package/src/design-system/portal-handling.ts +138 -0
  83. package/src/design-system/preview-builder.ts +769 -0
  84. package/src/{render-context.ts → design-system/render-context.ts} +32 -6
  85. package/src/design-system/render-prop-parser.ts +50 -0
  86. package/src/design-system/responsive-resolver.ts +180 -0
  87. package/src/design-system/selectable-state.ts +157 -0
  88. package/src/design-system/state-master.ts +245 -0
  89. package/src/design-system/state-utils.ts +15 -0
  90. package/src/design-system/story-builder-context.ts +40 -0
  91. package/src/design-system/story-builder.ts +1272 -0
  92. package/src/design-system/story-diagnostics.ts +80 -0
  93. package/src/design-system/story-dimensioning.ts +272 -0
  94. package/src/design-system/story-frames.ts +400 -0
  95. package/src/design-system/story-instance.ts +333 -0
  96. package/src/{story-layout.ts → design-system/story-layout.ts} +2 -2
  97. package/src/design-system/story-render-strategy.ts +150 -0
  98. package/src/design-system/story-tree-search.ts +110 -0
  99. package/src/design-system/symbol-fallback.ts +89 -0
  100. package/src/design-system/symbol-source.ts +172 -0
  101. package/src/design-system/table-helpers.ts +56 -0
  102. package/src/design-system/tag-predicates.ts +99 -0
  103. package/src/design-system/theme-context.ts +52 -0
  104. package/src/design-system/typography.ts +100 -0
  105. package/src/design-system/ui-builder.ts +2566 -0
  106. package/src/{clip-path-decorative.ts → effects/clip-path-decorative.ts} +11 -11
  107. package/src/effects/icon-builder.ts +1074 -0
  108. package/src/effects/index.ts +5 -0
  109. package/src/effects/portal-panel.ts +369 -0
  110. package/src/{radial-gradient.ts → effects/radial-gradient.ts} +1 -1
  111. package/src/framework-adapters/index.ts +34 -0
  112. package/src/framework-adapters/shadcn.ts +525 -0
  113. package/src/{github.ts → github/github.ts} +46 -21
  114. package/src/github/index.ts +1 -0
  115. package/src/layout/deferred-layout.ts +1370 -0
  116. package/src/layout/index.ts +24 -0
  117. package/src/layout/layout-parser.ts +375 -0
  118. package/src/{layout-utils.ts → layout/layout-utils.ts} +22 -17
  119. package/src/layout/parser/alignment.ts +54 -0
  120. package/src/layout/parser/flex.ts +59 -0
  121. package/src/layout/parser/index.ts +65 -0
  122. package/src/layout/parser/ir.ts +80 -0
  123. package/src/layout/parser/layout-mode.ts +57 -0
  124. package/src/layout/parser/sizing.ts +241 -0
  125. package/src/layout/parser/spacing-scale.ts +78 -0
  126. package/src/layout/parser/spacing.ts +134 -0
  127. package/src/layout/ring-utils.ts +171 -0
  128. package/src/layout/size-utils.ts +143 -0
  129. package/src/layout/text-resize-decision.ts +51 -0
  130. package/src/{width-solver.ts → layout/width-solver.ts} +168 -37
  131. package/src/main.ts +444 -162
  132. package/src/{config.ts → plugin/config.ts} +12 -12
  133. package/src/{dev-server.ts → plugin/dev-server.ts} +3 -3
  134. package/src/plugin/image-src-collector.ts +52 -0
  135. package/src/plugin/index.ts +3 -0
  136. package/src/plugin/packs/index.ts +2 -0
  137. package/src/{pack-provider.ts → plugin/packs/pack-provider.ts} +12 -12
  138. package/src/{packs.ts → plugin/packs/packs.ts} +22 -17
  139. package/src/render-engine-version.ts +2 -0
  140. package/src/{class-utils.ts → tailwind/class-utils.ts} +33 -6
  141. package/src/tailwind/index.ts +8 -0
  142. package/src/tailwind/jsx-utils.ts +310 -0
  143. package/src/{node-ir.ts → tailwind/node-ir.ts} +36 -19
  144. package/src/{responsive-analyzer.ts → tailwind/responsive-analyzer.ts} +32 -2
  145. package/src/{state-analyzer.ts → tailwind/state-analyzer.ts} +71 -5
  146. package/src/{tailwind.ts → tailwind/tailwind.ts} +415 -673
  147. package/src/{utility-resolver.ts → tailwind/utility-resolver.ts} +27 -6
  148. package/src/{font-style-resolver.ts → text/font-style-resolver.ts} +0 -2
  149. package/src/text/index.ts +4 -0
  150. package/src/{inline-text.ts → text/inline-text.ts} +13 -13
  151. package/src/{text-builder.ts → text/text-builder.ts} +24 -7
  152. package/src/{text-line.ts → text/text-line.ts} +2 -2
  153. package/src/{change-detection.ts → tokens/change-detection.ts} +12 -12
  154. package/src/{color-resolver.ts → tokens/color-resolver.ts} +1 -6
  155. package/src/{colors.ts → tokens/colors.ts} +13 -6
  156. package/src/tokens/index.ts +6 -0
  157. package/src/{token-source.ts → tokens/token-source.ts} +4 -1
  158. package/src/{tokens.ts → tokens/tokens.ts} +106 -18
  159. package/src/{variables.ts → tokens/variables.ts} +447 -102
  160. package/templates/patch-tokens-route.ts +25 -6
  161. package/templates/scan-components-route.ts +15 -4
  162. package/ui.html +485 -37
  163. package/src/component-lookup.ts +0 -82
  164. package/src/design-system.ts +0 -59
  165. package/src/icon-builder.ts +0 -607
  166. package/src/layout-parser.ts +0 -667
  167. package/src/story-builder.ts +0 -1706
  168. package/src/ui-builder.ts +0 -1996
  169. /package/src/{image-cache.ts → cache/image-cache.ts} +0 -0
  170. /package/src/{blob-placement.ts → effects/blob-placement.ts} +0 -0
  171. /package/src/{transform-math.ts → tailwind/transform-math.ts} +0 -0
package/README.md CHANGED
@@ -1,12 +1,18 @@
1
+ <img src="https://inkbridge.ink/inkbridge-logo.png" alt="Inkbridge" width="80" />
2
+
1
3
  # Inkbridge
2
4
 
3
- Generates native Figma frames from your Tailwind React components and syncs design tokens back to your codebase via GitHub PRs.
5
+ Generates native Figma frames and reusable Figma component instances from your Tailwind React components, and syncs design tokens back to your codebase via GitHub PRs.
6
+
7
+ <img src="https://inkbridge.ink/docs/mediacards-figma.png" alt="An Inkbridge-generated Figma page showing component variants rendered as native Figma frames" />
8
+
9
+ > Read the methodology behind this — stories as the single source of truth between design and code: [inkbridge.ink/methodology](https://inkbridge.ink/methodology). Browse the full docs at [inkbridge.ink/docs](https://inkbridge.ink/docs).
4
10
 
5
11
  ## What it does
6
12
 
7
13
  | Feature | Description |
8
14
  |---|---|
9
- | **Generate Design System Page** | Scans your Storybook stories and builds a pixel-accurate Figma page from your Tailwind classes |
15
+ | **Generate Design System Page** | Scans your Storybook stories and builds a pixel-accurate Figma page from your Tailwind classes, including reusable component instances for symbol candidates (CVA and non-CVA) |
10
16
  | **Push to Code** | Creates a GitHub PR from Figma token changes. Source can be CSS-first (`auto`/`css`) or DTCG (`dtcg`). |
11
17
  | **Detect & Sync Changes** | Detects class-level changes in Figma frames and proposes them as a GitHub PR |
12
18
  | **Dev Mode codegen** | Shows Tailwind class names for any selected node in Figma Dev Mode |
@@ -17,7 +23,7 @@ Generates native Figma frames from your Tailwind React components and syncs desi
17
23
 
18
24
  - **Figma Desktop** (not the browser — the plugin needs localhost access)
19
25
  - **Node.js 18+** and **pnpm**
20
- - A project with Next.js, Tailwind CSS, and Storybook stories (`.stories.tsx`)
26
+ - A project with Next.js, Tailwind CSS, and Storybook stories (`.stories.tsx` or `.stories.ts`)
21
27
 
22
28
  ---
23
29
 
@@ -30,11 +36,15 @@ pnpm add -D inkbridge
30
36
  pnpm exec inkbridge setup
31
37
  ```
32
38
 
33
- `setup` does three things automatically:
34
- - Creates `inkbridge.config.json` in your project root (auto-detects component paths from `.storybook/main.ts`)
35
- - Creates the scanner API route at `src/app/api/figma/scan-components/route.ts`
36
- - Creates the token patch API route at `src/app/api/figma/patch-tokens/route.ts`
37
- - Adds `figma:dev` and `figma:scan` scripts to your `package.json`
39
+ `pnpm exec inkbridge setup` is the only required step after install. It prints exactly what it will change before writing anything (run with `--dry-run` to preview without applying):
40
+
41
+ - Creates `inkbridge.config.json` in your project root (auto-detects component paths from `.storybook/main.*`)
42
+ - Creates the scanner API route at `src/app/api/inkbridge/scan-components/route.ts`
43
+ - Creates the token patch API route at `src/app/api/inkbridge/patch-tokens/route.ts`
44
+ - Adds `inkbridge:dev` and `inkbridge:scan` scripts to your `package.json`
45
+ - Adds `headers()` to your `next.config.*` exposing CORS on `/api/inkbridge/:path*` so the Figma plugin iframe can reach those routes (scoped — your other routes are untouched)
46
+
47
+ Inkbridge does not modify your ESLint config or any other tooling. The recommended `react/forbid-dom-props` rule for inline styles is suggested in "Recommended lint rules" below, but never written by setup.
38
48
 
39
49
  ### 2. Load the plugin in Figma Desktop
40
50
 
@@ -47,7 +57,7 @@ Figma remembers this path — you only do this once.
47
57
  ### 3. Start your dev server
48
58
 
49
59
  ```bash
50
- pnpm figma:dev
60
+ pnpm inkbridge:dev
51
61
  ```
52
62
 
53
63
  The plugin auto-discovers your server on ports `4000`, `3000`, and `5173`.
@@ -60,24 +70,32 @@ The plugin auto-discovers your server on ports `4000`, `3000`, and `5173`.
60
70
 
61
71
  ### Generate Design System Page
62
72
 
63
- 1. Start dev server: `pnpm figma:dev`
73
+ 1. Start dev server: `pnpm inkbridge:dev`
64
74
  2. Open any Figma file
65
75
  3. **Plugins → Development → Inkbridge → Generate Design System Page**
66
- 4. The plugin scans your Storybook stories and builds a "Design System" page
76
+ 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
67
77
 
68
78
  Component data is always scanned live on every run — never stale. Re-run at any time to pick up changes.
69
79
 
80
+ For symbol candidates, the generated page renders real Figma component instances instead of only flattened frames:
81
+
82
+ - CVA components (for example `Button`) render as variant-aware instances.
83
+ - Non-CVA reusable components (for example `Card` compounds) can render as instances too.
84
+ - For compound instances, story text is applied by slot-aware overrides (for example title/description/content) when possible.
85
+
86
+ When a story instance uses non-default style/behavior props (for example `className`, `disabled`, `aria-invalid`, or unknown props), rendering falls back to direct frames for visual correctness.
87
+
70
88
  ### Manual scan
71
89
 
72
90
  ```bash
73
- pnpm figma:scan
91
+ pnpm inkbridge:scan
74
92
  ```
75
93
 
76
94
  Writes `.inkbridge/component-definitions.json`. Useful for debugging scanner output.
77
95
 
78
- ### Push to Code (Pro)
96
+ ### Push to Code
79
97
 
80
- Requires a Pro license and GitHub configuration.
98
+ Sync token edits from Figma back to your codebase as a GitHub PR.
81
99
 
82
100
  1. **Plugins → Development → Inkbridge → Settings**
83
101
  2. Fill in:
@@ -91,7 +109,6 @@ Requires a Pro license and GitHub configuration.
91
109
  - **Allow New Tokens from Figma** — optional; permits creating new token keys on push (off by default)
92
110
  - **New Token Prefixes** — optional comma-separated allowlist (for example `chart-, brand-`)
93
111
  - **GitHub token** — a [fine-grained PAT](https://github.com/settings/tokens?type=beta) with `Contents` and `Pull requests` read & write
94
- - **License key** — from your Inkbridge account
95
112
  3. **Save Settings**
96
113
  4. **Plugins → Development → Inkbridge → Push to Code**
97
114
  5. Enter a commit message and click **Push Tokens to Code** (it auto-detects token changes and opens the PR step)
@@ -115,31 +132,95 @@ Edit `inkbridge.config.json` in your project root:
115
132
  |---|---|---|
116
133
  | `componentPaths` | auto-detected | Directories to scan for components |
117
134
  | `exclude` | `[]` | Directory or file names to skip |
118
- | `onlyWithStories` | `true` | Only include components with a `.stories.tsx` file |
135
+ | `onlyWithStories` | `true` | Only include components with a `.stories.tsx` or `.stories.ts` file |
119
136
 
120
137
  The scanner re-reads this file on every scan — no server restart needed.
121
138
 
122
139
  ---
123
140
 
141
+ ## Supported styling
142
+
143
+ Inkbridge reads styling from **Tailwind class names** (`className="…"`).
144
+ The Figma renderer is built to handle the breadth of Tailwind utilities:
145
+ flex / grid layouts, responsive variants (`sm:`, `md:`, `lg:`, …),
146
+ arbitrary values (`left-[18.33%]`, `aspect-5/3`), color / spacing
147
+ tokens, and SVG attribute inheritance.
148
+
149
+ ### What's not supported yet
150
+
151
+ - **Inline `style={{ … }}` props.** Currently ignored by the renderer.
152
+ If you set `style={{ color: '#0a0', padding: 8 }}` on an element, the
153
+ Figma rendering will use whatever the Tailwind class list says — your
154
+ inline overrides won't be applied. Use Tailwind utilities or arbitrary
155
+ values instead (`text-[#0a0] p-2`). A consumer-side ESLint rule
156
+ (`react/forbid-dom-props` + `react/forbid-component-props`) is
157
+ recommended to catch this — see "Recommended lint rules" below.
158
+
159
+ - **CSS variables in arbitrary classes** (`text-[var(--accent)]`) —
160
+ not yet resolved through the scanner's token map; the literal CSS
161
+ variable name reaches Figma and renders as black. Use a Tailwind
162
+ token alias (`text-accent`) instead.
163
+
164
+ - **`<g transform="…">`** — the transform isn't composed onto child
165
+ positions yet, so paths inside a transformed group render at their
166
+ pre-transform coordinates.
167
+
168
+ - **`clip-path` / `mask` on `<g>`** — clipping is honored at the
169
+ element level (`overflow-hidden`, `clip-path-decorative-*`) but not
170
+ via SVG `<g clip-path="url(…)">`.
171
+
172
+ These are tracked as universality enhancements. File an issue if one
173
+ blocks you and we'll prioritize.
174
+
175
+ ### Recommended lint rules
176
+
177
+ Until inline-style support lands, add these rules to your project's
178
+ ESLint config so you don't accidentally rely on patterns the plugin
179
+ ignores:
180
+
181
+ ```json
182
+ {
183
+ "rules": {
184
+ "react/forbid-dom-props": ["error", {
185
+ "forbid": [{
186
+ "propName": "style",
187
+ "message": "Use Tailwind classes — Inkbridge ignores inline styles."
188
+ }]
189
+ }],
190
+ "react/forbid-component-props": ["error", {
191
+ "forbid": [{
192
+ "propName": "style",
193
+ "message": "Use Tailwind classes — Inkbridge ignores inline styles."
194
+ }]
195
+ }]
196
+ }
197
+ }
198
+ ```
199
+
200
+ Skip this rule on any component where Figma rendering doesn't matter
201
+ (e.g. animation-only effects).
202
+
203
+ ---
204
+
124
205
  ## Troubleshooting
125
206
 
126
207
  ### "Dev server not reachable"
127
208
 
128
209
  The plugin cannot connect to `localhost:4000`, `:3000`, or `:5173`.
129
210
 
130
- - Make sure `pnpm figma:dev` is running
211
+ - Make sure `pnpm inkbridge:dev` is running
131
212
  - Check the terminal for errors in the Next.js server
132
213
  - Make sure you're using **Figma Desktop** — the browser version blocks localhost
133
214
 
134
215
  ### "Create Pull Request" does nothing / no PR opens
135
216
 
136
- - Restart your dev server (`pnpm figma:dev`) so `/api/figma/patch-tokens` is available
217
+ - Restart your dev server (`pnpm inkbridge:dev`) so `/api/inkbridge/patch-tokens` is available
137
218
  - Re-import the plugin from `node_modules/inkbridge/manifest.json` after updating
138
219
  - Re-open the plugin and retry **Push Tokens to Code**
139
220
 
140
221
  ### Theme rename/new theme only commits one changed token
141
222
 
142
- - Ensure your project route `src/app/api/figma/patch-tokens/route.ts` is up to date:
223
+ - Ensure your project route `src/app/api/inkbridge/patch-tokens/route.ts` is up to date:
143
224
 
144
225
  ```bash
145
226
  pnpm exec inkbridge setup
@@ -184,15 +265,16 @@ Component data is always scanned live — you only need to update when a new `in
184
265
 
185
266
  ```
186
267
  Figma plugin (sandboxed)
187
- └── code.js Main logic — cannot make network requests directly
188
- └── ui.html Hidden iframe — relays all network requests to code.js
268
+ └── code.js Main logic — no direct network access
269
+ └── ui.html Hidden iframe — relays I/O for code.js
189
270
 
190
- code.js ui.html localhost:4000/api/figma/scan-components
191
- localhost:4000/api/figma/patch-tokens
192
- https://api.github.com
271
+ code.js ui.html localhost:4000/api/inkbridge/scan-components
272
+ localhost:4000/api/inkbridge/patch-tokens
273
+ https://api.github.com
193
274
  ```
194
275
 
195
- All network I/O is relayed through the UI iframe via `postMessage` due to the Figma sandbox restriction.
276
+ All network I/O is relayed through the UI iframe via `postMessage`
277
+ because the Figma plugin sandbox can't make requests directly.
196
278
 
197
279
  ---
198
280