synthesisui 0.16.321 → 0.16.323
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 +59 -1
- package/dist/doctor/variant-calls.js +117 -0
- package/dist/doctor/variant-read.js +53 -10
- package/dist/install-marks.js +9 -1
- package/package.json +1 -1
package/dist/commands/import.js
CHANGED
|
@@ -37,6 +37,7 @@ import { MUI_DEFAULT_SPACING, readStyledComponents, spacingOf, } from "../doctor
|
|
|
37
37
|
import { buildTable } from "../doctor/tokens.js";
|
|
38
38
|
import { definitionSpan, parseClass, readInlineStyle, rootClasses, rootTag, transcribe, } from "../doctor/transcribe.js";
|
|
39
39
|
import { accountClasses, invariantHolds, sumAccounts, } from "../doctor/value-ledger.js";
|
|
40
|
+
import { variantCallsIn } from "../doctor/variant-calls.js";
|
|
40
41
|
import { transcribeVariants } from "../doctor/variant-read.js";
|
|
41
42
|
import { frontierKind, packageRoot } from "../frontier-kind.js";
|
|
42
43
|
import { keyframesInSheets } from "../global-keyframes.js";
|
|
@@ -787,6 +788,10 @@ export async function takeCensus(root, opts) {
|
|
|
787
788
|
* variant tables) belong to the PRIMARY definition; the root classes and
|
|
788
789
|
* the root tag are per component, scoped by name.
|
|
789
790
|
*/
|
|
791
|
+
/** Os componentes deste arquivo - quem mora dentro do span de outro é recortado dele. */
|
|
792
|
+
const siblings = found.map((f) => f.name);
|
|
793
|
+
/** As tabelas que ESTE ARQUIVO declara - o conjunto contra o qual um consumo é casado. */
|
|
794
|
+
const declaredTables = new Set(transcribeVariants(src, declaredValues, globalClasses).reads.map((r) => r.symbol));
|
|
790
795
|
for (const extra of found.slice(1)) {
|
|
791
796
|
const ecls = rootClasses(src, extra.name);
|
|
792
797
|
const et = transcribe(ecls, declaredValues);
|
|
@@ -800,6 +805,24 @@ export async function takeCensus(root, opts) {
|
|
|
800
805
|
// sketch belonged to the first component and the second read an empty
|
|
801
806
|
// one (not-expressed.md, dono, 01/08).
|
|
802
807
|
const esketch = sketchOf(src, extra.name);
|
|
808
|
+
/**
|
|
809
|
+
* E AS TABELAS QUE ELE CHAMA (T42a, 27/08) - a família que faltava aqui.
|
|
810
|
+
*
|
|
811
|
+
* Este caminho nunca viu `transcribeVariants`, e o comentário abaixo dizia isso em voz
|
|
812
|
+
* alta: "roda para o primeiro componente do arquivo, então aqui não há tabela de
|
|
813
|
+
* variantes". Era limitação descrita, não decisão - e por causa dela o `TooltipContent`
|
|
814
|
+
* e o `Layer` chegavam sem uma camada sequer enquanto o vizinho ficava com os eixos
|
|
815
|
+
* deles.
|
|
816
|
+
*
|
|
817
|
+
* O CSS module continua FORA daqui de propósito: uma folha `.module.css` é do arquivo, e
|
|
818
|
+
* `parts`/`tree` seguem sendo montados só no caminho primário. A fronteira é a origem do
|
|
819
|
+
* dado - tabela pertence a quem chama, folha pertence ao arquivo.
|
|
820
|
+
*/
|
|
821
|
+
const ev = transcribeVariants(src, declaredValues, globalClasses, {
|
|
822
|
+
tables: variantCallsIn(src, extra.name, declaredTables, siblings),
|
|
823
|
+
/** Só as tabelas dele: as formas de arquivo seguem sendo do primeiro exportado. */
|
|
824
|
+
fileWideShapes: false,
|
|
825
|
+
});
|
|
803
826
|
const esize = Object.keys(et.base).length +
|
|
804
827
|
Object.keys(et.dark).length +
|
|
805
828
|
Object.keys(et.states).length;
|
|
@@ -825,6 +848,25 @@ export async function takeCensus(root, opts) {
|
|
|
825
848
|
}
|
|
826
849
|
: {}),
|
|
827
850
|
...et,
|
|
851
|
+
/** A base dele soma o que a tabela que ELE chama traz - nunca a do vizinho. */
|
|
852
|
+
base: { ...ev.base.base, ...et.base },
|
|
853
|
+
...(Object.keys({ ...ev.base.states, ...et.states }).length > 0
|
|
854
|
+
? { states: { ...ev.base.states, ...et.states } }
|
|
855
|
+
: {}),
|
|
856
|
+
...(ev.layers.length > 0 ? { layers: ev.layers } : {}),
|
|
857
|
+
...(ev.raw.length > 0 ? { rawLayers: ev.raw } : {}),
|
|
858
|
+
...(Object.keys(ev.axes).length > 0
|
|
859
|
+
? { declaredAxes: { ...extra.axes, ...ev.axes } }
|
|
860
|
+
: {}),
|
|
861
|
+
...(Object.keys(ev.defaults).length > 0
|
|
862
|
+
? { defaults: ev.defaults }
|
|
863
|
+
: {}),
|
|
864
|
+
...(ev.unslotted.length > 0
|
|
865
|
+
? { unplaced: [...new Set(ev.unslotted)] }
|
|
866
|
+
: {}),
|
|
867
|
+
...(ev.notes.length > 0
|
|
868
|
+
? { renderNotes: [...new Set(ev.notes)] }
|
|
869
|
+
: {}),
|
|
828
870
|
...(etag ? { rootTag: etag } : {}),
|
|
829
871
|
...rootPackage(etag, esketch),
|
|
830
872
|
...rootBehaviour(etag, esketch),
|
|
@@ -858,7 +900,23 @@ export async function takeCensus(root, opts) {
|
|
|
858
900
|
* for the result, which is the "valid and unread" failure this pipeline has
|
|
859
901
|
* paid for twice already.
|
|
860
902
|
*/
|
|
861
|
-
|
|
903
|
+
/**
|
|
904
|
+
* A TRANSCRIÇÃO É DO COMPONENTE QUE CONSOME A TABELA, não do arquivo (T42a, 27/08).
|
|
905
|
+
*
|
|
906
|
+
* Antes: `transcribeVariants(src, …)` fundia TODAS as tabelas do arquivo e o resultado era
|
|
907
|
+
* gravado aqui, no primeiro componente exportado. Num arquivo com dois, o segundo perdia
|
|
908
|
+
* tudo e o primeiro recebia o que não era dele - o `Tooltip` chegou ao censo com o eixo
|
|
909
|
+
* `side`, que pertence ao `TooltipContent`.
|
|
910
|
+
*
|
|
911
|
+
* `variantCallsIn` responde quais tabelas ESTE componente chama, pelo span da definição
|
|
912
|
+
* dele e só dentro do `className`. Um arquivo de um componente só - que é o caso do
|
|
913
|
+
* `Button` e de todo app do corpus - devolve exatamente o mesmo resultado de antes.
|
|
914
|
+
*/
|
|
915
|
+
const v = transcribeVariants(src, declaredValues, globalClasses, {
|
|
916
|
+
tables: variantCallsIn(src, found[0].name, declaredTables, siblings),
|
|
917
|
+
/** O primeiro exportado continua levando as formas de arquivo, como hoje. */
|
|
918
|
+
fileWideShapes: true,
|
|
919
|
+
});
|
|
862
920
|
/**
|
|
863
921
|
* THE RESTING OPTION, from the definition itself. `cva` says it in
|
|
864
922
|
* `defaultVariants`; a lookup-record component says it in the destructuring -
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { definitionSpan } from "./transcribe.js";
|
|
2
|
+
/** Um literal que uma chamada pode travar: `true`, `false`, `"sm"`, `'md'`. */
|
|
3
|
+
const LITERAL = /^(?:true|false|"[^"]*"|'[^']*'|`[^`$]*`)$/;
|
|
4
|
+
/** Do delimitador de abertura até o que o fecha, respeitando aninhamento. */
|
|
5
|
+
function through(source, open, pair = "{}") {
|
|
6
|
+
let depth = 0;
|
|
7
|
+
for (let i = open; i < source.length; i += 1) {
|
|
8
|
+
const c = source[i];
|
|
9
|
+
if (c === pair[0])
|
|
10
|
+
depth += 1;
|
|
11
|
+
else if (c === pair[1]) {
|
|
12
|
+
depth -= 1;
|
|
13
|
+
if (depth === 0)
|
|
14
|
+
return i;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return -1;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Os argumentos que a chamada TRAVA. `{ size, ring: true }` deixa `size` aberto - é o prop do
|
|
21
|
+
* componente viajando adiante - e trava `ring`, que é a diferença entre um eixo e uma decisão.
|
|
22
|
+
*/
|
|
23
|
+
function fixedArgs(args) {
|
|
24
|
+
const brace = args.indexOf("{");
|
|
25
|
+
if (brace === -1)
|
|
26
|
+
return [];
|
|
27
|
+
const end = through(args, brace);
|
|
28
|
+
if (end === -1)
|
|
29
|
+
return [];
|
|
30
|
+
const parts = [];
|
|
31
|
+
let depth = 0;
|
|
32
|
+
let start = brace + 1;
|
|
33
|
+
for (let i = brace + 1; i <= end; i += 1) {
|
|
34
|
+
const c = args[i];
|
|
35
|
+
if (c === "{" || c === "[" || c === "(")
|
|
36
|
+
depth += 1;
|
|
37
|
+
else if (c === "}" || c === "]" || c === ")") {
|
|
38
|
+
if (i === end) {
|
|
39
|
+
parts.push(args.slice(start, i));
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
depth -= 1;
|
|
43
|
+
}
|
|
44
|
+
else if (c === "," && depth === 0) {
|
|
45
|
+
parts.push(args.slice(start, i));
|
|
46
|
+
start = i + 1;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const out = [];
|
|
50
|
+
for (const part of parts) {
|
|
51
|
+
const colon = part.indexOf(":");
|
|
52
|
+
/** Sem `:` é atalho de objeto (`{ size }`): o prop viaja e o eixo continua aberto. */
|
|
53
|
+
if (colon === -1)
|
|
54
|
+
continue;
|
|
55
|
+
const axis = part.slice(0, colon).trim();
|
|
56
|
+
const value = part.slice(colon + 1).trim();
|
|
57
|
+
if (!axis || !LITERAL.test(value))
|
|
58
|
+
continue;
|
|
59
|
+
out.push({ axis, option: value.replace(/^["'`]|["'`]$/g, "") });
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* As tabelas que ESTE componente consome, dentro do `className` dele.
|
|
65
|
+
*
|
|
66
|
+
* `symbols` é o conjunto que o arquivo declara - recebê-lo em vez de descobrir aqui é o que impede
|
|
67
|
+
* esta função de casar uma chamada qualquer (`cn`, `clsx`, um helper dele) com uma tabela.
|
|
68
|
+
*/
|
|
69
|
+
export function variantCallsIn(source, component, symbols, siblings = []) {
|
|
70
|
+
const span = definitionSpan(source, component);
|
|
71
|
+
if (!span)
|
|
72
|
+
return [];
|
|
73
|
+
/**
|
|
74
|
+
* O CORPO DELE, MENOS O DE QUEM MORA DENTRO. Um componente pode ser declarado dentro de outro, e
|
|
75
|
+
* então o span do de fora contém o do de dentro - herdar dali seria recriar a atribuição errada
|
|
76
|
+
* um nível abaixo. Recortar os irmãos é o que impede isso, e é por lista de nomes, nunca por
|
|
77
|
+
* heurística de posição.
|
|
78
|
+
*/
|
|
79
|
+
const cuts = siblings
|
|
80
|
+
.filter((name) => name !== component)
|
|
81
|
+
.map((name) => definitionSpan(source, name))
|
|
82
|
+
.filter((s) => s !== null && s.from > span.from && s.to <= span.to)
|
|
83
|
+
.sort((a, b) => a.from - b.from);
|
|
84
|
+
let body = "";
|
|
85
|
+
let at = span.from;
|
|
86
|
+
for (const cut of cuts) {
|
|
87
|
+
if (cut.from > at)
|
|
88
|
+
body += source.slice(at, cut.from);
|
|
89
|
+
at = Math.max(at, cut.to);
|
|
90
|
+
}
|
|
91
|
+
body += source.slice(at, span.to);
|
|
92
|
+
const out = [];
|
|
93
|
+
const seen = new Set();
|
|
94
|
+
for (const symbol of symbols) {
|
|
95
|
+
/**
|
|
96
|
+
* TODA CHAMADA DENTRO DO CORPO DELE, não só a que está escrita no `className`.
|
|
97
|
+
*
|
|
98
|
+
* A primeira versão exigia a chamada dentro do atributo, e o `Card` do cliente monta as classes
|
|
99
|
+
* numa variável antes - `const classes = cn(cardVariants({…}), …)` e depois `className={classes}`.
|
|
100
|
+
* Ele perdia os cinco eixos dele de uma vez. O que associa é o SPAN da definição; onde a linha
|
|
101
|
+
* mora dentro dele é estilo de quem escreveu.
|
|
102
|
+
*/
|
|
103
|
+
for (const call of body.matchAll(new RegExp(`\\b${symbol}\\s*\\(`, "g"))) {
|
|
104
|
+
const paren = (call.index ?? 0) + call[0].length - 1;
|
|
105
|
+
const close = through(body, paren, "()");
|
|
106
|
+
if (close === -1)
|
|
107
|
+
continue;
|
|
108
|
+
const key = `${symbol}@${paren}`;
|
|
109
|
+
if (seen.has(key))
|
|
110
|
+
continue;
|
|
111
|
+
seen.add(key);
|
|
112
|
+
/** Só o que está ENTRE os parênteses da chamada - um `{` de depois é de outra linha. */
|
|
113
|
+
out.push({ symbol, fixed: fixedArgs(body.slice(paren + 1, close)) });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
@@ -1157,33 +1157,76 @@ export function transcribeVariants(source, declared,
|
|
|
1157
1157
|
* Sem default de propósito. Um `Map` vazio é a resposta de quem não tem folha global, e ela se
|
|
1158
1158
|
* escreve em voz alta; um parâmetro que se pode esquecer é o defeito que isto está desfazendo.
|
|
1159
1159
|
*/
|
|
1160
|
-
globals
|
|
1161
|
-
|
|
1160
|
+
globals,
|
|
1161
|
+
/**
|
|
1162
|
+
* O QUE ESTE COMPONENTE CONSOME - e a razão de este parâmetro existir.
|
|
1163
|
+
*
|
|
1164
|
+
* Sem ele, a transcrição é do ARQUIVO: todas as tabelas fundidas num resultado só, que o import
|
|
1165
|
+
* gravava no primeiro componente exportado. Num arquivo com dois, o segundo perdia tudo e o
|
|
1166
|
+
* primeiro recebia o que não era dele (T42a, medido em 27/08).
|
|
1167
|
+
*
|
|
1168
|
+
* `undefined` mantém o comportamento de arquivo, que é o certo para quem pergunta sobre o
|
|
1169
|
+
* arquivo. Uma lista restringe às tabelas que aquele componente CHAMA, e aplica o que a chamada
|
|
1170
|
+
* dele trava - `avatarVariants({ size, ring: true })` fixa `ring`, então a camada do `ring` é
|
|
1171
|
+
* base dele e o eixo sai da lista de eixos abertos.
|
|
1172
|
+
*/
|
|
1173
|
+
consumed) {
|
|
1174
|
+
const all = readVariants(source);
|
|
1175
|
+
/**
|
|
1176
|
+
* SÓ AS TABELAS QUE ELE CHAMA. Um componente que não chama nenhuma fica sem camadas de variante -
|
|
1177
|
+
* que é a verdade sobre ele, e não um efeito de ser o segundo do arquivo.
|
|
1178
|
+
*/
|
|
1179
|
+
const wanted = consumed
|
|
1180
|
+
? new Map(consumed.tables.map((c) => [c.symbol, c.fixed]))
|
|
1181
|
+
: null;
|
|
1182
|
+
const reads = wanted ? all.filter((r) => wanted.has(r.symbol)) : all;
|
|
1162
1183
|
const fromRecords = {};
|
|
1163
1184
|
const unslotted = [];
|
|
1164
1185
|
const notes = [];
|
|
1165
|
-
const
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1186
|
+
const fileWide = consumed ? consumed.fileWideShapes : true;
|
|
1187
|
+
const inline = fileWide
|
|
1188
|
+
? [
|
|
1189
|
+
...readInlineConditions(source),
|
|
1190
|
+
// The two shapes the enumeration found to be five times more common than `cva`.
|
|
1191
|
+
...readLookupRecords(source, fromRecords, unslotted),
|
|
1192
|
+
...readClassTernaries(source),
|
|
1193
|
+
]
|
|
1194
|
+
: [];
|
|
1171
1195
|
/**
|
|
1172
1196
|
* O record que um `style=` consome - valores prontos, sem tabela de escala no meio.
|
|
1173
1197
|
* Entram direto nas camadas finais (e registram o eixo), nunca em `raw`: `raw` é
|
|
1174
1198
|
* matéria-prima de reinterpretação por classes, e estes já são o valor final.
|
|
1175
1199
|
*/
|
|
1176
|
-
const styleRecords = readStyleRecords(source, fromRecords);
|
|
1200
|
+
const styleRecords = fileWide ? readStyleRecords(source, fromRecords) : [];
|
|
1177
1201
|
const axes = {};
|
|
1178
1202
|
const defaults = {};
|
|
1179
1203
|
const allLayers = [];
|
|
1180
1204
|
const baseClasses = [];
|
|
1181
1205
|
for (const read of reads) {
|
|
1206
|
+
/**
|
|
1207
|
+
* O QUE A CHAMADA DELE TRAVA. `avatarVariants({ size, ring: true })` diz que este componente
|
|
1208
|
+
* SEMPRE tem `ring` - então a camada daquele eixo aplica sempre (é base dele) e `ring` deixa de
|
|
1209
|
+
* ser um eixo que alguém escolhe. Sem isto, o `AvatarStack` herdaria um eixo `ring` que o
|
|
1210
|
+
* código dele não oferece a ninguém.
|
|
1211
|
+
*/
|
|
1212
|
+
const fixed = new Map((wanted?.get(read.symbol) ?? []).map((f) => [f.axis, f.option]));
|
|
1182
1213
|
baseClasses.push(...read.base);
|
|
1183
|
-
|
|
1214
|
+
for (const [axis, option] of fixed)
|
|
1215
|
+
baseClasses.push(...(read.variants[axis]?.[option] ?? []));
|
|
1216
|
+
allLayers.push(...(fixed.size === 0
|
|
1217
|
+
? read.layers
|
|
1218
|
+
: read.layers.filter((l) => {
|
|
1219
|
+
/** A travada já entrou como base; a de OUTRA opção do mesmo eixo não se aplica. */
|
|
1220
|
+
for (const [axis] of fixed)
|
|
1221
|
+
if (l.when?.variant?.[axis] !== undefined)
|
|
1222
|
+
return false;
|
|
1223
|
+
return true;
|
|
1224
|
+
})));
|
|
1184
1225
|
unslotted.push(...read.unslotted);
|
|
1185
1226
|
Object.assign(defaults, read.defaults);
|
|
1186
1227
|
for (const [axis, options] of Object.entries(read.variants)) {
|
|
1228
|
+
if (fixed.has(axis))
|
|
1229
|
+
continue;
|
|
1187
1230
|
const names = Object.keys(options);
|
|
1188
1231
|
// Two options is what makes a closed set somebody chose from - the same rule
|
|
1189
1232
|
// the contract writer and the doctor already follow.
|
package/dist/install-marks.js
CHANGED
|
@@ -335,8 +335,16 @@ export const CHECKER_SINCE = "0.16.308";
|
|
|
335
335
|
* forte dos três - um produto quase preto entrava na medição como página clara. O que não dá para
|
|
336
336
|
* avaliar (`var(…)`, gradiente) deixa de ser emitido em vez de virar uma face. Isso muda a
|
|
337
337
|
* EVIDÊNCIA que o relatório de import entrega ao agente, e é sobre ela que a face é julgada.
|
|
338
|
+
*
|
|
339
|
+
* 0.16.321 -> 0.16.322 em 27/08: uma tabela de variantes passa a pertencer ao componente que a
|
|
340
|
+
* CHAMA, e não ao primeiro componente exportado do arquivo. Num arquivo com dois, o segundo
|
|
341
|
+
* chegava sem uma camada sequer e o primeiro chegava com o estilo do vizinho - medido no
|
|
342
|
+
* `codelevel-ui`, o `Tooltip` carregava o fundo escuro e o eixo `side` do balão. O hash do corpus
|
|
343
|
+
* NÃO se moveu, e isso é a informação: os 21 apps dourados têm um componente por arquivo, então a
|
|
344
|
+
* estabilidade ali prova ausência de regressão e não ausência de efeito. Quem tem dois componentes
|
|
345
|
+
* num arquivo só vê a correção depois de remedir.
|
|
338
346
|
*/
|
|
339
|
-
export const READER_SINCE = "0.16.
|
|
347
|
+
export const READER_SINCE = "0.16.322";
|
|
340
348
|
/**
|
|
341
349
|
* O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
|
|
342
350
|
*
|
package/package.json
CHANGED