synthesisui 0.16.130 → 0.16.131
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.
|
@@ -467,9 +467,16 @@ versionOf) {
|
|
|
467
467
|
*/
|
|
468
468
|
if (hasKids && as !== "row" && as !== "stack")
|
|
469
469
|
as = arrangement(classes);
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
470
|
+
/**
|
|
471
|
+
* A plain structural box earns a name only when it carries decisions - and it must earn
|
|
472
|
+
* one, because the name is what the class string travels on.
|
|
473
|
+
*
|
|
474
|
+
* UMA CLASSE DE MODULE TAMBÉM É DECISÃO. Num app de CSS Modules o elemento veste
|
|
475
|
+
* `className={styles.content}` e nenhuma string: sem isto o nó não ganhava nome, não virava
|
|
476
|
+
* part, e o bloco de 16 declarações lido do module não tinha onde pousar. O Tooltip dele
|
|
477
|
+
* chegava com 2 das 35 (04/08).
|
|
478
|
+
*/
|
|
479
|
+
if (!name && (classes || node.moduleClass))
|
|
473
480
|
name = "box";
|
|
474
481
|
/**
|
|
475
482
|
* A NODE WHOSE CONTENT IS THE CALLER'S is a slot, and it keeps its own name
|
package/dist/commands/import.js
CHANGED
|
@@ -2174,6 +2174,43 @@ async function resolveReadParts(census, root) {
|
|
|
2174
2174
|
}
|
|
2175
2175
|
target.base = { ...style, ...target.base };
|
|
2176
2176
|
}
|
|
2177
|
+
/**
|
|
2178
|
+
* O QUE UM CSS MODULE DECLAROU, ONTO THE PART THAT WEARS THAT CLASS.
|
|
2179
|
+
*
|
|
2180
|
+
* Num app de CSS Modules a classe do module é a identidade do elemento, e a anatomia dá
|
|
2181
|
+
* outro nome ao mesmo nó - o `content` do Tooltip dele vira `text` pelo papel. As duas
|
|
2182
|
+
* listas nunca se encontravam, porque a junção era por NOME: o módulo entregava
|
|
2183
|
+
* `parts.content` com 16 declarações e a anatomia substituía tudo por `parts.text` vazia.
|
|
2184
|
+
* As 35 declarações do Tooltip chegavam como 2 (04/08).
|
|
2185
|
+
*
|
|
2186
|
+
* A junção é por CLASSE, que é um dado do próprio nó - ver `SketchNode.moduleClass`. Uma
|
|
2187
|
+
* classe cujo nó a anatomia não nomeia é dita em voz alta, nunca empurrada para a raiz.
|
|
2188
|
+
*/
|
|
2189
|
+
const sketch = (look?.sketch ?? []);
|
|
2190
|
+
const fromModule = look?.parts ?? {};
|
|
2191
|
+
for (const [index, node] of sketch.entries()) {
|
|
2192
|
+
const cls = node.moduleClass;
|
|
2193
|
+
if (!cls)
|
|
2194
|
+
continue;
|
|
2195
|
+
const block = fromModule[cls];
|
|
2196
|
+
if (!block)
|
|
2197
|
+
continue;
|
|
2198
|
+
const part = partAt[index];
|
|
2199
|
+
const target = part ? resolved.parts[part] : undefined;
|
|
2200
|
+
if (!target) {
|
|
2201
|
+
notes.add(`\`.${cls}\` in a CSS module styles an element the anatomy does not name, so it is not applied - putting it on the component would paint the wrong thing`);
|
|
2202
|
+
continue;
|
|
2203
|
+
}
|
|
2204
|
+
/** O que a class string já disse ganha: um utilitário no mesmo elemento é mais recente. */
|
|
2205
|
+
target.base = { ...block.base, ...target.base };
|
|
2206
|
+
if (Object.keys(block.dark ?? {}).length > 0)
|
|
2207
|
+
target.dark = { ...block.dark, ...target.dark };
|
|
2208
|
+
for (const [state, decls] of Object.entries(block.states ?? {}))
|
|
2209
|
+
target.states = {
|
|
2210
|
+
...target.states,
|
|
2211
|
+
[state]: { ...decls, ...(target.states?.[state] ?? {}) },
|
|
2212
|
+
};
|
|
2213
|
+
}
|
|
2177
2214
|
/**
|
|
2178
2215
|
* REPLACED, NOT APPENDED - because this runs more than once.
|
|
2179
2216
|
*
|
|
@@ -83,7 +83,19 @@ function rules(css, media = null, out = []) {
|
|
|
83
83
|
const open = css.indexOf("{", i);
|
|
84
84
|
if (open === -1)
|
|
85
85
|
break;
|
|
86
|
-
|
|
86
|
+
/**
|
|
87
|
+
* O SELETOR É O QUE VEM DEPOIS DA ÚLTIMA DECLARAÇÃO, não o texto todo até a chave.
|
|
88
|
+
*
|
|
89
|
+
* Num CSS plano o cabeçalho de uma regra já vem limpo, e por isso isto passou. Num `.scss`
|
|
90
|
+
* aninhado não: o corpo de `.content` é
|
|
91
|
+
*
|
|
92
|
+
* background-color: …; border-radius: 4px; .header {
|
|
93
|
+
*
|
|
94
|
+
* e o cabeçalho da regra do `.header` saía com as duas declarações grudadas na frente.
|
|
95
|
+
* `classesIn` então achava fragmentos como `0` (de `opacity: 0`) e 12 seletores por arquivo
|
|
96
|
+
* iam para `unslotted` (04/08).
|
|
97
|
+
*/
|
|
98
|
+
const head = css.slice(i, open).split(/[;}]/).pop()?.trim() ?? "";
|
|
87
99
|
// Balance to the matching close, because an at-rule contains whole rules.
|
|
88
100
|
let depth = 0;
|
|
89
101
|
let close = -1;
|
|
@@ -113,6 +125,33 @@ function rules(css, media = null, out = []) {
|
|
|
113
125
|
}
|
|
114
126
|
else if (head) {
|
|
115
127
|
out.push({ selector: head, body, media });
|
|
128
|
+
/**
|
|
129
|
+
* UM BLOCO ANINHADO É UMA REGRA, e não texto do pai.
|
|
130
|
+
*
|
|
131
|
+
* Esta varredura era plana, e num `.scss` isso significa que
|
|
132
|
+
*
|
|
133
|
+
* [data-theme="light"] { .container { .content { background } } }
|
|
134
|
+
*
|
|
135
|
+
* produzia UMA regra: seletor `[data-theme="light"]`, sem classe nenhuma, então
|
|
136
|
+
* `unslotted` - e o bloco inteiro ia para o lixo. Já a versão sem tema produzia
|
|
137
|
+
* `.container` com TODAS as declarações de todos os níveis, porque `declarations()`
|
|
138
|
+
* varre o corpo e o corpo é o arquivo. Medido no repo dele (04/08): 196 de 200 modules
|
|
139
|
+
* usam aninhamento, o Tooltip saiu com 19 declarações na raiz e 4 classes perdidas, 969
|
|
140
|
+
* de 1637 parts vieram vazias, e 109 blocos dark viraram 5.
|
|
141
|
+
*
|
|
142
|
+
* Descer com o seletor do pai na mão resolve os três de uma vez: o filho passa a ter
|
|
143
|
+
* seletor completo, `classesIn` acha a classe certa, a relação pai-filho é registrada, e
|
|
144
|
+
* `[data-theme="dark"] .x` casa o teste de tema. O `&` do Sass é resolvido contra o pai,
|
|
145
|
+
* que é o que ele significa.
|
|
146
|
+
*/
|
|
147
|
+
for (const nested of rules(body, media)) {
|
|
148
|
+
out.push({
|
|
149
|
+
...nested,
|
|
150
|
+
selector: nested.selector.includes("&")
|
|
151
|
+
? nested.selector.replace(/&/g, head)
|
|
152
|
+
: `${head} ${nested.selector}`,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
116
155
|
}
|
|
117
156
|
i = close + 1;
|
|
118
157
|
}
|
|
@@ -121,8 +160,22 @@ function rules(css, media = null, out = []) {
|
|
|
121
160
|
/** `prop: value;` pairs, in the camelCase the contract uses. */
|
|
122
161
|
function declarations(body) {
|
|
123
162
|
const out = {};
|
|
124
|
-
|
|
125
|
-
|
|
163
|
+
/**
|
|
164
|
+
* SÓ O NÍVEL DE CIMA - e "só" exige repetir, porque um module aninha mais de um nível.
|
|
165
|
+
*
|
|
166
|
+
* Uma passada tira o bloco mais interno e deixa o do meio aberto, então as declarações do
|
|
167
|
+
* meio vazavam para o pai: `.card { padding; .title { font-size; > h3 { margin } } }` dava
|
|
168
|
+
* `font-size` ao card e `margin` ao title. Com 196 de 200 modules dele aninhando e a maioria
|
|
169
|
+
* em três níveis, é o vazamento que fazia a raiz vestir o module inteiro (04/08).
|
|
170
|
+
*/
|
|
171
|
+
let flat = body;
|
|
172
|
+
for (let guard = 0; guard < 12; guard++) {
|
|
173
|
+
const next = flat.replace(/\{[^{}]*\}/g, "");
|
|
174
|
+
if (next === flat)
|
|
175
|
+
break;
|
|
176
|
+
flat = next;
|
|
177
|
+
}
|
|
178
|
+
flat = flat.replace(/[^;{}]*\{/g, "");
|
|
126
179
|
for (const piece of flat.split(";")) {
|
|
127
180
|
const colon = piece.indexOf(":");
|
|
128
181
|
if (colon === -1)
|
package/dist/doctor/sketch.js
CHANGED
|
@@ -427,6 +427,11 @@ function closeOf(source, open) {
|
|
|
427
427
|
}
|
|
428
428
|
return -1;
|
|
429
429
|
}
|
|
430
|
+
/**
|
|
431
|
+
* `className={styles.content}` e `className={s.content}` - a forma que um app de CSS Modules
|
|
432
|
+
* usa em todo elemento. O identificador é o import do module, e a propriedade é a classe.
|
|
433
|
+
*/
|
|
434
|
+
const MODULE_CLASS = /className=\{\s*([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)\s*\}/;
|
|
430
435
|
export function sketchOf(source, name) {
|
|
431
436
|
/**
|
|
432
437
|
* READ THE IMPORTS BEFORE SLICING - they live at the top of the file, and the
|
|
@@ -519,6 +524,10 @@ export function sketchOf(source, name) {
|
|
|
519
524
|
const list = repeatOf(source, event.at);
|
|
520
525
|
if (list)
|
|
521
526
|
node.repeats = list;
|
|
527
|
+
/** A classe de module que ele veste - ver `moduleClass`. */
|
|
528
|
+
const mod = MODULE_CLASS.exec(event.body);
|
|
529
|
+
if (mod)
|
|
530
|
+
node.moduleClass = mod[2];
|
|
522
531
|
// What has to be true for this element to exist at all - see `guardAt`.
|
|
523
532
|
const guard = guardAt(source, event.at);
|
|
524
533
|
if (guard) {
|
package/package.json
CHANGED