synthesisui 0.16.109 → 0.16.110
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/commands/import.js +19 -3
- package/dist/doctor/broken-refs.js +46 -0
- package/dist/skill-import.js +35 -2
- package/package.json +1 -1
package/dist/commands/import.js
CHANGED
|
@@ -428,6 +428,12 @@ export async function takeCensus(root, opts) {
|
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
const t = transcribe(rootClasses(src, found[0].name), declaredValues);
|
|
431
|
+
/**
|
|
432
|
+
* The transcription carries `dark` too, and spreading it put the key back after
|
|
433
|
+
* the conditional below decided to leave it out. Two writers for one field is
|
|
434
|
+
* how a decision gets undone by the line above it.
|
|
435
|
+
*/
|
|
436
|
+
const { dark: _measuredDark, ...withoutDark } = t;
|
|
431
437
|
/**
|
|
432
438
|
* THE VARIANT STYLES, FOLDED IN.
|
|
433
439
|
*
|
|
@@ -540,10 +546,20 @@ export async function takeCensus(root, opts) {
|
|
|
540
546
|
if (size > 0 || tag) {
|
|
541
547
|
looks[found[0].name] = {
|
|
542
548
|
...(sketch.length > 0 ? { sketch } : {}),
|
|
543
|
-
...
|
|
549
|
+
...withoutDark,
|
|
544
550
|
base,
|
|
545
551
|
states,
|
|
546
|
-
|
|
552
|
+
/**
|
|
553
|
+
* OMITTED WHEN EMPTY, so a real loss is legible.
|
|
554
|
+
*
|
|
555
|
+
* `dark` is a field of the READING, not of the contract - the platform
|
|
556
|
+
* converts it into a `{when:{scheme:"dark"}}` layer, which is the one way
|
|
557
|
+
* a recipe says dark. Emitting the key regardless made a validator report
|
|
558
|
+
* all 36 components as "not arriving whole" for a key with nothing in it,
|
|
559
|
+
* and the 7 that carry a real value were buried in the noise
|
|
560
|
+
* (not-expressed.md, dono, 03/08). 29 of 36 were empty.
|
|
561
|
+
*/
|
|
562
|
+
...(Object.keys(dark).length > 0 ? { dark } : {}),
|
|
547
563
|
...(Object.keys(parts).length > 0 ? { parts } : {}),
|
|
548
564
|
...(tree.length > 0 ? { tree } : {}),
|
|
549
565
|
...(tag ? { rootTag: tag } : {}),
|
|
@@ -864,7 +880,7 @@ export async function takeCensus(root, opts) {
|
|
|
864
880
|
*/
|
|
865
881
|
const coverage = summarizeCoverage(shapes, componentFiles, Object.keys(looks).length, Object.values(looks).reduce((n, look) => n +
|
|
866
882
|
Object.keys(look.base).length +
|
|
867
|
-
Object.keys(look.dark).length +
|
|
883
|
+
Object.keys(look.dark ?? {}).length +
|
|
868
884
|
Object.values(look.states).reduce((m, block) => m + Object.keys(block).length, 0) +
|
|
869
885
|
// The LAYERS count: the record and ternary readers produce layers rather than a
|
|
870
886
|
// base, so leaving them out reported a Tag with eight colours as three
|
|
@@ -17,8 +17,51 @@
|
|
|
17
17
|
* this product has (dono, 01/08: "a normalização será de acordo com cada
|
|
18
18
|
* projeto").
|
|
19
19
|
*/
|
|
20
|
+
import { frontierKind } from "../frontier-kind.js";
|
|
21
|
+
import { importMap } from "./imports.js";
|
|
20
22
|
/** `var(--x)`, including inside a Tailwind arbitrary value: `bg-[var(--x)]`. */
|
|
21
23
|
const VAR_REF = /var\(\s*(--[a-zA-Z0-9_-]+)/g;
|
|
24
|
+
/**
|
|
25
|
+
* VARIABLES A HEADLESS LIBRARY SETS AT RUNTIME, which no stylesheet can declare.
|
|
26
|
+
*
|
|
27
|
+
* Base UI measures the trigger and writes `--anchor-width` on the positioner element
|
|
28
|
+
* before paint, so `min-w-[var(--anchor-width)]` on their Select is correct and works.
|
|
29
|
+
* Counting it as a broken reference told the owner their own code was defective, and it
|
|
30
|
+
* cost the report its credibility on the twelve that ARE broken (not-expressed.md,
|
|
31
|
+
* dono, 03/08). Two of their thirteen were this.
|
|
32
|
+
*
|
|
33
|
+
* The list is the SHARED vocabulary of headless positioning - Base UI, Radix, Ark and
|
|
34
|
+
* Floating UI all name the anchor's width `--anchor-width` - plus the self-identifying
|
|
35
|
+
* per-library prefixes. Same reasoning as `NON_RENDERING` in `frontier-kind.ts`: a name
|
|
36
|
+
* is only read after the PACKAGE has answered.
|
|
37
|
+
*/
|
|
38
|
+
const RUNTIME_ANCHOR = new Set([
|
|
39
|
+
"--anchor-width",
|
|
40
|
+
"--anchor-height",
|
|
41
|
+
"--available-width",
|
|
42
|
+
"--available-height",
|
|
43
|
+
"--transform-origin",
|
|
44
|
+
"--popup-width",
|
|
45
|
+
"--popup-height",
|
|
46
|
+
"--trigger-width",
|
|
47
|
+
"--trigger-height",
|
|
48
|
+
]);
|
|
49
|
+
/** `--radix-popper-anchor-width` and its siblings in the other libraries. */
|
|
50
|
+
const RUNTIME_PREFIX = /^--(?:radix|reka|ark|kb|floating|reactour)-/;
|
|
51
|
+
/**
|
|
52
|
+
* Does this file import a library that supplies such a variable?
|
|
53
|
+
*
|
|
54
|
+
* THE PACKAGE DECIDES, never the variable name on its own: a project that declares no
|
|
55
|
+
* headless dependency and writes `var(--anchor-width)` really has written a reference
|
|
56
|
+
* to nothing, and saying so is the whole value of this scan.
|
|
57
|
+
*/
|
|
58
|
+
function importsHeadless(source) {
|
|
59
|
+
for (const spec of Object.values(importMap(source))) {
|
|
60
|
+
if (frontierKind(spec) === "headless")
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
22
65
|
/**
|
|
23
66
|
* PREFIXES A DECLARATION MAY CARRY that a reference dropped.
|
|
24
67
|
*
|
|
@@ -46,10 +89,13 @@ const NAMESPACES = [
|
|
|
46
89
|
export function findBrokenRefs(sources, declared) {
|
|
47
90
|
const seen = new Map();
|
|
48
91
|
for (const { file, source } of sources) {
|
|
92
|
+
const runtime = importsHeadless(source);
|
|
49
93
|
for (const m of source.matchAll(VAR_REF)) {
|
|
50
94
|
const name = m[1];
|
|
51
95
|
if (declared.has(name))
|
|
52
96
|
continue;
|
|
97
|
+
if (runtime && (RUNTIME_ANCHOR.has(name) || RUNTIME_PREFIX.test(name)))
|
|
98
|
+
continue;
|
|
53
99
|
const hit = seen.get(name) ?? { count: 0, files: new Set() };
|
|
54
100
|
hit.count += 1;
|
|
55
101
|
hit.files.add(file);
|
package/dist/skill-import.js
CHANGED
|
@@ -388,9 +388,15 @@ Open the project and answer the questions below. Then add a \`reading\` object t
|
|
|
388
388
|
"name": "body",
|
|
389
389
|
"at": 2,
|
|
390
390
|
"children": [
|
|
391
|
-
{ "as": "
|
|
391
|
+
{ "as": "component", "ref": "Text", "at": 3 },
|
|
392
392
|
{ "as": "heading", "name": "value", "at": 4 }
|
|
393
393
|
]
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
"as": "component",
|
|
397
|
+
"ref": "Tooltip",
|
|
398
|
+
"at": 5,
|
|
399
|
+
"children": [{ "as": "icon", "name": "info", "at": 6 }]
|
|
394
400
|
}
|
|
395
401
|
]
|
|
396
402
|
},
|
|
@@ -399,7 +405,7 @@ Open the project and answer the questions below. Then add a \`reading\` object t
|
|
|
399
405
|
"anatomy": [
|
|
400
406
|
{ "as": "image", "name": "cover", "at": 1 },
|
|
401
407
|
{ "as": "heading", "name": "title", "at": 2 },
|
|
402
|
-
{ "as": "component", "ref": "TextEditor" },
|
|
408
|
+
{ "as": "component", "ref": "TextEditor", "at": 5 },
|
|
403
409
|
{
|
|
404
410
|
"as": "row",
|
|
405
411
|
"name": "footer",
|
|
@@ -702,6 +708,21 @@ because a button's content model is *phrasing* and an icon is phrasing. So an \`
|
|
|
702
708
|
Everything else is a leaf, and a leaf that holds elements has them HOISTED OUT to become
|
|
703
709
|
its siblings - which destroys the nesting you read. If something arranges, say \`row\`/\`stack\`.
|
|
704
710
|
|
|
711
|
+
**A frontier keeps its own \`at\`, so it keeps its own classes.** This is the one that gets
|
|
712
|
+
talked out of: \`<Text className="text-lightgray-500 font-medium">\` is one of THEIR
|
|
713
|
+
components, so it is a \`component\` node - and pointing \`at\` its sketch index carries the
|
|
714
|
+
typography onto it exactly as a part would. Reading it as a \`text\` part instead is a
|
|
715
|
+
downgrade with a real cost: \`composes\` is built from \`component\` nodes, so a library whose
|
|
716
|
+
most-used atom is composed 363 times reported composing it ZERO times, and its strongest
|
|
717
|
+
composition law became invisible (not-expressed.md, dono, 03/08).
|
|
718
|
+
|
|
719
|
+
<Tooltip><Info/></Tooltip> frontier with a child, both survive
|
|
720
|
+
<Text className="…">Label</Text> frontier with "at", the type survives
|
|
721
|
+
|
|
722
|
+
If you find yourself writing "the contract cannot hold this, so I sent something else",
|
|
723
|
+
check it against \`recipe_vocabulary\` before you write the workaround - and if the check
|
|
724
|
+
disagrees with this file, the check is right and this file is old.
|
|
725
|
+
|
|
705
726
|
### \`{children}\` is a node, not an absence
|
|
706
727
|
|
|
707
728
|
Four things decide what a component looks like on screen, and only the first is in its own source:
|
|
@@ -847,6 +868,18 @@ a recipe before these tools existed, and four separate readings were lost in sil
|
|
|
847
868
|
\`dark:\` inside a variant, a state the compiler cannot spell, a part name with a dot in it,
|
|
848
869
|
a layer with an empty style. Each of those was correct work that arrived as nothing.
|
|
849
870
|
|
|
871
|
+
**A FIELD OF THE READING IS NOT A FIELD OF THE RECIPE.** \`looks[X].dark\` is how the census
|
|
872
|
+
reports a dark half it measured; a recipe has one way to say the same thing, and it is a
|
|
873
|
+
layer:
|
|
874
|
+
|
|
875
|
+
\`\`\`json
|
|
876
|
+
{ "when": { "scheme": "dark" }, "style": { "backgroundColor": "{color.darkgray.300}" } }
|
|
877
|
+
\`\`\`
|
|
878
|
+
|
|
879
|
+
Copying \`dark\` in at the top level of a recipe costs you that block, silently, on every
|
|
880
|
+
component that has one - and \`import\` already converts it for the recipes IT writes, so the
|
|
881
|
+
only place this can be lost is a recipe you hand-built (not-expressed.md, dono, 03/08).
|
|
882
|
+
|
|
850
883
|
**In ONE call.** Build every recipe in memory, then send the whole reading to
|
|
851
884
|
\`validate_recipes\` - one round trip for 35 components instead of 35. \`validate_recipe\`
|
|
852
885
|
(singular) is for the one recipe you rewrote after the batch named it; reaching for it in a
|
package/package.json
CHANGED