synthesisui 0.16.410 → 0.16.411

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.
@@ -27,6 +27,7 @@
27
27
  * retyped ten-class string is where a `hover:` goes missing, and six components
28
28
  * lost their states to exactly that (audit, dono, 01/08).
29
29
  */
30
+ import { displayFromClasses } from "./display-from-class.js";
30
31
  import { frontierOf, rendersNothing, } from "./frontier-kind.js";
31
32
  /** An svg's insides are geometry, not anatomy: the glyph is the node. */
32
33
  const SVG_INTERNALS = new Set([
@@ -182,12 +183,23 @@ const NEUTRAL = new Set([
182
183
  "nav",
183
184
  "details",
184
185
  ]);
185
- /** `flex-col`, `grid` and `block` arrange DOWN; a bare `flex` arranges ACROSS. */
186
+ /**
187
+ * `flex-col`, `grid` and `block` arrange DOWN; a bare `flex` arranges ACROSS.
188
+ *
189
+ * ONE READING OF THE BOX, not two. This used to run its own regex over the class string
190
+ * while `transcribe` ran another, and the two answers disagreed by construction: the form
191
+ * is a lossy reduction of `display` - it says "across or down" and drops the difference
192
+ * between a grid and a column. Both now come off the same table, so the form is DERIVED
193
+ * from the declaration instead of being a second opinion about it.
194
+ */
186
195
  function arrangement(classes) {
187
- const list = ` ${classes ?? ""} `;
188
- if (/\s(flex-col|flex-col-reverse|grid|block|table)\s/.test(list))
196
+ const box = displayFromClasses(classes);
197
+ const direction = box.flexDirection;
198
+ if (direction === "column" || direction === "column-reverse")
189
199
  return "stack";
190
- if (/\s(flex|inline-flex|flex-row|flex-row-reverse)\s/.test(list))
200
+ if (direction === "row" || direction === "row-reverse")
201
+ return "row";
202
+ if (box.display === "flex" || box.display === "inline-flex")
191
203
  return "row";
192
204
  return "stack";
193
205
  }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * O DISPLAY QUE O CLIENTE ESCREVEU, LIDO DE UM CLASS STRING - a tabela, num lugar só.
3
+ *
4
+ * O QUE O CLIENTE GANHA: o preview desenha a caixa que ele declarou, e não a que a
5
+ * plataforma teria adivinhado. `display` é a declaração que decide se o componente dele é
6
+ * uma linha, uma coluna, uma grade ou uma caixa em linha - e o desenho pergunta por ela
7
+ * para saber se o layout daquele nó é DELE. Sem ela, a forma inferida por nós vence a que
8
+ * ele escreveu, que é o inverso exato da lei de prioridade de layout.
9
+ *
10
+ * MEDIDO em 09/09 sobre três sistemas - dos componentes cuja raiz é estilizada por
11
+ * utilitário, quantos tinham `display` na receita: 2 de 58, 9 de 20 e 0 de 32; pela via de
12
+ * CSS Module, 48 de 196. A sintaxe que ele escolheu estava decidindo se a declaração dele
13
+ * sobrevivia, e ninguém escolhe uma sintaxe por esse motivo.
14
+ *
15
+ * A DIREÇÃO VIAJA JUNTO, ou `flex flex-col` vira uma linha: `display:flex` é `row` por
16
+ * padrão, e emitir o display sem a direção troca em silêncio toda coluna dele por uma
17
+ * linha - uma leitura pior que a anterior, porque parece deliberada.
18
+ *
19
+ * ESTE ARQUIVO TEM UM GÊMEO BYTE-IDÊNTICO em `libs/ds-contracts/src/display-from-class.ts`,
20
+ * garantido por spec. O CLI é publicado standalone e não pode importar os contratos; a
21
+ * plataforma precisa da mesma tabela para alcançar quem já importou sem pedir re-import.
22
+ * Editar um exige copiar para o outro.
23
+ */
24
+ /**
25
+ * Os valores de `display` do CSS, na grafia utilitária que os frameworks convergiram em
26
+ * usar para cada um. A tabela é sobre CSS: a chave é só como aquele valor costuma ser
27
+ * escrito quando não é escrito por CSS.
28
+ */
29
+ export const DISPLAY_UTILITIES = {
30
+ flex: { property: "display", value: "flex" },
31
+ grid: { property: "display", value: "grid" },
32
+ "inline-flex": { property: "display", value: "inline-flex" },
33
+ "inline-grid": { property: "display", value: "inline-grid" },
34
+ "inline-block": { property: "display", value: "inline-block" },
35
+ inline: { property: "display", value: "inline" },
36
+ block: { property: "display", value: "block" },
37
+ "flow-root": { property: "display", value: "flow-root" },
38
+ contents: { property: "display", value: "contents" },
39
+ table: { property: "display", value: "table" },
40
+ "inline-table": { property: "display", value: "inline-table" },
41
+ "list-item": { property: "display", value: "list-item" },
42
+ hidden: { property: "display", value: "none" },
43
+ "flex-col": { property: "flexDirection", value: "column" },
44
+ "flex-col-reverse": { property: "flexDirection", value: "column-reverse" },
45
+ "flex-row": { property: "flexDirection", value: "row" },
46
+ "flex-row-reverse": { property: "flexDirection", value: "row-reverse" },
47
+ "flex-wrap": { property: "flexWrap", value: "wrap" },
48
+ "flex-wrap-reverse": { property: "flexWrap", value: "wrap-reverse" },
49
+ "flex-nowrap": { property: "flexWrap", value: "nowrap" },
50
+ };
51
+ /**
52
+ * As declarações de caixa que um class string carrega, na ordem em que ele as escreveu.
53
+ *
54
+ * SÓ A CLASSE NUA CONTA. Um utilitário com condição na frente - `md:flex`, `hover:grid`,
55
+ * `dark:hidden` - descreve a caixa em OUTRO estado, e escrevê-lo na base afirmaria que
56
+ * aquele estado é o de repouso. Quem lê estado é quem lê estado.
57
+ */
58
+ export function displayFromClasses(classes) {
59
+ const out = {};
60
+ for (const raw of (classes ?? "").split(/\s+/)) {
61
+ if (!raw || raw.includes(":"))
62
+ continue;
63
+ const found = DISPLAY_UTILITIES[raw];
64
+ if (found)
65
+ out[found.property] = found.value;
66
+ }
67
+ return out;
68
+ }
@@ -42,6 +42,7 @@
42
42
  * hover:shadow-md → states.hover
43
43
  * data-[checked]:bg-ocean-50 → states.checked
44
44
  */
45
+ import { DISPLAY_UTILITIES } from "../display-from-class.js";
45
46
  import { tokenRefFor } from "../token-ref.js";
46
47
  import { frameworkDeclaration } from "./framework-palette.js";
47
48
  /**
@@ -384,9 +385,10 @@ const TYPE_KEYWORD = {
384
385
  * and without the position it stopped being a veil and became a block in the flow; the
385
386
  * chevron's `justify-between` is what puts it at the far edge of the header.
386
387
  *
387
- * `flex` and `flex-col` stay OUT on purpose - they travel as the node's own form
388
- * (`row`/`stack`), and declaring the same thing twice is how two sources of truth start
389
- * disagreeing. What comes in here is the DIMENSION (`flex-1`, `shrink-0`) and the PLACE.
388
+ * What comes in here is the DIMENSION (`flex-1`, `shrink-0`), the PLACE, and - since 09/09 -
389
+ * the DISPLAY in full. `flex` and `flex-col` used to be held out so the node's form
390
+ * (`row`/`stack`) would be the single carrier; the display block below says what that cost
391
+ * and why it was reversed.
390
392
  */
391
393
  const PLACE_KEYWORD = {
392
394
  // Position: what makes an overlay an overlay.
@@ -419,12 +421,27 @@ const PLACE_KEYWORD = {
419
421
  "overflow-y-hidden": { property: "overflowY", value: "hidden" },
420
422
  "overflow-x-scroll": { property: "overflowX", value: "scroll" },
421
423
  "overflow-y-scroll": { property: "overflowY", value: "scroll" },
422
- // Display, when it is not the arrangement we already carry as a form.
423
- "inline-flex": { property: "display", value: "inline-flex" },
424
- "inline-block": { property: "display", value: "inline-block" },
425
- inline: { property: "display", value: "inline" },
426
- block: { property: "display", value: "block" },
427
- hidden: { property: "display", value: "none" },
424
+ /**
425
+ * DISPLAY, ALL OF IT - and this reverses the decision written above.
426
+ *
427
+ * WHAT THE CLIENT SAW: their ThemeToggle is `relative grid place-items-center h-11 w-11
428
+ * rounded-full`. Everything survived except the word `grid`, and without it the preview
429
+ * drew a wide capsule with both icons stacked in the top-left corner instead of a round
430
+ * 2.75rem button - because `place-items-center` only does anything inside a grid or a
431
+ * flex box, and because `component-showcase.tsx` asks `base.display != null` to decide
432
+ * whether THEY declared the layout. With no display it answers no, and the shape WE infer
433
+ * beats the one they wrote - the exact inverse of the layout-priority law.
434
+ *
435
+ * `flex` and `flex-col` were held out on the reasoning that they already travel as the
436
+ * node's form (`row`/`stack`) and that declaring it twice starts a disagreement. The
437
+ * disagreement started anyway, because the form is a LOSSY reduction: it answers "across
438
+ * or down", so `grid` arrives as `stack` and `inline-grid` loses its inline-ness.
439
+ *
440
+ * The table itself lives in `display-from-class.ts` - ONE source, because the platform
441
+ * needs the same reading to reach whoever imported before this shipped, without asking
442
+ * them to re-import. The form stays derived from the same class string.
443
+ */
444
+ ...DISPLAY_UTILITIES,
428
445
  // Focus and the pointer: real decisions, and `outline-none` is 21 of theirs.
429
446
  "outline-none": { property: "outline", value: "none" },
430
447
  "cursor-pointer": { property: "cursor", value: "pointer" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.410",
3
+ "version": "0.16.411",
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": {