synthesisui 0.16.105 → 0.16.106

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.
@@ -145,6 +145,12 @@ root,
145
145
  /** This component's sketch, so a node can name its classes by INDEX instead
146
146
  * of retyping them - see `AnatomyRead.at`. */
147
147
  sketch) {
148
+ /**
149
+ * THE PACKAGE THE RETURNED ELEMENT CAME FROM, measured rather than spelled.
150
+ * Node 0 of the sketch IS what the component returns, and the reader stamped its
151
+ * import specifier there - see `SketchNode.from`.
152
+ */
153
+ const rootPackage = sketch?.[0]?.from ?? null;
148
154
  const parts = {};
149
155
  const composes = [];
150
156
  const external = [];
@@ -342,20 +348,52 @@ sketch) {
342
348
  * `from` says it: the PACKAGE disambiguates what the name cannot. It wins over
343
349
  * the name, because a caller that sends both is telling us where it came from.
344
350
  */
345
- const rootFrom = String(rootObj?.from ?? "").trim();
351
+ /**
352
+ * THE PACKAGE, NEVER THE DOT.
353
+ *
354
+ * This read `rootRaw.includes(".")` as "somebody else's namespace" - the exact
355
+ * rule the platform's own root reader stopped using, left behind here. So a
356
+ * reading that says `root: { from: "Collapsible.Root" }` stamped a TAG where a
357
+ * package belongs, and since this field wins over `rootTag` downstream, ten of
358
+ * their thirty-five components were badged `3RD-PARTY · COLLAPSIBLE.ROOT` while
359
+ * the census sat on the answer: `@base-ui/react/collapsible`, headless, ours to
360
+ * draw (dono, 03/08).
361
+ *
362
+ * The sketch stamps the package on node 0, so the answer is one lookup away and
363
+ * a caller that spells a tag no longer decides.
364
+ */
365
+ const sent = String(rootObj?.from ?? "").trim();
366
+ const looksLikeTag = sent !== "" && /^[A-Z]/.test(sent);
367
+ const rootFrom = looksLikeTag ? (rootPackage ?? "") : sent;
346
368
  if (rootFrom) {
347
369
  rootOut = { from: rootFrom, ...paints };
348
370
  }
349
371
  else if (rootRaw && /^[A-Z]/.test(rootRaw)) {
350
- if (rootRaw.includes(".")) {
351
- rootOut = { from: rootRaw, ...paints };
352
- }
353
- else {
372
+ if (!rootRaw.includes(".")) {
373
+ /**
374
+ * A BARE CAPITALISED NAME goes through the crosswalk, and kebab-casing is the
375
+ * fallback for a system we generated ourselves - the platform then checks the
376
+ * slug is a component it actually has, so a wrong guess degrades to nothing
377
+ * rather than to a hole.
378
+ */
354
379
  const slug = resolve?.(rootRaw) ?? safePartName(rootRaw);
355
380
  if (slug)
356
381
  rootOut = { ref: slug, name: rootRaw, ...paints };
357
382
  }
383
+ else if (rootPackage) {
384
+ rootOut = { from: rootPackage, ...paints };
385
+ }
358
386
  }
387
+ /**
388
+ * A NAMESPACED NAME WITH NO PACKAGE ANYWHERE SAYS NOTHING.
389
+ *
390
+ * The dot is not being read as "somebody else's" here - that judgement belongs to
391
+ * the package and nothing else. It is read as what it structurally is: a member of
392
+ * a namespace, which cannot be one of their own top-level components, so the
393
+ * crosswalk has nothing to match and kebab-casing `BaseDialog.Root` into
394
+ * `base-dialog-root` would invent a component nobody has. Silence is the honest
395
+ * answer, and the package - when the sketch stamped one - is the loud one.
396
+ */
359
397
  if (coerced > 0) {
360
398
  notes.push(`${coerced} node${coerced === 1 ? "" : "s"} named a form that does not exist - kept, drawn as what ${coerced === 1 ? "it holds" : "they hold"}`);
361
399
  }
@@ -1774,13 +1774,40 @@ async function resolveReadParts(census, root) {
1774
1774
  ...(libraries.length > 0 ? { external: libraries } : {}),
1775
1775
  ...(resolved.root ? { root: resolved.root } : {}),
1776
1776
  };
1777
+ /**
1778
+ * ONE READING WRITES ONE GENERATION.
1779
+ *
1780
+ * The tree was REPLACED and the parts were MERGED, so every pass left its part
1781
+ * names behind under the next pass's tree. Two commands is all it takes: `--dry`
1782
+ * derives an anatomy and writes `box`, `box-2`, `text`; the send resolves the
1783
+ * reader's own and writes `trigger`, `panel`, `status-dot` - and the first
1784
+ * generation stays, styled and referenced by nothing.
1785
+ *
1786
+ * Measured on the owner's census (dono, 03/08): 143 orphan parts carrying real
1787
+ * declarations across 26 of 36 components - `CollapsibleCard` alone had 26 parts
1788
+ * and 13 in its tree, which is the "11 parts carry 33 declarations the anatomy
1789
+ * never puts on an element" the Canvas reports. The banner was right and the
1790
+ * cause was ours.
1791
+ *
1792
+ * A part from an EARLIER source survives only if the new tree names it - which
1793
+ * keeps a CSS-module part the anatomy wears, and drops the stale generation.
1794
+ */
1795
+ const worn = new Set();
1796
+ const collect = (nodes) => {
1797
+ for (const node of nodes) {
1798
+ if (node.part)
1799
+ worn.add(node.part);
1800
+ if (Array.isArray(node.children))
1801
+ collect(node.children);
1802
+ }
1803
+ };
1804
+ collect(resolved.tree);
1805
+ const inherited = Object.fromEntries(Object.entries(look?.parts ?? {}).filter(([part]) => worn.has(part)));
1777
1806
  looks[component] = look
1778
1807
  ? {
1779
1808
  ...look,
1780
1809
  ...carried,
1781
- ...(hasParts
1782
- ? { parts: { ...(look.parts ?? {}), ...resolved.parts } }
1783
- : {}),
1810
+ ...(hasParts ? { parts: { ...inherited, ...resolved.parts } } : {}),
1784
1811
  }
1785
1812
  : {
1786
1813
  base: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.105",
3
+ "version": "0.16.106",
4
4
  "description": "Bring SynthesisUI design systems into any project - tokens, typed components, whole pages and an agent-ready CLAUDE.md manifest.",
5
5
  "type": "module",
6
6
  "bin": {