synthesisui 0.16.98 → 0.16.100
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/dist/anatomy-read.js +18 -1
- package/dist/commands/mcp.js +19 -0
- package/dist/doctor/sketch.js +17 -1
- package/dist/doctor/transcribe.js +95 -13
- package/dist/skill-import.js +11 -0
- package/package.json +1 -1
package/dist/anatomy-read.js
CHANGED
|
@@ -305,7 +305,24 @@ sketch) {
|
|
|
305
305
|
"")
|
|
306
306
|
: "";
|
|
307
307
|
const paints = rootPainted ? { classes: rootPainted } : {};
|
|
308
|
-
|
|
308
|
+
/**
|
|
309
|
+
* A LIBRARY ROOT WHOSE NAME IS NOT DOTTED.
|
|
310
|
+
*
|
|
311
|
+
* Three components return a Base UI primitive imported under a single word -
|
|
312
|
+
* `Pill` and `SelectionCard` return `Toggle`, `RadioCardGroup` returns
|
|
313
|
+
* `RadioGroup` - and `"root": "Toggle"` would point at THEIR own Toggle (a
|
|
314
|
+
* switch), inventing a relation that does not exist. There was no way to say
|
|
315
|
+
* "a library component with a bare name", so `root` was left out on all three
|
|
316
|
+
* (not-expressed.md, dono, 01/08).
|
|
317
|
+
*
|
|
318
|
+
* `from` says it: the PACKAGE disambiguates what the name cannot. It wins over
|
|
319
|
+
* the name, because a caller that sends both is telling us where it came from.
|
|
320
|
+
*/
|
|
321
|
+
const rootFrom = String(rootObj?.from ?? "").trim();
|
|
322
|
+
if (rootFrom) {
|
|
323
|
+
rootOut = { from: rootFrom, ...paints };
|
|
324
|
+
}
|
|
325
|
+
else if (rootRaw && /^[A-Z]/.test(rootRaw)) {
|
|
309
326
|
if (rootRaw.includes(".")) {
|
|
310
327
|
rootOut = { from: rootRaw, ...paints };
|
|
311
328
|
}
|
package/dist/commands/mcp.js
CHANGED
|
@@ -437,6 +437,25 @@ async function resolveAtNodes(root, entries) {
|
|
|
437
437
|
],
|
|
438
438
|
}
|
|
439
439
|
: {}),
|
|
440
|
+
/**
|
|
441
|
+
* THE PARTS, which is where a provider-rooted component keeps
|
|
442
|
+
* EVERYTHING.
|
|
443
|
+
*
|
|
444
|
+
* `Tooltip` returns `<BaseTooltip.Provider>` - a context provider that
|
|
445
|
+
* renders no element and carries no style - and its whole look (fill,
|
|
446
|
+
* radius, padding, shadow) is on the popup PART. The merge carried
|
|
447
|
+
* `base` and `layers` and stopped there, so the validator judged a
|
|
448
|
+
* component with no declarations anywhere and said BELOW THE FLOOR
|
|
449
|
+
* about one that draws fine (not-expressed.md, dono, 01/08).
|
|
450
|
+
*/
|
|
451
|
+
...(look?.parts && Object.keys(look.parts).length > 0
|
|
452
|
+
? {
|
|
453
|
+
parts: {
|
|
454
|
+
...look.parts,
|
|
455
|
+
...(recipe0.parts ?? {}),
|
|
456
|
+
},
|
|
457
|
+
}
|
|
458
|
+
: {}),
|
|
440
459
|
/**
|
|
441
460
|
* THE ROOT TAG TRAVELS, so the validator can name the KIND.
|
|
442
461
|
*
|
package/dist/doctor/sketch.js
CHANGED
|
@@ -82,8 +82,24 @@ function staticCallClasses(body) {
|
|
|
82
82
|
argStart = i + 1;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* A COMMENT BEFORE THE STRING IS STILL THE STRING.
|
|
87
|
+
*
|
|
88
|
+
* Real code annotates these lists - `// Light mode`, `// Shadow with subtle
|
|
89
|
+
* brand tint` - and the argument then reads as `// Light mode\n"bg-darkgray-800
|
|
90
|
+
* …"`, which is not a bare literal, so it was dropped. The Tooltip kept only
|
|
91
|
+
* its last two arguments (the two with no comment above them) and lost its
|
|
92
|
+
* fill, radius, padding and shadow - and it only came to light because the
|
|
93
|
+
* floor check flagged it (not-expressed.md, dono, 01/08). Measured: SIX of 36
|
|
94
|
+
* components in that library annotate a `cn()` this way.
|
|
95
|
+
*/
|
|
85
96
|
const classes = args
|
|
86
|
-
.map((a) => a
|
|
97
|
+
.map((a) => a
|
|
98
|
+
// block comments first, so a `/* … */` spanning the line cannot leave
|
|
99
|
+
// a stray `*/` behind for the line rule to keep
|
|
100
|
+
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
101
|
+
.replace(/(^|\n)\s*\/\/[^\n]*/g, "$1")
|
|
102
|
+
.trim())
|
|
87
103
|
.filter((a) => /^(["'`]).*\1$/.test(a) && !a.includes("${"))
|
|
88
104
|
.map((a) => a.slice(1, -1).trim())
|
|
89
105
|
.filter(Boolean);
|
|
@@ -241,6 +241,15 @@ const TAILWIND_COLOR = {
|
|
|
241
241
|
white: "#ffffff",
|
|
242
242
|
black: "#000000",
|
|
243
243
|
transparent: "transparent",
|
|
244
|
+
/**
|
|
245
|
+
* KEYWORDS ARE VALUES. `bg-current` is `background-color: currentColor` and
|
|
246
|
+
* `text-inherit` is `color: inherit` - real CSS, no palette needed, and they
|
|
247
|
+
* were being dropped as unreadable. Nine utilities across the owner's library,
|
|
248
|
+
* and `bg-current` is how a spinner takes its colour from its parent - drop it
|
|
249
|
+
* and the spinner is invisible (not-expressed.md, dono, 01/08).
|
|
250
|
+
*/
|
|
251
|
+
current: "currentColor",
|
|
252
|
+
inherit: "inherit",
|
|
244
253
|
// zinc and blue, because a real Select is styled entirely in them and every
|
|
245
254
|
// reference read as nothing (test14, 01/08). Tailwind's own values, verbatim.
|
|
246
255
|
"zinc-50": "#fafafa",
|
|
@@ -351,6 +360,9 @@ const STATE_SPELLING = {
|
|
|
351
360
|
first: "first",
|
|
352
361
|
last: "last",
|
|
353
362
|
empty: "empty",
|
|
363
|
+
/** Base UI's enter/exit faces - `data-[starting-style]:opacity-0`. */
|
|
364
|
+
"starting-style": "startingStyle",
|
|
365
|
+
"ending-style": "endingStyle",
|
|
354
366
|
};
|
|
355
367
|
const DATA_STATE = /^data-\[(?:state=)?([a-z-]+)\]$/;
|
|
356
368
|
/**
|
|
@@ -837,6 +849,33 @@ function refFor(name) {
|
|
|
837
849
|
return `{color.${name}}`;
|
|
838
850
|
return `{color.${m[1]}.${m[2]}}`;
|
|
839
851
|
}
|
|
852
|
+
/** Their breakpoint names, as Tailwind ships them. A project that renames these
|
|
853
|
+
* declares its own, and the census carries that - this is the default ladder. */
|
|
854
|
+
const BREAKPOINT = /^(sm|md|lg|xl|2xl|min-\[[^\]]+\]|max-\[[^\]]+\])$/;
|
|
855
|
+
/**
|
|
856
|
+
* The layer for one set of conditions, created once and reused.
|
|
857
|
+
*
|
|
858
|
+
* Reused rather than appended per utility, because `dark:hover:bg-x` and
|
|
859
|
+
* `dark:hover:border-y` are ONE conditional look with two declarations - two
|
|
860
|
+
* layers with identical conditions would compile to two identical rules.
|
|
861
|
+
*/
|
|
862
|
+
function layerFor(out, when, at) {
|
|
863
|
+
out.layers ??= [];
|
|
864
|
+
const same = out.layers.find((l) => (l.at ?? null) === (at ?? null) &&
|
|
865
|
+
(l.when?.state ?? null) === (when.state ?? null) &&
|
|
866
|
+
(l.when?.within ?? null) === (when.within ?? null) &&
|
|
867
|
+
(l.when?.scheme ?? null) === (when.scheme ?? null) &&
|
|
868
|
+
l.when?.variant == null);
|
|
869
|
+
if (same)
|
|
870
|
+
return same;
|
|
871
|
+
const created = {
|
|
872
|
+
...(Object.keys(when).length > 0 ? { when } : {}),
|
|
873
|
+
...(at ? { at } : {}),
|
|
874
|
+
style: {},
|
|
875
|
+
};
|
|
876
|
+
out.layers.push(created);
|
|
877
|
+
return created;
|
|
878
|
+
}
|
|
840
879
|
/**
|
|
841
880
|
* Read every class in a component's root element and route each declaration by
|
|
842
881
|
* its modifier.
|
|
@@ -1005,20 +1044,63 @@ export function transcribe(classes, declared) {
|
|
|
1005
1044
|
if (rest.length === 0) {
|
|
1006
1045
|
target = isDark ? out.dark : out.base;
|
|
1007
1046
|
}
|
|
1008
|
-
else if (rest.length === 1 && !isDark) {
|
|
1009
|
-
const raw = STATE_SPELLING[rest[0]] != null
|
|
1010
|
-
? rest[0]
|
|
1011
|
-
: (DATA_STATE.exec(rest[0])?.[1] ?? null);
|
|
1012
|
-
const state = raw ? (STATE_SPELLING[raw] ?? null) : null;
|
|
1013
|
-
if (state)
|
|
1014
|
-
target = out.states[state] ?? (out.states[state] = {});
|
|
1015
|
-
else
|
|
1016
|
-
unslotted = true;
|
|
1017
|
-
}
|
|
1018
1047
|
else {
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1048
|
+
/**
|
|
1049
|
+
* EVERY MODIFIER GETS A SLOT, and the contract has had one all along.
|
|
1050
|
+
*
|
|
1051
|
+
* This used to route a bare state and drop everything else, on a comment
|
|
1052
|
+
* that said "a recipe has no slot for it" - true when it was written and
|
|
1053
|
+
* false since the transcription grew `layers`, which hold `scheme`,
|
|
1054
|
+
* `state`, `within` and `at` TOGETHER. Measured on the owner's library:
|
|
1055
|
+
* 29 real decisions dropped on that stale line, most of them a `dark:`
|
|
1056
|
+
* over a state (not-expressed.md, dono, 01/08).
|
|
1057
|
+
*
|
|
1058
|
+
* A recipe that reconstructs the component must carry them, so the router
|
|
1059
|
+
* reads the whole modifier list and only gives up on a modifier that
|
|
1060
|
+
* genuinely has no home - and then it SAYS so.
|
|
1061
|
+
*/
|
|
1062
|
+
const when = {};
|
|
1063
|
+
let at;
|
|
1064
|
+
for (const mod of rest) {
|
|
1065
|
+
/** `group-hover:`, `group-data-[checked]:` - the PARENT's state. */
|
|
1066
|
+
const group = /^group-(.+)$/.exec(mod);
|
|
1067
|
+
const bare = group ? group[1] : mod;
|
|
1068
|
+
const raw = STATE_SPELLING[bare] != null
|
|
1069
|
+
? bare
|
|
1070
|
+
: (DATA_STATE.exec(bare)?.[1] ?? null);
|
|
1071
|
+
const state = raw ? (STATE_SPELLING[raw] ?? null) : null;
|
|
1072
|
+
if (state) {
|
|
1073
|
+
if (group)
|
|
1074
|
+
when.within = state;
|
|
1075
|
+
else
|
|
1076
|
+
when.state = state;
|
|
1077
|
+
continue;
|
|
1078
|
+
}
|
|
1079
|
+
/** `md:`, `lg:` - a breakpoint of theirs, by their own name. */
|
|
1080
|
+
if (BREAKPOINT.test(mod) && !at) {
|
|
1081
|
+
at = mod;
|
|
1082
|
+
continue;
|
|
1083
|
+
}
|
|
1084
|
+
unslotted = true;
|
|
1085
|
+
}
|
|
1086
|
+
if (!unslotted) {
|
|
1087
|
+
if (isDark)
|
|
1088
|
+
when.scheme = "dark";
|
|
1089
|
+
// A bare single state with no scheme keeps its own slot: `states` is what
|
|
1090
|
+
// the compiler and every lens already read, and moving it to a layer
|
|
1091
|
+
// would be a shape change nothing asked for.
|
|
1092
|
+
if (when.state &&
|
|
1093
|
+
!when.within &&
|
|
1094
|
+
!when.scheme &&
|
|
1095
|
+
!at &&
|
|
1096
|
+
rest.length === 1) {
|
|
1097
|
+
target = out.states[when.state] ?? (out.states[when.state] = {});
|
|
1098
|
+
}
|
|
1099
|
+
else {
|
|
1100
|
+
const layer = layerFor(out, when, at);
|
|
1101
|
+
target = layer.style;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1022
1104
|
}
|
|
1023
1105
|
const decl = readUtility(utility, declared);
|
|
1024
1106
|
if (unslotted) {
|
package/dist/skill-import.js
CHANGED
|
@@ -622,6 +622,17 @@ depth appears anyway.
|
|
|
622
622
|
}
|
|
623
623
|
\`\`\`
|
|
624
624
|
|
|
625
|
+
**A library root whose name is not dotted needs its PACKAGE.** \`Pill\` returns Base UI's
|
|
626
|
+
\`Toggle\`, and \`"root": "Toggle"\` would point at THEIR own Toggle - a switch - inventing a
|
|
627
|
+
relation that does not exist. Send where it came from instead:
|
|
628
|
+
|
|
629
|
+
\`\`\`json
|
|
630
|
+
"Pill": { "root": { "from": "@base-ui/react/toggle" }, "anatomy": [ … ] }
|
|
631
|
+
\`\`\`
|
|
632
|
+
|
|
633
|
+
\`Radio.Root\` needs none of this: the dot already says it is somebody's namespace. Leaving the
|
|
634
|
+
root out was the old workaround and it cost the surface its name (not-expressed.md, dono, 01/08).
|
|
635
|
+
|
|
625
636
|
**The root takes what the PARENT paints on it.** When the returned root carries an override at
|
|
626
637
|
the call site - \`MetricCard\` returns \`<Card className="flex-1 dark:bg-darkgray-300">\` - send the
|
|
627
638
|
object form and point \`at\` the sketch node: \`{ "name": "Card", "at": 1 }\`. The string form still
|
package/package.json
CHANGED