@inchurch/matcha-theme 22.21.1 → 22.21.3
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.
|
@@ -1,13 +1,247 @@
|
|
|
1
1
|
@use "../abstracts/media-breakpoint" as *;
|
|
2
2
|
@use "../tokens/breakpoints-tokens" as *;
|
|
3
3
|
// =============================================================================
|
|
4
|
-
// matcha-form-field.scss —
|
|
5
|
-
//
|
|
6
|
-
// - tipografia do input (size por breakpoint)
|
|
7
|
-
// - placeholder color
|
|
8
|
-
// - disabled text color
|
|
4
|
+
// matcha-form-field.scss — FONTE ÚNICA de estilo do matcha-form-field
|
|
5
|
+
// (estrutura, states, sizes, tipografia). O component SCSS é comment-only.
|
|
9
6
|
// =============================================================================
|
|
10
7
|
|
|
8
|
+
// ═══ Estrutura e states (migrado do matcha-form-field.component.scss) ═══════
|
|
9
|
+
// Histórico: estas regras viviam no SCSS do componente (ViewEncapsulation.
|
|
10
|
+
// Emulated). Seletor de host escrito como `matcha-form-field[...]` ganhava
|
|
11
|
+
// sufixo [_ngcontent-…] e virava CSS morto — caso do disabled, cuja opacity
|
|
12
|
+
// nunca aplicou. Global no tema, o que está escrito é o que vale; os antigos
|
|
13
|
+
// ::ng-deep viram seletores diretos.
|
|
14
|
+
|
|
15
|
+
// Wrapper stacked: Label → gap → Box → gap → Hint (Figma matcha/field/_base)
|
|
16
|
+
.matcha-form-field-wrapper {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
align-items: flex-start;
|
|
20
|
+
gap: var(--matcha-space-075, 6px); // Figma matcha/field/text: gap 6px entre label/box/hint
|
|
21
|
+
width: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Box do input — onde fica o input/select/textarea
|
|
25
|
+
// Figma: align-self: stretch → ocupa toda a largura do wrapper
|
|
26
|
+
.matcha-form-field {
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: row;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: var(--matcha-space-100, 8px);
|
|
31
|
+
width: 100%; // stretch pro wrapper
|
|
32
|
+
min-height: 44px; // MD default
|
|
33
|
+
padding: 0 var(--matcha-space-150, 12px); // pad horizontal 12
|
|
34
|
+
border: var(--matcha-border-thin, 2px) solid var(--matcha-color-surface-border, #E1E7E2);
|
|
35
|
+
border-radius: var(--matcha-radius-lg, 8px);
|
|
36
|
+
background: transparent;
|
|
37
|
+
box-sizing: border-box;
|
|
38
|
+
transition: border-color var(--matcha-duration-fast, 200ms);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Slots prefix/suffix — elementos decorativos antes/depois do input
|
|
42
|
+
.matcha-form-field .matcha-form-field-prefix,
|
|
43
|
+
.matcha-form-field .matcha-form-field-suffix {
|
|
44
|
+
display: inline-flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
flex: none;
|
|
47
|
+
color: var(--matcha-color-text-label);
|
|
48
|
+
font-family: var(--matcha-font-family);
|
|
49
|
+
font-size: var(--matcha-font-size-sm, 14px);
|
|
50
|
+
font-weight: var(--matcha-weight-regular, 400);
|
|
51
|
+
line-height: var(--matcha-leading-body-md, 20px);
|
|
52
|
+
user-select: none;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.matcha-form-field .matcha-form-field-prefix:not(:empty) + * {
|
|
56
|
+
padding-left: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Hover / focus-within (Figma matcha/field/_base State=Focus).
|
|
60
|
+
// Disabled não chega aqui (pointer-events: none nas regras de disabled abaixo);
|
|
61
|
+
// readonly neutraliza o hover na regra própria de readonly; error e data-color
|
|
62
|
+
// vencem por especificidade/ordem.
|
|
63
|
+
.matcha-form-field:hover {
|
|
64
|
+
border-color: var(--matcha-color-surface-border-strong);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.matcha-form-field:focus-within {
|
|
68
|
+
border-color: var(--matcha-color-primary, #1664C2);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Color variants via data-color — override border-color
|
|
72
|
+
.matcha-form-field[data-color="accent"] { border-color: var(--matcha-color-accent); }
|
|
73
|
+
.matcha-form-field[data-color="primary"] { border-color: var(--matcha-color-primary); }
|
|
74
|
+
.matcha-form-field[data-color="danger"] { border-color: var(--matcha-color-danger); }
|
|
75
|
+
.matcha-form-field[data-color="warn"] { border-color: var(--matcha-color-warn); }
|
|
76
|
+
.matcha-form-field[data-color="success"] { border-color: var(--matcha-color-success); }
|
|
77
|
+
.matcha-form-field[data-color="info"] { border-color: var(--matcha-color-info); }
|
|
78
|
+
|
|
79
|
+
// Sizes (Figma heights): SM 36, MD 44, LG 52.
|
|
80
|
+
// Alturas não são responsivas — a tipografia responsiva fica no mixin abaixo.
|
|
81
|
+
matcha-form-field[size="sm"] .matcha-form-field,
|
|
82
|
+
matcha-form-field[size="tiny"] .matcha-form-field,
|
|
83
|
+
matcha-form-field[size="small"] .matcha-form-field {
|
|
84
|
+
min-height: 36px;
|
|
85
|
+
padding: 0 var(--matcha-space-150, 12px);
|
|
86
|
+
}
|
|
87
|
+
matcha-form-field[size="md"] .matcha-form-field,
|
|
88
|
+
matcha-form-field[size="medium"] .matcha-form-field {
|
|
89
|
+
min-height: 44px;
|
|
90
|
+
padding: 0 var(--matcha-space-150, 12px);
|
|
91
|
+
}
|
|
92
|
+
matcha-form-field[size="lg"] .matcha-form-field,
|
|
93
|
+
matcha-form-field[size="large"] .matcha-form-field,
|
|
94
|
+
matcha-form-field[size="huge"] .matcha-form-field {
|
|
95
|
+
min-height: 52px;
|
|
96
|
+
padding: 0 var(--matcha-space-200, 16px);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Disabled — Figma aplica opacity 0.38 no WRAPPER inteiro
|
|
100
|
+
// (label, field-box e hint ficam apagados de uma vez).
|
|
101
|
+
// EXCEÇÃO: tooltip do label preserva opacity=1 e pointer-events pra manter a
|
|
102
|
+
// pergunta "por que desabilitado?" respondível (UX crítico pra forms complexos).
|
|
103
|
+
// Sem border-color especial: o token interaction-disabled-border tem MAIS
|
|
104
|
+
// contraste que a borda normal e anulava o esmaecimento — a borda fica a normal
|
|
105
|
+
// e a opacity apaga o conjunto uniformemente.
|
|
106
|
+
matcha-form-field[disabled]:not([disabled="false"]) {
|
|
107
|
+
opacity: var(--matcha-opacity-disabled, 0.38);
|
|
108
|
+
|
|
109
|
+
.matcha-form-field {
|
|
110
|
+
pointer-events: none;
|
|
111
|
+
cursor: default;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Tooltip icon continua interativo e legível mesmo com wrapper disabled
|
|
115
|
+
.matcha-label-tooltip {
|
|
116
|
+
opacity: calc(1 / var(--matcha-opacity-disabled, 0.38));
|
|
117
|
+
pointer-events: auto;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Fallback legado (classe aplicada via JS quando o input interno tem disabled);
|
|
122
|
+
// cursor/cores de texto dessa classe vivem no theme mixin mais abaixo.
|
|
123
|
+
.matcha-form-field-disabled {
|
|
124
|
+
pointer-events: none;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Error state (Figma: border danger) — via @Input() error ou data-color="danger"
|
|
128
|
+
matcha-form-field[error]:not([error="false"]) .matcha-form-field {
|
|
129
|
+
border-color: var(--matcha-color-danger);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ─── Simulação de states em docs/playgrounds ────────────────────────────
|
|
133
|
+
matcha-form-field.is-state-focus .matcha-form-field {
|
|
134
|
+
border-color: var(--matcha-color-primary) !important;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
matcha-form-field.is-state-disabled {
|
|
138
|
+
opacity: var(--matcha-opacity-disabled, 0.38);
|
|
139
|
+
pointer-events: none;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ─── Field-range override (Figma matcha/field/range) ────────────────────
|
|
143
|
+
// Field-range renderiza DUAS caixas bordadas próprias (start/end com separador).
|
|
144
|
+
// O form-field externo NÃO deve desenhar sua box — apenas empilha label + range + hint.
|
|
145
|
+
.matcha-form-field:has(matcha-field-range) {
|
|
146
|
+
border: none;
|
|
147
|
+
background: transparent;
|
|
148
|
+
padding: 0;
|
|
149
|
+
min-height: 0;
|
|
150
|
+
gap: 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
matcha-form-field[size="sm"] .matcha-form-field:has(matcha-field-range),
|
|
154
|
+
matcha-form-field[size="tiny"] .matcha-form-field:has(matcha-field-range),
|
|
155
|
+
matcha-form-field[size="small"] .matcha-form-field:has(matcha-field-range),
|
|
156
|
+
matcha-form-field[size="md"] .matcha-form-field:has(matcha-field-range),
|
|
157
|
+
matcha-form-field[size="medium"] .matcha-form-field:has(matcha-field-range),
|
|
158
|
+
matcha-form-field[size="lg"] .matcha-form-field:has(matcha-field-range),
|
|
159
|
+
matcha-form-field[size="large"] .matcha-form-field:has(matcha-field-range),
|
|
160
|
+
matcha-form-field[size="huge"] .matcha-form-field:has(matcha-field-range) {
|
|
161
|
+
min-height: 0;
|
|
162
|
+
padding: 0;
|
|
163
|
+
border: none;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Erro: não mexe na borda do wrapper (já é none), a cor do erro vai para as halves
|
|
167
|
+
matcha-form-field[error]:not([error="false"]) .matcha-form-field:has(matcha-field-range) {
|
|
168
|
+
border: none;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ─── Textarea override (Figma matcha/field/textarea) ────────────────────
|
|
172
|
+
// Quando o field contém textarea, o wrapper vira column + padding all-sides
|
|
173
|
+
// Heights por size: SM 80px · MD 100px · LG 120px
|
|
174
|
+
.matcha-form-field:has(textarea) {
|
|
175
|
+
flex-direction: column;
|
|
176
|
+
align-items: flex-start;
|
|
177
|
+
padding: var(--matcha-space-150, 12px);
|
|
178
|
+
min-height: 80px; // fallback SM
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
matcha-form-field[size="sm"] .matcha-form-field:has(textarea),
|
|
182
|
+
matcha-form-field[size="tiny"] .matcha-form-field:has(textarea),
|
|
183
|
+
matcha-form-field[size="small"] .matcha-form-field:has(textarea) {
|
|
184
|
+
min-height: 80px;
|
|
185
|
+
padding: var(--matcha-space-150, 12px);
|
|
186
|
+
}
|
|
187
|
+
matcha-form-field[size="md"] .matcha-form-field:has(textarea),
|
|
188
|
+
matcha-form-field[size="medium"] .matcha-form-field:has(textarea) {
|
|
189
|
+
min-height: 100px;
|
|
190
|
+
padding: var(--matcha-space-150, 12px);
|
|
191
|
+
}
|
|
192
|
+
matcha-form-field[size="lg"] .matcha-form-field:has(textarea),
|
|
193
|
+
matcha-form-field[size="large"] .matcha-form-field:has(textarea),
|
|
194
|
+
matcha-form-field[size="huge"] .matcha-form-field:has(textarea) {
|
|
195
|
+
min-height: 120px;
|
|
196
|
+
padding: var(--matcha-space-150, 12px) var(--matcha-space-200, 16px);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ─── Search: ícone lupa automático após o input[type=search] (Figma suffix icon) ──
|
|
200
|
+
// Mesmo padding horizontal dos outros fields. Por size: SM 16 · MD 20 · LG 24.
|
|
201
|
+
.matcha-form-field:has(input[type="search"])::after {
|
|
202
|
+
content: '\e90c'; // codepoint "search" em MatchaIcons
|
|
203
|
+
font-family: 'MatchaIcons' !important; // fonte registrada no projects/matcha-icons/matcha-icons.css
|
|
204
|
+
font-weight: normal;
|
|
205
|
+
font-style: normal;
|
|
206
|
+
font-variant: normal;
|
|
207
|
+
speak: none;
|
|
208
|
+
text-transform: none;
|
|
209
|
+
-webkit-font-smoothing: antialiased;
|
|
210
|
+
color: var(--matcha-color-text-placeholder);
|
|
211
|
+
font-size: 16px;
|
|
212
|
+
line-height: 16px;
|
|
213
|
+
flex: none;
|
|
214
|
+
pointer-events: none;
|
|
215
|
+
display: inline-flex;
|
|
216
|
+
align-items: center;
|
|
217
|
+
justify-content: center;
|
|
218
|
+
}
|
|
219
|
+
matcha-form-field[size="md"] .matcha-form-field:has(input[type="search"])::after,
|
|
220
|
+
matcha-form-field[size="medium"] .matcha-form-field:has(input[type="search"])::after {
|
|
221
|
+
font-size: 20px;
|
|
222
|
+
line-height: 20px;
|
|
223
|
+
}
|
|
224
|
+
matcha-form-field[size="lg"] .matcha-form-field:has(input[type="search"])::after,
|
|
225
|
+
matcha-form-field[size="large"] .matcha-form-field:has(input[type="search"])::after,
|
|
226
|
+
matcha-form-field[size="huge"] .matcha-form-field:has(input[type="search"])::after {
|
|
227
|
+
font-size: 24px;
|
|
228
|
+
line-height: 24px;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Hierarquia de trailing icons: loading > clear × > suffix default.
|
|
232
|
+
// Cada nível oculta os abaixo pra não empilhar ícones redundantes.
|
|
233
|
+
|
|
234
|
+
// Loading: spinner assume o suffix; oculta lupa + × juntos.
|
|
235
|
+
.matcha-form-field:has(input[type="search"]):has(.matcha-form-field-spinner)::after,
|
|
236
|
+
.matcha-form-field:has(.matcha-form-field-spinner) .matcha-clear-button {
|
|
237
|
+
display: none !important;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Clear visível (input com valor): × toma o lugar da lupa default.
|
|
241
|
+
.matcha-form-field:has(input[type="search"]):has(.matcha-clear-button--visible)::after {
|
|
242
|
+
display: none;
|
|
243
|
+
}
|
|
244
|
+
|
|
11
245
|
// ── Structural (inputs) — sem border, sem bg (box wraps) ────────────────────
|
|
12
246
|
|
|
13
247
|
// ─── Filhos projetáveis do form-field ────────────────────────────────────
|
|
@@ -43,6 +277,13 @@
|
|
|
43
277
|
color: var(--matcha-color-text-primary); // Figma filled value: #E8EAED dark / #0E1116 light
|
|
44
278
|
resize: none;
|
|
45
279
|
|
|
280
|
+
// Figma: text-placeholder (#6E747A dark / #9AA0A6 light); opacity 1
|
|
281
|
+
// porque o Firefox aplica opacity < 1 no ::placeholder por default
|
|
282
|
+
&::placeholder {
|
|
283
|
+
color: var(--matcha-color-text-placeholder);
|
|
284
|
+
opacity: 1;
|
|
285
|
+
}
|
|
286
|
+
|
|
46
287
|
&:disabled {
|
|
47
288
|
color: var(--matcha-color-interaction-disabled-fg);
|
|
48
289
|
-webkit-text-fill-color: var(--matcha-color-interaction-disabled-fg); // Safari override
|
|
@@ -352,13 +593,19 @@
|
|
|
352
593
|
}
|
|
353
594
|
}
|
|
354
595
|
|
|
355
|
-
// Select trigger ocupa altura
|
|
596
|
+
// Select trigger ocupa altura E largura totais do form-field (clique abre
|
|
597
|
+
// dropdown em qualquer ponto da caixa)
|
|
356
598
|
matcha-select,
|
|
357
599
|
.matcha-select-container,
|
|
358
600
|
.matcha-select-trigger {
|
|
359
601
|
height: 100%;
|
|
360
602
|
}
|
|
361
603
|
|
|
604
|
+
.matcha-select-container,
|
|
605
|
+
.matcha-select-trigger {
|
|
606
|
+
width: 100%;
|
|
607
|
+
}
|
|
608
|
+
|
|
362
609
|
// Suffix costuma agrupar mais de uma info (contador de caracteres + ícone de
|
|
363
610
|
// status/erro) — 8px de respiro entre elas. Regra global (sem ::ng-deep): o
|
|
364
611
|
// host do <matcha-suffix> tem class .matcha-form-field-suffix e vive dentro do
|