@inchurch/matcha-theme 22.36.1 → 22.37.0
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.
|
@@ -461,3 +461,24 @@ matcha-button-toggle {
|
|
|
461
461
|
}
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
|
+
|
|
465
|
+
// =============================================================================
|
|
466
|
+
// Readonly — seleção legível, clique inerte
|
|
467
|
+
// =============================================================================
|
|
468
|
+
// NENHUMA troca de cor aqui, e é isso que separa `readonly` de `disabled`: o bloco
|
|
469
|
+
// `&[disabled]` acima aplica os mixins `disabled-*-button` nos botões inativos, apagando
|
|
470
|
+
// justamente o contraste que diz qual opção está selecionada. Numa tela cujo propósito é LER
|
|
471
|
+
// esse estado, apagá-lo é o oposto do que se quer.
|
|
472
|
+
//
|
|
473
|
+
// O que muda é só a promessa de interação: o ponteiro deixa de sugerir clique. A inércia em si
|
|
474
|
+
// mora no `onSelect` do componente, não aqui — CSS não deve ser a trava.
|
|
475
|
+
matcha-button-toggle[readonly] {
|
|
476
|
+
|
|
477
|
+
.button-group {
|
|
478
|
+
|
|
479
|
+
button[matcha-button],
|
|
480
|
+
a[matcha-button] {
|
|
481
|
+
cursor: default;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
@@ -13,16 +13,19 @@
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
// ── Hover (off) — bg sutil surface alpha (Figma matcha/state-layer) ─
|
|
16
|
-
|
|
16
|
+
// `[readonly]` entra nas guardas de hover/active junto de `[disabled]`: nao vai
|
|
17
|
+
// acontecer nada no clique, entao prometer interacao e mentir. Mas NAO entra nas regras
|
|
18
|
+
// de COR abaixo — e justamente por isso que readonly existe: o estado continua legivel.
|
|
19
|
+
&:not([disabled]):not([readonly]):hover .matcha-checkbox-container {
|
|
17
20
|
background: var(--matcha-color-surface-hover, rgba(0, 0, 0, 0.04));
|
|
18
21
|
box-shadow: var(--matcha-shadow-1);
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
// ── Hover/Focus quando checked/indeterminate — accent-alpha bg ─────
|
|
22
|
-
&:not([disabled]):hover :is([checked], [indeterminate]) ~ .matcha-checkbox-container,
|
|
25
|
+
&:not([disabled]):not([readonly]):hover :is([checked], [indeterminate]) ~ .matcha-checkbox-container,
|
|
23
26
|
// fallback global (estado checked/indeterminate sem condicional)
|
|
24
|
-
&:not([disabled]):hover .matcha-checkbox-container:has(.matcha-checkbox-icon--checked),
|
|
25
|
-
&:not([disabled]):hover .matcha-checkbox-container:has(.matcha-checkbox-icon--indeterminate) {
|
|
27
|
+
&:not([disabled]):not([readonly]):hover .matcha-checkbox-container:has(.matcha-checkbox-icon--checked),
|
|
28
|
+
&:not([disabled]):not([readonly]):hover .matcha-checkbox-container:has(.matcha-checkbox-icon--indeterminate) {
|
|
26
29
|
background: var(--matcha-color-accent-alpha, rgba(0, 148, 0, 0.1));
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -67,6 +70,14 @@
|
|
|
67
70
|
&[disabled] .matcha-checkbox-label {
|
|
68
71
|
color: var(--matcha-color-disabled-fg);
|
|
69
72
|
}
|
|
73
|
+
|
|
74
|
+
// ── Readonly — cursor de leitura, e NENHUMA troca de cor ───────────
|
|
75
|
+
// O ponteiro deixa de ser `pointer` porque nao ha o que acionar; o glyph e o label
|
|
76
|
+
// ficam com a cor normal, que e o ponto de usar readonly em vez de disabled.
|
|
77
|
+
&[readonly] .matcha-checkbox,
|
|
78
|
+
&[readonly] .matcha-checkbox-container {
|
|
79
|
+
cursor: default;
|
|
80
|
+
}
|
|
70
81
|
}
|
|
71
82
|
}
|
|
72
83
|
|
|
@@ -107,7 +118,7 @@ $matcha-checkbox-touch: 36px;
|
|
|
107
118
|
}
|
|
108
119
|
|
|
109
120
|
// Active overlay — só quando não disabled
|
|
110
|
-
matcha-checkbox:not([disabled]) .matcha-checkbox-container:active::before {
|
|
121
|
+
matcha-checkbox:not([disabled]):not([readonly]) .matcha-checkbox-container:active::before {
|
|
111
122
|
opacity: var(--matcha-state-active);
|
|
112
123
|
}
|
|
113
124
|
|
|
@@ -14,6 +14,29 @@
|
|
|
14
14
|
|
|
15
15
|
@mixin matcha-file-uploader-theme($theme) {
|
|
16
16
|
|
|
17
|
+
// ── Shell (modo múltiplo: moldura única em volta de dropzone + lista) ──
|
|
18
|
+
// Recebe o mesmo tratamento visual da dropzone porque é ELE que passa a ser
|
|
19
|
+
// a "área de upload" quando a lista mora dentro — inclusive o realce de
|
|
20
|
+
// dragover, já que os handlers de drag vivem aqui.
|
|
21
|
+
.matcha-file-uploader-shell {
|
|
22
|
+
background: var(--matcha-color-surface-background, var(--matcha-color-surface-bg));
|
|
23
|
+
border-color: var(--matcha-color-surface-border);
|
|
24
|
+
|
|
25
|
+
&.matcha-file-uploader-dragover {
|
|
26
|
+
background: var(--matcha-color-accent-alpha);
|
|
27
|
+
border-color: var(--matcha-color-accent);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&.matcha-file-uploader-disabled {
|
|
31
|
+
opacity: 0.5;
|
|
32
|
+
// pointer-events + cursor default, não `not-allowed`: constraint #14 do
|
|
33
|
+
// INTERACTION-SYSTEM (o lint de CSS avisa). A dropzone legada abaixo ainda
|
|
34
|
+
// usa not-allowed — rastreado no backlog, fora do escopo desta mudança.
|
|
35
|
+
pointer-events: none;
|
|
36
|
+
cursor: default;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
17
40
|
// ── Dropzone ──
|
|
18
41
|
.matcha-file-uploader-dropzone {
|
|
19
42
|
background: var(--matcha-color-surface-background, var(--matcha-color-surface-bg));
|
|
@@ -29,6 +52,14 @@
|
|
|
29
52
|
cursor: not-allowed;
|
|
30
53
|
pointer-events: none;
|
|
31
54
|
}
|
|
55
|
+
|
|
56
|
+
// Dentro do shell a moldura e o fundo são do shell — a dropzone é só a
|
|
57
|
+
// afordância de clique. Duas classes de propósito: precisa vencer o bloco
|
|
58
|
+
// acima, que tem a mesma especificidade.
|
|
59
|
+
&.matcha-file-uploader-dropzone--inset {
|
|
60
|
+
background: transparent;
|
|
61
|
+
border-color: transparent;
|
|
62
|
+
}
|
|
32
63
|
}
|
|
33
64
|
|
|
34
65
|
.matcha-file-uploader-dropzone__icon-pill {
|
|
@@ -94,8 +125,27 @@
|
|
|
94
125
|
color: var(--matcha-color-text-primary);
|
|
95
126
|
}
|
|
96
127
|
|
|
97
|
-
|
|
128
|
+
// Apagar é vermelho EM REPOUSO, não só no hover: remover arquivo é
|
|
129
|
+
// destrutivo e irreversível, e num modo múltiplo com vários itens
|
|
130
|
+
// empilhados a ação precisa ser distinguível antes de o ponteiro chegar
|
|
131
|
+
// nela (em touch não há hover nenhum). `danger` é papel, não hue —
|
|
132
|
+
// o tema pode remapear.
|
|
133
|
+
//
|
|
134
|
+
// `--matcha-icon-color` é obrigatório, e não redundante com o `color`: o
|
|
135
|
+
// matcha-icon resolve o glyph por `var(--matcha-icon-color, …-icon-default)`
|
|
136
|
+
// (matcha-icon.scss:97) e NÃO herda o `color` do pai. Era por isso que o
|
|
137
|
+
// vermelho antigo de hover nunca chegou a pintar a lixeira.
|
|
138
|
+
&.matcha-file-uploader-file__action--delete {
|
|
98
139
|
color: var(--matcha-color-danger);
|
|
140
|
+
--matcha-icon-color: var(--matcha-color-danger);
|
|
141
|
+
|
|
142
|
+
// Fundo tinted em vez de surface-hover neutro, e a cor é reafirmada
|
|
143
|
+
// porque o :hover genérico acima empurraria text-primary.
|
|
144
|
+
&:hover {
|
|
145
|
+
background: var(--matcha-color-danger-alpha);
|
|
146
|
+
color: var(--matcha-color-danger);
|
|
147
|
+
--matcha-icon-color: var(--matcha-color-danger);
|
|
148
|
+
}
|
|
99
149
|
}
|
|
100
150
|
}
|
|
101
151
|
|
|
@@ -116,6 +166,15 @@
|
|
|
116
166
|
&:hover {
|
|
117
167
|
background: var(--matcha-color-surface-card);
|
|
118
168
|
}
|
|
169
|
+
|
|
170
|
+
// Mesma regra do delete na linha. Aqui só o GLYPH vira danger: o fundo
|
|
171
|
+
// continua sendo a pastilha de surface-card, que é o que garante contraste
|
|
172
|
+
// do ícone sobre uma imagem qualquer — trocá-lo por danger-alpha (10%)
|
|
173
|
+
// deixaria o vermelho competir com a foto atrás.
|
|
174
|
+
&.matcha-file-uploader-card__action--delete {
|
|
175
|
+
color: var(--matcha-color-danger);
|
|
176
|
+
--matcha-icon-color: var(--matcha-color-danger);
|
|
177
|
+
}
|
|
119
178
|
}
|
|
120
179
|
}
|
|
121
180
|
|
|
@@ -137,6 +196,75 @@
|
|
|
137
196
|
width: 100%;
|
|
138
197
|
}
|
|
139
198
|
|
|
199
|
+
// ── Shell (modo múltiplo) ────────────────────────────────────────────────────
|
|
200
|
+
// A "área de upload" quando a lista mora dentro: uma moldura tracejada só,
|
|
201
|
+
// com a dropzone no topo e a lista rolável embaixo. Sem arquivo nenhum o
|
|
202
|
+
// resultado é visualmente idêntico à dropzone solta — só a moldura mudou de
|
|
203
|
+
// dono, do filho para o pai.
|
|
204
|
+
.matcha-file-uploader-shell {
|
|
205
|
+
display: flex;
|
|
206
|
+
flex-direction: column;
|
|
207
|
+
width: 100%;
|
|
208
|
+
box-sizing: border-box;
|
|
209
|
+
border: var(--matcha-border-thin, 2px) dashed transparent;
|
|
210
|
+
border-radius: var(--matcha-radius-lg, 8px);
|
|
211
|
+
overflow: hidden; // o radius precisa cortar a lista que rola por dentro
|
|
212
|
+
transition: background-color var(--matcha-duration-instant, 80ms) linear,
|
|
213
|
+
border-color var(--matcha-duration-instant, 80ms) linear;
|
|
214
|
+
|
|
215
|
+
// Classe de dimensionamento posta NO HOST tem que alcancar o shell — mesmo
|
|
216
|
+
// padrao (e mesmo racional) do matcha-grid, grid.component.scss:11-18. Sem
|
|
217
|
+
// isto, `<matcha-file-uploader class="h-400">` esticaria o host e deixaria o
|
|
218
|
+
// shell na altura do conteudo, e a area continuaria crescendo por dentro.
|
|
219
|
+
//
|
|
220
|
+
// `height: 100%` contra host de altura auto resolve pra `auto`: e no-op para
|
|
221
|
+
// quem nao define altura, portanto value-preserving nos usos existentes.
|
|
222
|
+
height: 100%;
|
|
223
|
+
|
|
224
|
+
// O foco visível é da dropzone interna (o elemento focável), não do shell.
|
|
225
|
+
&:focus-within {
|
|
226
|
+
outline: none;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Com altura definida no host, e a DROPZONE que absorve a sobra: com 1 arquivo
|
|
230
|
+
// ela fica grande e a area nao tem buraco; conforme a lista cresce, cede
|
|
231
|
+
// espaco ate o proprio conteudo (pill + dois textos), que o min-height auto
|
|
232
|
+
// do flex protege de ser esmagado. Sem altura definida, nao ha sobra para
|
|
233
|
+
// distribuir e o resultado e o mesmo de antes.
|
|
234
|
+
.matcha-file-uploader-dropzone--inset {
|
|
235
|
+
flex: 1 1 auto;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// ── Lista de arquivos rolável (dentro do shell) ──────────────────────────────
|
|
240
|
+
// max-height em custom property com fallback, igual --matcha-panel-max-height
|
|
241
|
+
// (280px é o mesmo teto que select/autocomplete/panel já usam para "lista com
|
|
242
|
+
// mais conteúdo abaixo"). Passar `none` devolve o crescimento ilimitado antigo.
|
|
243
|
+
.matcha-file-uploader-list {
|
|
244
|
+
display: flex;
|
|
245
|
+
flex-direction: column;
|
|
246
|
+
gap: var(--matcha-space-100, 8px);
|
|
247
|
+
min-height: 0; // sem isso o floor de min-content impede o scroll no flex
|
|
248
|
+
// Pede o tamanho do conteudo e ENCOLHE quando falta espaco — e ai o scroll
|
|
249
|
+
// interno assume. E o que faz a lista caber quando o host tem altura definida
|
|
250
|
+
// e o teto de 280px seria maior do que sobrou.
|
|
251
|
+
flex: 0 1 auto;
|
|
252
|
+
max-height: var(--matcha-file-uploader-list-max-height, 280px);
|
|
253
|
+
overflow-y: auto;
|
|
254
|
+
overflow-x: hidden; // scrollbar vertical + nowrap gera barra horizontal fantasma
|
|
255
|
+
overscroll-behavior: contain; // o scroll não vaza pra página ao chegar no fim
|
|
256
|
+
-webkit-overflow-scrolling: touch;
|
|
257
|
+
padding: 0 var(--matcha-space-100, 8px) var(--matcha-space-100, 8px);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Dentro da lista o espaçamento é do `gap` — o margin-top do item rolaria
|
|
261
|
+
// junto e daria um respiro fantasma no topo do scroll.
|
|
262
|
+
.matcha-file-uploader-list > .matcha-file-uploader-file,
|
|
263
|
+
.matcha-file-uploader-list > .matcha-file-uploader-card {
|
|
264
|
+
margin-top: 0;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
|
|
140
268
|
// ── Dropzone box (Estado=Dropzone — Figma 16152:209) — a zona INTEIRA é o alvo
|
|
141
269
|
.matcha-file-uploader-dropzone {
|
|
142
270
|
display: flex;
|
|
@@ -157,6 +285,24 @@
|
|
|
157
285
|
}
|
|
158
286
|
}
|
|
159
287
|
|
|
288
|
+
// Dropzone dentro do shell: sem moldura própria (é do shell) e sem o radius
|
|
289
|
+
// que arredondaria um canto interno. Mantém padding, cursor e foco.
|
|
290
|
+
// Precisa vir DEPOIS do bloco base: mesma especificidade (uma classe), então é
|
|
291
|
+
// a ordem que decide — declarado antes, o `border: 2px dashed` do base vencia e
|
|
292
|
+
// sobravam 2px de borda transparente dentro do shell.
|
|
293
|
+
.matcha-file-uploader-dropzone--inset {
|
|
294
|
+
border-width: 0;
|
|
295
|
+
border-radius: 0;
|
|
296
|
+
|
|
297
|
+
// Anel de foco PARA DENTRO. A dropzone inset ocupa a largura toda do shell,
|
|
298
|
+
// que tem `overflow: hidden` (o radius precisa cortar a lista rolável): com o
|
|
299
|
+
// `outline-offset: 2px` do bloco base o anel cai fora da caixa e é ceifado,
|
|
300
|
+
// deixando o alvo de teclado sem indicação visível nas laterais.
|
|
301
|
+
&:focus-visible {
|
|
302
|
+
outline-offset: -2px;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
160
306
|
// layout="card": dropzone vazio compartilha a proporção do card preenchido
|
|
161
307
|
// (aspect-ratio aplicado inline via previewRatio) pra empty e filled terem a
|
|
162
308
|
// MESMA altura lado a lado. Sem isso, vazio é dimensionado por padding/conteúdo
|
|
@@ -369,6 +515,14 @@
|
|
|
369
515
|
width: 20px;
|
|
370
516
|
height: 20px;
|
|
371
517
|
}
|
|
518
|
+
// Com o uploader desabilitado a linha continua legivel, mas as acoes saem de
|
|
519
|
+
// operacao. `pointer-events: none` + `cursor: default` em vez de
|
|
520
|
+
// `not-allowed`: constraint #14 do INTERACTION-SYSTEM.
|
|
521
|
+
&:disabled {
|
|
522
|
+
opacity: var(--matcha-opacity-disabled, 0.38);
|
|
523
|
+
pointer-events: none;
|
|
524
|
+
cursor: default;
|
|
525
|
+
}
|
|
372
526
|
}
|
|
373
527
|
|
|
374
528
|
// ── Card layout — preview preenchido 16:9 + ações no hover (Estado=Drop filled) ──
|
|
@@ -429,6 +583,14 @@
|
|
|
429
583
|
width: 18px;
|
|
430
584
|
height: 18px;
|
|
431
585
|
}
|
|
586
|
+
|
|
587
|
+
// Mesma regra da acao da linha: desabilitado sai de operacao sem virar
|
|
588
|
+
// `not-allowed` (constraint #14 do INTERACTION-SYSTEM).
|
|
589
|
+
&:disabled {
|
|
590
|
+
opacity: var(--matcha-opacity-disabled, 0.38);
|
|
591
|
+
pointer-events: none;
|
|
592
|
+
cursor: default;
|
|
593
|
+
}
|
|
432
594
|
}
|
|
433
595
|
|
|
434
596
|
// ── Cropper inline (modo crop: imagem única) ──────────────────────────────
|
|
@@ -464,6 +626,7 @@
|
|
|
464
626
|
|
|
465
627
|
// ── Reduced motion ───────────────────────────────────────────────────────────
|
|
466
628
|
@media (prefers-reduced-motion: reduce) {
|
|
629
|
+
.matcha-file-uploader-shell,
|
|
467
630
|
.matcha-file-uploader-dropzone,
|
|
468
631
|
.matcha-file-uploader-file__progress-fill,
|
|
469
632
|
.matcha-file-uploader-file__action,
|
|
@@ -424,6 +424,33 @@
|
|
|
424
424
|
--matcha-table-cell-bg: var(--matcha-table-row-bg-hover-accent);
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
+
// O ALVO é a CÉLULA inteira, não só o texto do nome.
|
|
428
|
+
//
|
|
429
|
+
// A âncora envolve o nome, e em título curto isso vira um alvo de poucos pixels —
|
|
430
|
+
// reclamação de quem usa, medida em séries. O `::after` esticado resolve sem trocar
|
|
431
|
+
// a âncora por handler de clique: o href continua existindo, então ctrl+clique,
|
|
432
|
+
// clique do meio e "abrir em nova aba" seguem funcionando, e o foco de teclado
|
|
433
|
+
// continua sendo o do link.
|
|
434
|
+
//
|
|
435
|
+
// De quebra conserta o hover: a regra acima só pinta a linha quando o mouse está
|
|
436
|
+
// sobre o TEXTO. Com a área esticada, pinta ao entrar na célula — que é o que faz
|
|
437
|
+
// a linha parecer clicável.
|
|
438
|
+
//
|
|
439
|
+
// Escopado em `.matcha-table td` de propósito: `a[matcha-cell-link]` também aparece
|
|
440
|
+
// em card de listagem, fora de tabela, e lá o link deve seguir do tamanho do texto.
|
|
441
|
+
//
|
|
442
|
+
// O custo é a seleção de texto DENTRO desta célula. No resto da linha continua
|
|
443
|
+
// funcionando, que é a diferença para a linha toda clicável.
|
|
444
|
+
td:has(a[matcha-cell-link]) {
|
|
445
|
+
position: relative;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
td a[matcha-cell-link]::after {
|
|
449
|
+
content: '';
|
|
450
|
+
position: absolute;
|
|
451
|
+
inset: 0;
|
|
452
|
+
}
|
|
453
|
+
|
|
427
454
|
tbody tr.is-selected td {
|
|
428
455
|
--matcha-table-cell-bg: var(--matcha-table-row-bg-selected);
|
|
429
456
|
}
|
|
@@ -46,6 +46,17 @@
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
// Texto do tooltip — `pre-line` respeita as quebras (`\n`) que o directive insere
|
|
50
|
+
// entre os itens quando `matchaTooltip` recebe um array (1 informação por linha);
|
|
51
|
+
// linhas longas ainda quebram normalmente. O alinhamento vem da custom property
|
|
52
|
+
// `--matcha-tooltip-text-align` que o directive seta a partir de `matchaTooltipAlign`
|
|
53
|
+
// (default center) — só é perceptível com múltiplas linhas.
|
|
54
|
+
.matcha-tooltip-text {
|
|
55
|
+
white-space: pre-line;
|
|
56
|
+
overflow-wrap: anywhere;
|
|
57
|
+
text-align: var(--matcha-tooltip-text-align, center);
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
// ── Arrow (mesma cor do bg) — 13.856×6 — ::after triangular ────────────────
|
|
50
61
|
// Tamanho via border-style: solid trick. base 13.856 ≈ 2×7px borders → border-width
|
|
51
62
|
// horizontal ~7, vertical 6. Mantemos arredondado pelo Figma (13.856 × 6).
|