inkbridge 0.1.0-beta.20 → 0.1.0-beta.22
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 +2 -1
- package/bin/inkbridge.mjs +64 -9
- package/code.js +11 -11
- package/package.json +11 -2
- package/scanner/adapter-utils-regression.ts +159 -0
- package/scanner/component-scanner.ts +406 -19
- package/scanner/font-family-extract-regression.ts +113 -0
- package/scanner/framework-adapter-shadcn-regression.ts +96 -1
- package/scanner/grid-cols-extraction-regression.ts +110 -0
- package/scanner/imported-array-map-regression.ts +195 -0
- package/scanner/input-range-regression.ts +217 -0
- package/scanner/intrinsic-sizing-regression.ts +333 -0
- package/scanner/jsx-prop-unresolved-regression.ts +178 -0
- package/scanner/local-const-className-regression.ts +331 -0
- package/scanner/ring-utility-regression.ts +25 -4
- package/scanner/state-classification-regression.ts +38 -0
- package/scanner/story-args-resolution-regression.ts +270 -0
- package/scanner/stretch-to-parent-width-regression.ts +35 -1
- package/scanner/tailwind-parser.ts +38 -2
- package/src/components/component-gen.ts +11 -151
- package/src/design-system/cva-master.ts +7 -3
- package/src/design-system/design-system.ts +8 -0
- package/src/design-system/node-helpers.ts +15 -1
- package/src/design-system/preview-builder.ts +14 -45
- package/src/design-system/state-master.ts +23 -1
- package/src/design-system/story-builder.ts +67 -5
- package/src/design-system/ui-builder.ts +116 -6
- package/src/framework-adapters/index.ts +15 -2
- package/src/framework-adapters/shadcn.ts +83 -67
- package/src/layout/deferred-layout.ts +187 -1
- package/src/layout/index.ts +2 -0
- package/src/layout/intrinsic-applier.ts +105 -0
- package/src/layout/intrinsic-sizing.ts +183 -0
- package/src/layout/layout-utils.ts +2 -1
- package/src/layout/parser/layout-mode.ts +14 -4
- package/src/layout/ring-utils.ts +31 -82
- package/src/render-engine-version.ts +1 -1
- package/src/tailwind/adapter-utils.ts +137 -0
- package/src/tailwind/jsx-utils.ts +9 -0
- package/src/tailwind/node-ir.ts +172 -0
- package/src/tailwind/tailwind.ts +52 -24
- package/src/tokens/tokens.ts +11 -3
- package/templates/scan-components-route.ts +11 -1
package/README.md
CHANGED
|
@@ -36,13 +36,14 @@ pnpm add -D inkbridge
|
|
|
36
36
|
pnpm exec inkbridge setup
|
|
37
37
|
```
|
|
38
38
|
|
|
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):
|
|
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, or `--force` to refresh route templates and `inkbridge.config.json` after a plugin update):
|
|
40
40
|
|
|
41
41
|
- Creates `inkbridge.config.json` in your project root (auto-detects component paths from `.storybook/main.*`)
|
|
42
42
|
- Creates the scanner API route at `src/app/api/inkbridge/scan-components/route.ts`
|
|
43
43
|
- Creates the token patch API route at `src/app/api/inkbridge/patch-tokens/route.ts`
|
|
44
44
|
- Adds `inkbridge:dev` and `inkbridge:scan` scripts to your `package.json`
|
|
45
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
|
+
- Appends `.inkbridge/` to your `.gitignore` so the scanner-output JSON doesn't show up in every diff
|
|
46
47
|
|
|
47
48
|
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.
|
|
48
49
|
|
package/bin/inkbridge.mjs
CHANGED
|
@@ -157,6 +157,14 @@ function printEnvironment(env) {
|
|
|
157
157
|
|
|
158
158
|
async function setup() {
|
|
159
159
|
const dryRun = process.argv.includes("--dry-run");
|
|
160
|
+
// `--force` re-creates the inkbridge-managed files (route templates,
|
|
161
|
+
// inkbridge.config.json) even when they already exist. Useful when a
|
|
162
|
+
// newer plugin version ships an updated template (e.g. the
|
|
163
|
+
// INKBRIDGE_LOCAL check in the scanner route) and the consumer wants
|
|
164
|
+
// to refresh without hand-editing. Never touches package.json or
|
|
165
|
+
// next.config — those are partial-edit territory and force-rewriting
|
|
166
|
+
// them would clobber consumer state.
|
|
167
|
+
const force = process.argv.includes("--force");
|
|
160
168
|
const scanRouteDest = join(PROJECT_ROOT, "src/app/api/inkbridge/scan-components/route.ts");
|
|
161
169
|
const scanRouteSrc = join(PACKAGE_DIR, "templates/scan-components-route.ts");
|
|
162
170
|
const patchRouteDest = join(PROJECT_ROOT, "src/app/api/inkbridge/patch-tokens/route.ts");
|
|
@@ -165,7 +173,7 @@ async function setup() {
|
|
|
165
173
|
const inkbridgeCfgPath = join(PROJECT_ROOT, "inkbridge.config.json");
|
|
166
174
|
|
|
167
175
|
console.log("");
|
|
168
|
-
console.log(` inkbridge setup${dryRun ? " — dry run (no files will be written)" : ""}`);
|
|
176
|
+
console.log(` inkbridge setup${dryRun ? " — dry run (no files will be written)" : ""}${force ? " — force (overwrite existing inkbridge files)" : ""}`);
|
|
169
177
|
console.log("");
|
|
170
178
|
|
|
171
179
|
const env = detectEnvironment(PROJECT_ROOT);
|
|
@@ -176,14 +184,24 @@ async function setup() {
|
|
|
176
184
|
// ------------------------------------------------------------------
|
|
177
185
|
const plan = [];
|
|
178
186
|
|
|
179
|
-
if (!existsSync(inkbridgeCfgPath)) {
|
|
180
|
-
plan.push({
|
|
187
|
+
if (!existsSync(inkbridgeCfgPath) || force) {
|
|
188
|
+
plan.push({
|
|
189
|
+
kind: existsSync(inkbridgeCfgPath) ? "overwrite" : "create",
|
|
190
|
+
path: "inkbridge.config.json",
|
|
191
|
+
detail: `componentPaths: [${env.componentPaths.join(", ")}]`,
|
|
192
|
+
});
|
|
181
193
|
}
|
|
182
|
-
if (!existsSync(scanRouteDest)) {
|
|
183
|
-
plan.push({
|
|
194
|
+
if (!existsSync(scanRouteDest) || force) {
|
|
195
|
+
plan.push({
|
|
196
|
+
kind: existsSync(scanRouteDest) ? "overwrite" : "create",
|
|
197
|
+
path: "src/app/api/inkbridge/scan-components/route.ts",
|
|
198
|
+
});
|
|
184
199
|
}
|
|
185
|
-
if (!existsSync(patchRouteDest)) {
|
|
186
|
-
plan.push({
|
|
200
|
+
if (!existsSync(patchRouteDest) || force) {
|
|
201
|
+
plan.push({
|
|
202
|
+
kind: existsSync(patchRouteDest) ? "overwrite" : "create",
|
|
203
|
+
path: "src/app/api/inkbridge/patch-tokens/route.ts",
|
|
204
|
+
});
|
|
187
205
|
}
|
|
188
206
|
|
|
189
207
|
let pkg = null;
|
|
@@ -215,6 +233,27 @@ async function setup() {
|
|
|
215
233
|
});
|
|
216
234
|
}
|
|
217
235
|
|
|
236
|
+
// Make sure the scanner-output directory is gitignored. The API
|
|
237
|
+
// route writes `.inkbridge/component-definitions.json` on every
|
|
238
|
+
// plugin run; without this entry consumers see the file in their
|
|
239
|
+
// diff after every `pnpm inkbridge:scan`.
|
|
240
|
+
const gitignorePath = join(PROJECT_ROOT, ".gitignore");
|
|
241
|
+
const gitignoreSource = existsSync(gitignorePath)
|
|
242
|
+
? readFileSync(gitignorePath, "utf8")
|
|
243
|
+
: "";
|
|
244
|
+
const gitignoreNeedsPatch = existsSync(join(PROJECT_ROOT, ".git"))
|
|
245
|
+
&& !gitignoreSource.split("\n").some(line => {
|
|
246
|
+
const trimmed = line.trim();
|
|
247
|
+
return trimmed === ".inkbridge" || trimmed === ".inkbridge/";
|
|
248
|
+
});
|
|
249
|
+
if (gitignoreNeedsPatch) {
|
|
250
|
+
plan.push({
|
|
251
|
+
kind: "modify",
|
|
252
|
+
path: ".gitignore",
|
|
253
|
+
detail: "+ .inkbridge/ (scanner output)",
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
218
257
|
if (plan.length === 0) {
|
|
219
258
|
console.log(" Nothing to do — setup is already complete.");
|
|
220
259
|
console.log("");
|
|
@@ -224,7 +263,11 @@ async function setup() {
|
|
|
224
263
|
|
|
225
264
|
console.log(" Setup will make these changes:");
|
|
226
265
|
for (const item of plan) {
|
|
227
|
-
const prefix = item.kind === "create"
|
|
266
|
+
const prefix = item.kind === "create"
|
|
267
|
+
? "+ create"
|
|
268
|
+
: item.kind === "overwrite"
|
|
269
|
+
? "↻ overwrite"
|
|
270
|
+
: "~ modify";
|
|
228
271
|
console.log(` ${prefix} ${item.path}${item.detail ? ` (${item.detail})` : ""}`);
|
|
229
272
|
}
|
|
230
273
|
console.log("");
|
|
@@ -259,8 +302,20 @@ async function setup() {
|
|
|
259
302
|
} else if (env.nextConfig && item.path === env.nextConfig) {
|
|
260
303
|
await patchNextConfig(PROJECT_ROOT);
|
|
261
304
|
continue; // patchNextConfig already prints
|
|
305
|
+
} else if (item.path === ".gitignore") {
|
|
306
|
+
const existing = existsSync(gitignorePath)
|
|
307
|
+
? readFileSync(gitignorePath, "utf8")
|
|
308
|
+
: "";
|
|
309
|
+
const needsLeadingNewline = existing.length > 0 && !existing.endsWith("\n");
|
|
310
|
+
const block = (needsLeadingNewline ? "\n" : "")
|
|
311
|
+
+ "\n# Inkbridge scanner output (regenerated on every plugin run)\n.inkbridge/\n";
|
|
312
|
+
await writeFile(gitignorePath, existing + block, "utf8");
|
|
262
313
|
}
|
|
263
|
-
const prefix = item.kind === "create"
|
|
314
|
+
const prefix = item.kind === "create"
|
|
315
|
+
? "✓ created"
|
|
316
|
+
: item.kind === "overwrite"
|
|
317
|
+
? "✓ overwrote"
|
|
318
|
+
: "✓ modified";
|
|
264
319
|
console.log(` ${prefix} ${item.path}`);
|
|
265
320
|
}
|
|
266
321
|
|