synthesisui 0.16.212 → 0.16.214
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 +6 -0
- package/dist/commands/import.js +26 -5
- package/dist/doctor/fragments.js +8 -1
- package/dist/doctor/style-ledger.js +17 -0
- package/dist/doctor/transcribe.js +96 -5
- package/dist/doctor/variant-read.js +38 -3
- package/dist/install-marks.js +1 -1
- package/package.json +1 -1
package/dist/anatomy-read.js
CHANGED
|
@@ -469,6 +469,12 @@ sxSpacing) {
|
|
|
469
469
|
base: { ...fromSx, ...t.base },
|
|
470
470
|
dark: t.dark,
|
|
471
471
|
states: t.states,
|
|
472
|
+
/**
|
|
473
|
+
* O TIPO SEMPRE TEVE A CASA E A MONTAGEM NÃO PASSAVA - então a seta do
|
|
474
|
+
* Tooltip real transcrevia `data-[side=top]:top-full` para uma layer e a
|
|
475
|
+
* part chegava sem ela: um posicionador que não posiciona (12/08).
|
|
476
|
+
*/
|
|
477
|
+
...(t.layers?.length ? { layers: t.layers } : {}),
|
|
472
478
|
};
|
|
473
479
|
/**
|
|
474
480
|
* A drop on a PART is still a drop. The root path already says these out loud;
|
package/dist/commands/import.js
CHANGED
|
@@ -30,7 +30,7 @@ import { describeForeign, readStyleIslands, } from "../doctor/style-island.js";
|
|
|
30
30
|
import { buildLedger, describeLedger, } from "../doctor/style-ledger.js";
|
|
31
31
|
import { MUI_DEFAULT_SPACING, readStyledComponents, spacingOf, } from "../doctor/style-props.js";
|
|
32
32
|
import { buildTable } from "../doctor/tokens.js";
|
|
33
|
-
import { definitionSpan, readInlineStyle, rootClasses, rootTag, transcribe, } from "../doctor/transcribe.js";
|
|
33
|
+
import { definitionSpan, parseClass, readInlineStyle, rootClasses, rootTag, transcribe, } from "../doctor/transcribe.js";
|
|
34
34
|
import { transcribeVariants } from "../doctor/variant-read.js";
|
|
35
35
|
import { frontierKind, packageRoot } from "../frontier-kind.js";
|
|
36
36
|
import { withLibraryStructure } from "../library-structure.js";
|
|
@@ -843,10 +843,25 @@ export async function takeCensus(root, opts) {
|
|
|
843
843
|
* animates nothing.
|
|
844
844
|
*/
|
|
845
845
|
for (const node of sketch) {
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
846
|
+
/**
|
|
847
|
+
* O PAR COMPÕE AQUI TAMBÉM - a mesma regra de `composeAnimation`: num elemento
|
|
848
|
+
* que escreve `animate-out fade-out`, o nome que o sistema define é `fade-out`,
|
|
849
|
+
* e `out` sozinho é o motor sem frames. Coletar o motor foi o que pendurou uma
|
|
850
|
+
* animação `in` no censo real (12/08).
|
|
851
|
+
*/
|
|
852
|
+
const utilities = (node.classes ?? "")
|
|
853
|
+
.split(/\s+/)
|
|
854
|
+
.filter(Boolean)
|
|
855
|
+
.map((cls) => parseClass(cls).utility);
|
|
856
|
+
for (const utility of utilities) {
|
|
857
|
+
const named = /^animate-([a-z][\w-]*)$/.exec(utility);
|
|
858
|
+
if (!named || named[1] === "none")
|
|
859
|
+
continue;
|
|
860
|
+
const composed = (named[1] === "in" || named[1] === "out") &&
|
|
861
|
+
utilities.includes(`fade-${named[1]}`)
|
|
862
|
+
? `fade-${named[1]}`
|
|
863
|
+
: named[1];
|
|
864
|
+
animations.add(composed);
|
|
850
865
|
}
|
|
851
866
|
}
|
|
852
867
|
/**
|
|
@@ -890,6 +905,12 @@ export async function takeCensus(root, opts) {
|
|
|
890
905
|
...rootPackage(tag, sketch),
|
|
891
906
|
...rootBehaviour(tag, sketch),
|
|
892
907
|
...(placed.length > 0 ? { layers: placed } : {}),
|
|
908
|
+
/**
|
|
909
|
+
* A MATÉRIA-PRIMA DAS CAMADAS, ainda como classes - ver `raw` em
|
|
910
|
+
* `transcribeVariants`. É o que permite uma tabela de escala nova
|
|
911
|
+
* reinterpretar este censo por deploy, sem `sync` na máquina de ninguém.
|
|
912
|
+
*/
|
|
913
|
+
...(v.raw.length > 0 ? { rawLayers: v.raw } : {}),
|
|
893
914
|
...(Object.keys(islandStyle).length > 0 ? { islandStyle } : {}),
|
|
894
915
|
...(v.unslotted.length > 0
|
|
895
916
|
? { unplaced: [...new Set(v.unslotted)] }
|
package/dist/doctor/fragments.js
CHANGED
|
@@ -309,9 +309,16 @@ export function judgeFragments(seen, declared, admitted) {
|
|
|
309
309
|
? { ...f, read: true }
|
|
310
310
|
: { ...f, read: false, reason: "computed" };
|
|
311
311
|
const t = transcribe(literal.split(/\s+/).filter(Boolean), declared);
|
|
312
|
+
/**
|
|
313
|
+
* AS QUATRO CASAS DA TRANSCRIÇÃO, não três. O `dark:data-[checked]:bg-…` do
|
|
314
|
+
* RadioCard real transcrevia INTEIRO para uma layer `{state, scheme}` e o juiz
|
|
315
|
+
* só contava base/dark/states - então um fragmento 100% lido ficava na fila de
|
|
316
|
+
* `value-not-read`, e o conserto que a fila pedia já estava entregue (12/08).
|
|
317
|
+
*/
|
|
312
318
|
const read = Object.keys(t.base).length +
|
|
313
319
|
Object.keys(t.dark).length +
|
|
314
|
-
Object.values(t.states ?? {}).reduce((n, b) => n + Object.keys(b).length, 0)
|
|
320
|
+
Object.values(t.states ?? {}).reduce((n, b) => n + Object.keys(b).length, 0) +
|
|
321
|
+
(t.layers ?? []).reduce((n, l) => n + Object.keys(l.style).length, 0) >
|
|
315
322
|
0;
|
|
316
323
|
return read
|
|
317
324
|
? { ...f, read: true }
|
|
@@ -68,6 +68,23 @@ const SHAPE_LABEL = {
|
|
|
68
68
|
const A_READER_REACHES = new Set([
|
|
69
69
|
"shape-not-read",
|
|
70
70
|
"binding-not-read",
|
|
71
|
+
/**
|
|
72
|
+
* `value-not-read` ENTROU EM 11/08, e o docstring acima dizia o contrário por um motivo que
|
|
73
|
+
* envelheceu.
|
|
74
|
+
*
|
|
75
|
+
* Ele dizia: *"a forma FOI lida e o valor está fora das escalas deles - texto não ensina nada a
|
|
76
|
+
* leitor nenhum"*. Verdade quando a resposta era um LEITOR. Só que a resposta dela nunca foi um
|
|
77
|
+
* leitor: é uma TABELA DE ESCALA, e a tabela se escreve exatamente do texto - `sr-only`,
|
|
78
|
+
* `flex flex-col`, `data-[side=top]:top-full`.
|
|
79
|
+
*
|
|
80
|
+
* Sem o texto, esses 15 do repo do dono chegavam como número puro, e qualquer conserto nosso
|
|
81
|
+
* exigia que ELE re-medisse. O princípio é o contrário (dono, 12/08): *"o usuário não pode ficar
|
|
82
|
+
* rodando comandos do CLI para confirmar algo que a gente quer resolver - tudo deve estar no
|
|
83
|
+
* censo na entrada"*.
|
|
84
|
+
*
|
|
85
|
+
* O teto de 512 e o texto DISTINTO continuam valendo, e são eles que pagam a conta do tamanho.
|
|
86
|
+
*/
|
|
87
|
+
"value-not-read",
|
|
71
88
|
]);
|
|
72
89
|
const BECAUSE = {
|
|
73
90
|
"shape-not-read": "no reader in this version understands this shape, so the styles it holds reach no recipe",
|
|
@@ -538,8 +538,42 @@ const STATE_SPELLING = {
|
|
|
538
538
|
/** Base UI's enter/exit faces - `data-[starting-style]:opacity-0`. */
|
|
539
539
|
"starting-style": "startingStyle",
|
|
540
540
|
"ending-style": "endingStyle",
|
|
541
|
+
/** O par de `open`, que faltava - `data-[closed]:animate-out` no Modal real. */
|
|
542
|
+
closed: "closed",
|
|
541
543
|
};
|
|
542
|
-
|
|
544
|
+
/**
|
|
545
|
+
* `data-[state=open]:`, `data-[checked]:`, `data-[side=top]:` - a MESMA regra do
|
|
546
|
+
* `conditionOf` em `variant-read.ts`, que ganhou atributo=valor em 12/08 e este arquivo
|
|
547
|
+
* não: `data-[side=top]:top-full` tinha o valor na tabela de offset desde sempre e caía
|
|
548
|
+
* em `skipped` porque a CONDIÇÃO não tinha casa aqui. Os dois julgamentos têm que
|
|
549
|
+
* soletrar igual, senão o fragmento e a variante discordam sobre a mesma classe.
|
|
550
|
+
*/
|
|
551
|
+
const DATA_STATE = /^data-\[([a-z-]+)(?:=([a-z-]+))?\]$/;
|
|
552
|
+
/** `side-top` → `sideTop`, `starting-style` → `startingStyle`. */
|
|
553
|
+
function camelState(name) {
|
|
554
|
+
return name.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* O nome de estado de um modificador `data-[…]`, ou null quando não é um.
|
|
558
|
+
*
|
|
559
|
+
* `state=open` nomeia pelo VALOR (o atributo é só o veículo); qualquer outro atributo
|
|
560
|
+
* com valor nomeia pelos dois, senão `side=top` e `side=left` colidiriam num estado só.
|
|
561
|
+
* O que não está na tabela mas é legível vira estado por transcrição, nunca descartado:
|
|
562
|
+
* `lost` é para o que não dá para ler, não para o que a gente não previu.
|
|
563
|
+
*/
|
|
564
|
+
function dataState(modifier) {
|
|
565
|
+
const data = DATA_STATE.exec(modifier);
|
|
566
|
+
if (!data)
|
|
567
|
+
return null;
|
|
568
|
+
const name = data[1] === "state"
|
|
569
|
+
? (data[2] ?? "")
|
|
570
|
+
: data[2]
|
|
571
|
+
? camelState(`${data[1]}-${data[2]}`)
|
|
572
|
+
: data[1];
|
|
573
|
+
if (!name)
|
|
574
|
+
return null;
|
|
575
|
+
return STATE_SPELLING[name] ?? STATE_SPELLING[data[1]] ?? camelState(name);
|
|
576
|
+
}
|
|
543
577
|
/**
|
|
544
578
|
* Split a class into its modifiers and the utility itself.
|
|
545
579
|
*
|
|
@@ -1478,6 +1512,39 @@ function composeGradient(utilities, declared) {
|
|
|
1478
1512
|
broken,
|
|
1479
1513
|
};
|
|
1480
1514
|
}
|
|
1515
|
+
/**
|
|
1516
|
+
* UMA ENTRADA OU SAÍDA ANIMADA É DUAS UTILITIES QUE SÓ SIGNIFICAM JUNTAS - o mesmo
|
|
1517
|
+
* caso do gradiente, uma família ao lado.
|
|
1518
|
+
*
|
|
1519
|
+
* `data-[closed]:animate-out data-[closed]:fade-out` é como o tailwindcss-animate
|
|
1520
|
+
* escreve "sai desvanecendo": `animate-out` é o motor e não nomeia frame nenhum, e
|
|
1521
|
+
* `fade-out` nomeia os frames e não anima nada sozinho. Lidas isoladas, as duas
|
|
1522
|
+
* respostas eram erradas - `animate-out` virava `var(--animate-out)` apontando para um
|
|
1523
|
+
* keyframe que nenhum tema define, e `fade-out` resolvia para nada e sumia sem rastro.
|
|
1524
|
+
* O Modal do repo real fecha exatamente assim, e o `animate-in fade-in` do mesmo
|
|
1525
|
+
* arquivo já tinha posto uma animação `in` pendurada no censo (12/08).
|
|
1526
|
+
*
|
|
1527
|
+
* Composto por grupo de modificador porque é isso que as duas metades têm em comum -
|
|
1528
|
+
* a mesma regra do gradiente. Só a família `fade` entra: é a medida do repo real, e
|
|
1529
|
+
* `zoom-*`/`slide-in-*` ficam nomeados para quando um censo os trouxer.
|
|
1530
|
+
*/
|
|
1531
|
+
function composeAnimation(utilities) {
|
|
1532
|
+
const engine = utilities.find((u) => /^animate-(?:in|out)$/.test(u));
|
|
1533
|
+
if (!engine)
|
|
1534
|
+
return { value: null, consumed: new Set() };
|
|
1535
|
+
const direction = engine.slice("animate-".length);
|
|
1536
|
+
const effect = utilities.find((u) => u === `fade-${direction}`);
|
|
1537
|
+
if (!effect)
|
|
1538
|
+
return { value: null, consumed: new Set() };
|
|
1539
|
+
return {
|
|
1540
|
+
value: {
|
|
1541
|
+
property: "animation",
|
|
1542
|
+
value: `var(--animate-${effect})`,
|
|
1543
|
+
keyframe: effect,
|
|
1544
|
+
},
|
|
1545
|
+
consumed: new Set([engine, effect]),
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1481
1548
|
/**
|
|
1482
1549
|
* WHICH HALF OF THE TRANSCRIPTION A MODIFIER LIST BELONGS TO.
|
|
1483
1550
|
*
|
|
@@ -1517,10 +1584,7 @@ function slotFor(out, modifiers) {
|
|
|
1517
1584
|
/** `group-hover:`, `group-data-[checked]:` - the PARENT's state. */
|
|
1518
1585
|
const group = /^group-(.+)$/.exec(mod);
|
|
1519
1586
|
const bare = group ? group[1] : mod;
|
|
1520
|
-
const
|
|
1521
|
-
? bare
|
|
1522
|
-
: (DATA_STATE.exec(bare)?.[1] ?? null);
|
|
1523
|
-
const state = raw ? (STATE_SPELLING[raw] ?? null) : null;
|
|
1587
|
+
const state = STATE_SPELLING[bare] ?? dataState(bare);
|
|
1524
1588
|
if (state) {
|
|
1525
1589
|
if (group)
|
|
1526
1590
|
when.within = state;
|
|
@@ -1611,6 +1675,33 @@ export function transcribe(classes, declared) {
|
|
|
1611
1675
|
out.unreadable.push(at);
|
|
1612
1676
|
}
|
|
1613
1677
|
}
|
|
1678
|
+
/** A MESMA COMPOSIÇÃO POR GRUPO, para a família que só significa em par. */
|
|
1679
|
+
for (const group of groups.values()) {
|
|
1680
|
+
const animation = composeAnimation(group.utilities);
|
|
1681
|
+
if (!animation.value)
|
|
1682
|
+
continue;
|
|
1683
|
+
const prefix = group.modifiers.length
|
|
1684
|
+
? `${group.modifiers.join(":")}:`
|
|
1685
|
+
: "";
|
|
1686
|
+
for (const utility of animation.consumed)
|
|
1687
|
+
consumedByGroup.add(`${prefix}${utility}`);
|
|
1688
|
+
const { target, unslotted } = slotFor(out, group.modifiers);
|
|
1689
|
+
if (unslotted || !target) {
|
|
1690
|
+
for (const utility of animation.consumed)
|
|
1691
|
+
out.skipped.push(`${prefix}${utility}`);
|
|
1692
|
+
continue;
|
|
1693
|
+
}
|
|
1694
|
+
const decl = animation.value;
|
|
1695
|
+
if (decl.keyframe) {
|
|
1696
|
+
out.animations ??= [];
|
|
1697
|
+
if (!out.animations.includes(decl.keyframe))
|
|
1698
|
+
out.animations.push(decl.keyframe);
|
|
1699
|
+
}
|
|
1700
|
+
if (target[decl.property] == null) {
|
|
1701
|
+
target[decl.property] = decl.value;
|
|
1702
|
+
out.fromLiteral += 1;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1614
1705
|
for (const cls of classes) {
|
|
1615
1706
|
const { modifiers, utility } = parseClass(cls);
|
|
1616
1707
|
if (consumedByGroup.has(cls))
|
|
@@ -39,6 +39,10 @@ import { parseClass, transcribe } from "./transcribe.js";
|
|
|
39
39
|
* all before. `peer-*` is the sibling version of the same idea and reads the same way
|
|
40
40
|
* from a recipe's point of view.
|
|
41
41
|
*/
|
|
42
|
+
/** `side-top` → `sideTop`, `starting-style` → `startingStyle`. */
|
|
43
|
+
function camel(name) {
|
|
44
|
+
return name.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
45
|
+
}
|
|
42
46
|
const MODIFIER_STATE = {
|
|
43
47
|
hover: "hover",
|
|
44
48
|
focus: "focus",
|
|
@@ -51,6 +55,8 @@ const MODIFIER_STATE = {
|
|
|
51
55
|
selected: "selected",
|
|
52
56
|
highlighted: "highlighted",
|
|
53
57
|
open: "open",
|
|
58
|
+
/** O par de `open`, e a ausência dele matava o `data-[closed]:animate-out` do Modal dele. */
|
|
59
|
+
closed: "closed",
|
|
54
60
|
invalid: "invalid",
|
|
55
61
|
required: "required",
|
|
56
62
|
"read-only": "readOnly",
|
|
@@ -68,8 +74,19 @@ const MODIFIER_STATE = {
|
|
|
68
74
|
};
|
|
69
75
|
/** `group-hover`, `group-focus`, `peer-checked` - the state of something ELSE. */
|
|
70
76
|
const RELATIONAL = /^(?:group|peer)-(.+)$/;
|
|
71
|
-
/**
|
|
72
|
-
|
|
77
|
+
/**
|
|
78
|
+
* `data-[state=open]:`, `data-[checked]:`, `data-[side=top]:` - como @base-ui e Radix escrevem uma
|
|
79
|
+
* condição.
|
|
80
|
+
*
|
|
81
|
+
* A versão anterior aceitava só `state=` ou um nome pelado, então TODO outro atributo com valor caía
|
|
82
|
+
* em `lost`. Medido no repo do dono em 12/08: `data-[side=top]`, `data-[side=bottom]`,
|
|
83
|
+
* `data-[side=left]` e `data-[side=right]` - as quatro posições do Tooltip - morriam ali, e com elas
|
|
84
|
+
* o estilo que só existe quando o popup abre para aquele lado.
|
|
85
|
+
*
|
|
86
|
+
* O atributo E o valor viram o nome, porque é literalmente o que o DOM dele carrega
|
|
87
|
+
* (`data-side="top"`): transcrever não é inventar.
|
|
88
|
+
*/
|
|
89
|
+
const DATA_MODIFIER = /^data-\[([a-z-]+)(?:=([a-z-]+))?\]$/;
|
|
73
90
|
/** A breakpoint is a bare name we cannot read as a state. Their scale names them, so
|
|
74
91
|
* the caller decides whether the name exists rather than this guessing a width. */
|
|
75
92
|
const BREAKPOINT = /^(?:xs|sm|md|lg|xl|2xl|3xl|tablet|desktop|wide|mobile)$/;
|
|
@@ -102,9 +119,26 @@ export function conditionOf(modifiers) {
|
|
|
102
119
|
}
|
|
103
120
|
const data = DATA_MODIFIER.exec(raw);
|
|
104
121
|
if (data) {
|
|
105
|
-
|
|
122
|
+
/**
|
|
123
|
+
* `state=open` nomeia pelo VALOR (o atributo é só o veículo); qualquer outro atributo nomeia
|
|
124
|
+
* pelos dois, senão `side=top` e `side=left` colidiriam num estado só chamado `side`.
|
|
125
|
+
*/
|
|
126
|
+
const nome = data[1] === "state"
|
|
127
|
+
? (data[2] ?? "")
|
|
128
|
+
: data[2]
|
|
129
|
+
? camel(`${data[1]}-${data[2]}`)
|
|
130
|
+
: data[1];
|
|
131
|
+
const state = MODIFIER_STATE[nome] ?? MODIFIER_STATE[data[1]];
|
|
106
132
|
if (state)
|
|
107
133
|
out.state = state;
|
|
134
|
+
/**
|
|
135
|
+
* E O QUE NÃO ESTÁ NA TABELA MAS É LEGÍVEL NÃO SE PERDE. Um `data-side="top"` do base-ui é uma
|
|
136
|
+
* condição do DOM dele, escrita por extenso - descartá-la porque a nossa tabela não a lista
|
|
137
|
+
* seria a tabela decidindo o que o código dele pode dizer. `lost` fica para o que não dá para
|
|
138
|
+
* ler, não para o que a gente não previu.
|
|
139
|
+
*/
|
|
140
|
+
else if (nome)
|
|
141
|
+
out.state = camel(nome);
|
|
108
142
|
else
|
|
109
143
|
out.lost = true;
|
|
110
144
|
continue;
|
|
@@ -1028,6 +1062,7 @@ export function transcribeVariants(source, declared) {
|
|
|
1028
1062
|
axes,
|
|
1029
1063
|
defaults,
|
|
1030
1064
|
layers,
|
|
1065
|
+
raw: allLayers,
|
|
1031
1066
|
base: transcribe(baseClasses, declared),
|
|
1032
1067
|
unslotted,
|
|
1033
1068
|
notes,
|
package/dist/install-marks.js
CHANGED
|
@@ -100,7 +100,7 @@ export const CHECKER_SINCE = "0.16.202";
|
|
|
100
100
|
*
|
|
101
101
|
* Um censo medido antes disto carrega as duas leituras erradas.
|
|
102
102
|
*/
|
|
103
|
-
export const READER_SINCE = "0.16.
|
|
103
|
+
export const READER_SINCE = "0.16.214";
|
|
104
104
|
/**
|
|
105
105
|
* O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
|
|
106
106
|
*
|
package/package.json
CHANGED