@inchurch/matcha-theme 22.10.0 → 22.11.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.
@@ -113,10 +113,10 @@ matcha-accordion-item {
113
113
  // .accordion-header-slot
114
114
  // └── matcha-accordion-header (slot wrapper do consumer — display: inline default)
115
115
  // └── matcha-title (host inline-flex: sign + text)
116
- // └── .matcha-title__text (display: inline-block)
116
+ // └── .matcha-title__text (display: block, flex item)
117
117
  //
118
118
  // Pra constraint de largura propagar até o text element, cada nível precisa
119
- // ser flex + max-width: 100% + min-width: 0. Sem isso, o inline-flex/inline-block
119
+ // ser flex + max-width: 100% + min-width: 0. Sem isso, o inline-flex
120
120
  // calcula largura pelo conteúdo (sem shrink) e o texto wrappa.
121
121
  .accordion-header-slot {
122
122
  flex: 1 1 auto;
@@ -1,10 +1,55 @@
1
1
  // =============================================================================
2
2
  // matcha-avatar.scss — Avatar component (photo, initials, placeholder + status)
3
3
  // Aligned with Figma Avatar/Matcha: XS(24) SM(32) MD(40) LG(56) XL(80) 2XL(96)
4
+ //
5
+ // Estado visual (size/color/status/disabled/placeholder) é selecionado por
6
+ // ATRIBUTO no host (`matcha-avatar[size="medium"]`), não por classe — mesmo
7
+ // padrão já usado pelo `ring` abaixo e pelo `outline`/`link` do matcha-button.
8
+ // A classe `.matcha-avatar` na bolinha interna é só identidade estrutural.
4
9
  // =============================================================================
5
10
 
6
11
  // ── Structural (outside mixin) ──────────────────────────────────────────────
7
12
 
13
+ // Host — SEMPRE inline-flex, incondicional (não depende de haver conteúdo
14
+ // projetado). Com zero filhos em matcha-avatar-name/-caption/slot genérico,
15
+ // um flex container de um único item (a bolinha) renderiza idêntico a um
16
+ // avatar bare de hoje — não precisa de @ContentChild pra alternar layout.
17
+ matcha-avatar {
18
+ display: inline-flex;
19
+ align-items: center;
20
+ gap: var(--matcha-space-100, 8px);
21
+
22
+ &[orientation="stacked"] {
23
+ flex-direction: column;
24
+ text-align: center;
25
+ }
26
+ }
27
+
28
+ .matcha-avatar-text {
29
+ display: flex;
30
+ flex-direction: column;
31
+ min-width: 0;
32
+ }
33
+
34
+ matcha-avatar-name {
35
+ display: block;
36
+ color: var(--matcha-color-text-primary);
37
+ font-weight: var(--matcha-weight-medium, 500);
38
+ overflow: hidden;
39
+ text-overflow: ellipsis;
40
+ white-space: nowrap;
41
+ }
42
+
43
+ matcha-avatar-caption {
44
+ display: block;
45
+ color: var(--matcha-color-text-muted);
46
+ font-weight: var(--matcha-weight-regular, 400);
47
+ font-variant-numeric: tabular-nums;
48
+ overflow: hidden;
49
+ text-overflow: ellipsis;
50
+ white-space: nowrap;
51
+ }
52
+
8
53
  .matcha-avatar {
9
54
  display: inline-flex;
10
55
  align-items: center;
@@ -27,69 +72,141 @@
27
72
  // Aplicado no .matcha-avatar INNER (não no host) porque o inner é quem tem
28
73
  // width/height/border-radius:pill — box-shadow segue o radius desse elemento
29
74
  // e renderiza circular. No host (inline default) sairia retangular.
75
+ //
76
+ // Os 6 tokens semânticos resolvem inteiro aqui via seletor de atributo — var()
77
+ // direto, sem custom property nem lookup no componente. Halo (glow externo) só
78
+ // em accent/success/warn/danger; primary/neutral só têm o anel sólido. Cor
79
+ // literal (hex/rgb/var arbitrário) é o ÚNICO caso que passa pela custom
80
+ // property --matcha-avatar-ring-color (não dá pra enumerar seletor de atributo
81
+ // pra valor arbitrário) — branch de fallback no final, sem halo.
30
82
  // =============================================================================
31
- matcha-avatar[ring] .matcha-avatar {
83
+ matcha-avatar[ring="accent"] .matcha-avatar {
32
84
  box-shadow:
33
85
  0 0 0 2px transparent,
34
- 0 0 0 3px var(--matcha-avatar-ring-color, currentColor);
86
+ 0 0 0 3px var(--matcha-color-accent),
87
+ 0 0 0 5px var(--matcha-color-accent-alpha, rgba(0, 148, 0, 0.10));
35
88
  }
36
89
 
37
- matcha-avatar[ring]:not([ring="neutral"]) .matcha-avatar {
90
+ matcha-avatar[ring="success"] .matcha-avatar {
38
91
  box-shadow:
39
92
  0 0 0 2px transparent,
40
- 0 0 0 3px var(--matcha-avatar-ring-color, currentColor),
41
- 0 0 0 5px var(--matcha-avatar-ring-halo, transparent);
93
+ 0 0 0 3px var(--matcha-color-success),
94
+ 0 0 0 5px var(--matcha-color-success-alpha, rgba(22, 163, 74, 0.10));
42
95
  }
43
96
 
44
- // ── Variants (sizes, initials, icon, disabled) — nested em .matcha-avatar pra
45
- // usar `&.matcha-avatar-*` syntax. Bloco separado do base styles (linha 8-21)
46
- // porque matcha-avatar[ring] (acima) é regra absoluta, não nested.
47
- .matcha-avatar {
48
- // ── Sizes Canonical 5-step scale: tiny 24 · small 40 · medium 56 · large 80 · huge 96.
49
- // Abbreviations kept as @deprecated aliases, mapped BY PIXEL SIZE (old 32px `sm` dropped → tiny).
50
- // NOTE: --matcha-avatar-* tokens still carry the legacy abbreviated names; re-tier them to
51
- // tiny/small/medium/large/huge on the Figma/DSV3 side (token rename is design-driven).
52
- &.matcha-avatar-tiny,
53
- &.matcha-avatar-xs,
54
- &.matcha-avatar-sm {
55
- width: var(--matcha-avatar-xs, 24px);
56
- height: var(--matcha-avatar-xs, 24px);
57
- font-size: var(--matcha-text-2xs, 10px);
58
- line-height: 1;
59
- }
97
+ matcha-avatar[ring="warn"] .matcha-avatar {
98
+ box-shadow:
99
+ 0 0 0 2px transparent,
100
+ 0 0 0 3px var(--matcha-color-warn),
101
+ 0 0 0 5px var(--matcha-color-warn-alpha, rgba(245, 158, 11, 0.10));
102
+ }
60
103
 
61
- &.matcha-avatar-small,
62
- &.matcha-avatar-md {
63
- width: var(--matcha-avatar-md, 40px);
64
- height: var(--matcha-avatar-md, 40px);
65
- font-size: var(--matcha-text-md, 14px);
66
- line-height: 1;
67
- }
104
+ matcha-avatar[ring="danger"] .matcha-avatar {
105
+ box-shadow:
106
+ 0 0 0 2px transparent,
107
+ 0 0 0 3px var(--matcha-color-danger),
108
+ 0 0 0 5px var(--matcha-color-danger-alpha, rgba(239, 68, 68, 0.10));
109
+ }
68
110
 
69
- &.matcha-avatar-medium,
70
- &.matcha-avatar-lg {
71
- width: var(--matcha-avatar-lg, 56px);
72
- height: var(--matcha-avatar-lg, 56px);
73
- font-size: var(--matcha-text-2xl, 20px);
74
- line-height: 1;
75
- }
111
+ matcha-avatar[ring="primary"] .matcha-avatar {
112
+ box-shadow:
113
+ 0 0 0 2px transparent,
114
+ 0 0 0 3px var(--matcha-color-primary);
115
+ }
76
116
 
77
- &.matcha-avatar-large,
78
- &.matcha-avatar-xl {
79
- width: var(--matcha-avatar-xl, 80px);
80
- height: var(--matcha-avatar-xl, 80px);
81
- font-size: var(--matcha-text-3xl, 24px);
82
- line-height: 1;
83
- }
117
+ matcha-avatar[ring="neutral"] .matcha-avatar {
118
+ box-shadow:
119
+ 0 0 0 2px transparent,
120
+ 0 0 0 3px var(--matcha-color-surface-border);
121
+ }
122
+
123
+ // Fallback — [ring] presente mas não é nenhum dos 6 tokens acima (cor literal).
124
+ matcha-avatar[ring]:not([ring="accent"]):not([ring="success"]):not([ring="warn"]):not([ring="danger"]):not([ring="primary"]):not([ring="neutral"]) .matcha-avatar {
125
+ box-shadow:
126
+ 0 0 0 2px transparent,
127
+ 0 0 0 3px var(--matcha-avatar-ring-color, currentColor);
128
+ }
129
+
130
+ // ── Sizes — Canonical 5-step scale: tiny 24 · small 40 · medium 56 · large 80 · huge 96.
131
+ // O setter do [size] já normaliza os apelidos abreviados (xs/sm/md/lg/xl/2xl) pro nome
132
+ // canônico antes de refletir o atributo — só precisa dos 5 branches aqui.
133
+ // NOTE: --matcha-avatar-* tokens ainda carregam os nomes abreviados legados; retierar pra
134
+ // tiny/small/medium/large/huge do lado Figma/DSV3 é trabalho separado (design-driven).
135
+ matcha-avatar[size="tiny"] .matcha-avatar {
136
+ width: var(--matcha-avatar-xs, 24px);
137
+ height: var(--matcha-avatar-xs, 24px);
138
+ font-size: var(--matcha-text-2xs, 10px);
139
+ line-height: 1;
140
+ }
141
+
142
+ matcha-avatar[size="small"] .matcha-avatar {
143
+ width: var(--matcha-avatar-md, 40px);
144
+ height: var(--matcha-avatar-md, 40px);
145
+ font-size: var(--matcha-text-md, 14px);
146
+ line-height: 1;
147
+ }
148
+
149
+ matcha-avatar[size="medium"] .matcha-avatar {
150
+ width: var(--matcha-avatar-lg, 56px);
151
+ height: var(--matcha-avatar-lg, 56px);
152
+ font-size: var(--matcha-text-2xl, 20px);
153
+ line-height: 1;
154
+ }
155
+
156
+ matcha-avatar[size="large"] .matcha-avatar {
157
+ width: var(--matcha-avatar-xl, 80px);
158
+ height: var(--matcha-avatar-xl, 80px);
159
+ font-size: var(--matcha-text-3xl, 24px);
160
+ line-height: 1;
161
+ }
162
+
163
+ matcha-avatar[size="huge"] .matcha-avatar {
164
+ width: var(--matcha-avatar-2xl, 96px);
165
+ height: var(--matcha-avatar-2xl, 96px);
166
+ font-size: var(--matcha-text-4xl, 32px);
167
+ line-height: 1;
168
+ }
169
+
170
+ // ── Tipografia de matcha-avatar-name/-caption por [size] — mesmo [size] que
171
+ // já governa a bolinha, sem input separado nem seletor de irmão.
172
+ matcha-avatar[size="tiny"] {
173
+ matcha-avatar-name { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
174
+ matcha-avatar-caption { font-size: var(--matcha-text-xs, 11px); line-height: var(--matcha-leading-xs, 14px); }
175
+ }
176
+ matcha-avatar[size="small"] {
177
+ matcha-avatar-name { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
178
+ matcha-avatar-caption { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
179
+ }
180
+ matcha-avatar[size="medium"] {
181
+ matcha-avatar-name { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
182
+ matcha-avatar-caption { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
183
+ }
184
+ matcha-avatar[size="large"] {
185
+ matcha-avatar-name { font-size: var(--matcha-text-xl, 18px); line-height: var(--matcha-leading-xl, 24px); }
186
+ matcha-avatar-caption { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
187
+ }
188
+ matcha-avatar[size="huge"] {
189
+ matcha-avatar-name { font-size: var(--matcha-text-title-lg, 20px); line-height: var(--matcha-leading-title-lg, 28px); }
190
+ matcha-avatar-caption { font-size: var(--matcha-text-xl, 18px); line-height: var(--matcha-leading-xl, 24px); }
191
+ }
84
192
 
85
- &.matcha-avatar-huge,
86
- &.matcha-avatar-2xl {
87
- width: var(--matcha-avatar-2xl, 96px);
88
- height: var(--matcha-avatar-2xl, 96px);
89
- font-size: var(--matcha-text-4xl, 32px);
90
- line-height: 1;
193
+ // ── Stacked (hero/profile header) — tipografia maior, negrito, centralizada.
194
+ matcha-avatar[orientation="stacked"] {
195
+ &[size="tiny"], &[size="small"] {
196
+ matcha-avatar-name { font-size: var(--matcha-text-title-sm, 16px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-sm, 22px); }
197
+ matcha-avatar-caption { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
91
198
  }
199
+ &[size="medium"], &[size="large"] {
200
+ matcha-avatar-name { font-size: var(--matcha-text-title-md, 18px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-md, 24px); }
201
+ matcha-avatar-caption { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
202
+ }
203
+ &[size="huge"] {
204
+ matcha-avatar-name { font-size: var(--matcha-text-title-lg, 20px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-lg, 28px); }
205
+ matcha-avatar-caption { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
206
+ }
207
+ }
92
208
 
209
+ .matcha-avatar {
93
210
  // ── Image ──
94
211
  .matcha-avatar-image {
95
212
  width: 100%;
@@ -110,78 +227,80 @@ matcha-avatar[ring]:not([ring="neutral"]) .matcha-avatar {
110
227
  width: 100%;
111
228
  height: 100%;
112
229
  }
230
+ }
113
231
 
114
- // ── Disabled ──
115
- &.matcha-avatar--disabled,
116
- &.color-disabled {
117
- opacity: var(--matcha-opacity-disabled, 0.38);
118
- pointer-events: none;
119
- }
232
+ // ── Disabled ─────────────────────────────────────────────────────────────────
233
+ // `.color-disabled` preservado como gatilho manual alternativo (pré-existente,
234
+ // não gerido pelo componente) — `[disabled]` é o gatilho canônico hoje.
235
+ matcha-avatar[disabled] .matcha-avatar,
236
+ .matcha-avatar.color-disabled {
237
+ opacity: var(--matcha-opacity-disabled, 0.38);
238
+ pointer-events: none;
120
239
  }
121
240
 
122
241
  // ── Placeholder — vazado canônico (Figma matcha/avatar 5668:32088) ──────────
123
242
  // SVG usa fill-rule=evenodd: disco preenchido com currentColor + silhueta vazada.
124
243
  // `currentColor` do disco precisa ser a COR DA MARCA (não o contrast da .color class
125
244
  // global, que é branco/preto). Override aqui força o token de palette.
126
- .matcha-avatar.matcha-avatar--placeholder {
245
+ matcha-avatar[placeholder] .matcha-avatar {
127
246
  background: transparent !important;
128
-
129
- &.light-blue { color: var(--matcha-color-palette-light-blue) !important; }
130
- &.pink { color: var(--matcha-color-palette-pink) !important; }
131
- &.teal { color: var(--matcha-color-palette-teal) !important; }
132
- &.purple { color: var(--matcha-color-palette-purple) !important; }
133
- &.orange { color: var(--matcha-color-palette-orange) !important; }
134
- &.yellow { color: var(--matcha-color-palette-yellow) !important; }
135
- &.neutral { color: var(--matcha-color-icon-default) !important; }
136
247
  }
137
248
 
249
+ matcha-avatar[color="primary"][placeholder] .matcha-avatar { color: var(--matcha-color-primary) !important; }
250
+ matcha-avatar[color="light-blue"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-light-blue) !important; }
251
+ matcha-avatar[color="pink"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-pink) !important; }
252
+ matcha-avatar[color="teal"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-teal) !important; }
253
+ matcha-avatar[color="purple"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-purple) !important; }
254
+ matcha-avatar[color="orange"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-orange) !important; }
255
+ matcha-avatar[color="yellow"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-yellow) !important; }
256
+ matcha-avatar[color="neutral"][placeholder] .matcha-avatar { color: var(--matcha-color-icon-default) !important; }
257
+
138
258
  // Neutral em Initials — cinza canônico Figma (icon-default).
139
- .matcha-avatar:not(.matcha-avatar--placeholder).neutral {
259
+ matcha-avatar[color="neutral"]:not([placeholder]) .matcha-avatar {
140
260
  background: var(--matcha-color-icon-default);
141
261
  }
142
262
 
143
- // ── Initials — bg + fg por palette canônica Figma DSV3 (6 cores) ────────────
263
+ // ── Initials — bg + fg por cor (primary semântico + 6 da palette Figma DSV3)
144
264
  // O palette inverte por tema (light=tons saturados, dark=tons claros). text-primary
145
265
  // também inverte (#1a1d21 light / #e8eaed dark). Combinar os dois → contraste péssimo
146
- // em dark mode (1.2-2.9:1 FAIL). Por isso fg é fixed-per-color, não token-based.
266
+ // em dark mode (1.2-2.9:1 FAIL). Por isso fg da palette é fixed-per-color, não token-based.
267
+ // `primary` é semântico — usa `--matcha-color-primary-contrast`, já resolvido por tema.
147
268
  //
148
269
  // Light mode: pink/teal/purple bg escuros → fg branco. light-blue/orange/yellow bg
149
270
  // claros → fg preto (light-blue precisa #000 puro pra AA por 0.08).
150
271
  // Dark mode: todos os bg ficam lighter → fg preto funciona em tudo (5-12:1).
151
272
 
152
- .matcha-avatar:not(.matcha-avatar--placeholder) {
153
- // Backgrounds (mesmo seletor pros 2 temas — palette token já inverte sozinho).
154
- &.light-blue { background: var(--matcha-color-palette-light-blue); }
155
- &.pink { background: var(--matcha-color-palette-pink); }
156
- &.teal { background: var(--matcha-color-palette-teal); }
157
- &.purple { background: var(--matcha-color-palette-purple); }
158
- &.orange { background: var(--matcha-color-palette-orange); }
159
- &.yellow { background: var(--matcha-color-palette-yellow); }
273
+ matcha-avatar[color="primary"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-primary); }
274
+ matcha-avatar[color="light-blue"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-light-blue); }
275
+ matcha-avatar[color="pink"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-pink); }
276
+ matcha-avatar[color="teal"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-teal); }
277
+ matcha-avatar[color="purple"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-purple); }
278
+ matcha-avatar[color="orange"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-orange); }
279
+ matcha-avatar[color="yellow"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-yellow); }
280
+
281
+ matcha-avatar[color="primary"]:not([placeholder]) .matcha-avatar {
282
+ color: var(--matcha-color-primary-contrast);
160
283
  }
161
284
 
162
285
  // Light mode — bgs saturados (pink/teal/purple = escuros), fg branco passa AA.
163
286
  // orange/yellow/light-blue = claros, fg precisa ser dark (#000 pra light-blue por margem).
164
- .theme-default-light .matcha-avatar:not(.matcha-avatar--placeholder) {
165
- &.light-blue { color: #000; } // 5.42:1 AA
166
- &.pink { color: #fff; } // 4.95:1 AA
167
- &.teal { color: #fff; } // 5.32:1 AA
168
- &.purple { color: #fff; } // 6.30:1 AA
169
- &.orange { color: #1a1a1a; } // 4.59:1 AA
170
- &.yellow { color: #1a1a1a; } // 8.52:1 AAA
171
- &.neutral { color: #fff; } // icon-default #5f656b vs #fff = 5.18:1 AA
172
- }
287
+ .theme-default-light matcha-avatar[color="light-blue"]:not([placeholder]) .matcha-avatar { color: #000; } // 5.42:1 AA
288
+ .theme-default-light matcha-avatar[color="pink"]:not([placeholder]) .matcha-avatar { color: #fff; } // 4.95:1 AA
289
+ .theme-default-light matcha-avatar[color="teal"]:not([placeholder]) .matcha-avatar { color: #fff; } // 5.32:1 AA
290
+ .theme-default-light matcha-avatar[color="purple"]:not([placeholder]) .matcha-avatar { color: #fff; } // 6.30:1 AA
291
+ .theme-default-light matcha-avatar[color="orange"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 4.59:1 AA
292
+ .theme-default-light matcha-avatar[color="yellow"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 8.52:1 AAA
293
+ .theme-default-light matcha-avatar[color="neutral"]:not([placeholder]) .matcha-avatar { color: #fff; } // icon-default #5f656b vs #fff = 5.18:1 AA
173
294
 
174
295
  // Dark mode — todos os bgs ficam lighter (#54c5f7, #e46291, #4fb7ad, etc).
175
296
  // Texto branco falha em todos. Texto dark funciona em todos.
176
- .theme-default-dark .matcha-avatar:not(.matcha-avatar--placeholder) {
177
- &.light-blue { color: #1a1a1a; } // 8.87:1 AAA
178
- &.pink { color: #1a1a1a; } // 5.35:1 AA
179
- &.teal { color: #1a1a1a; } // 7.22:1 AAA
180
- &.purple { color: #1a1a1a; } // 4.98:1 AA
181
- &.orange { color: #1a1a1a; } // 8.58:1 AAA
182
- &.yellow { color: #1a1a1a; } // 11.94:1 AAA
183
- &.neutral { color: #1a1a1a; } // icon-default #9aa0a6 vs #1a1a1a = 5.97:1 AA
184
- }
297
+ .theme-default-dark matcha-avatar[color="light-blue"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 8.87:1 AAA
298
+ .theme-default-dark matcha-avatar[color="pink"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 5.35:1 AA
299
+ .theme-default-dark matcha-avatar[color="teal"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 7.22:1 AAA
300
+ .theme-default-dark matcha-avatar[color="purple"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 4.98:1 AA
301
+ .theme-default-dark matcha-avatar[color="orange"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 8.58:1 AAA
302
+ .theme-default-dark matcha-avatar[color="yellow"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 11.94:1 AAA
303
+ .theme-default-dark matcha-avatar[color="neutral"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // icon-default #9aa0a6 vs #1a1a1a = 5.97:1 AA
185
304
 
186
305
  // ── Avatar Group — empilhamento horizontal com overlap + overflow "+N" ──────
187
306
  // Substitui a composição manual (SCSS local) feita nas telas. -10px de overlap
@@ -234,159 +353,26 @@ matcha-avatar[ring]:not([ring="neutral"]) .matcha-avatar {
234
353
  border: var(--matcha-border-thin, 2px) solid var(--matcha-color-surface-card, #fff);
235
354
  box-sizing: border-box;
236
355
 
237
- // Size scales with avatar
238
- .matcha-avatar-xs &,
239
- .matcha-avatar-tiny & { width: var(--matcha-avatar-status-xs, 8px); height: var(--matcha-avatar-status-xs, 8px); }
240
-
241
- .matcha-avatar-sm &,
242
- .matcha-avatar-small & { width: var(--matcha-avatar-status-sm, 10px); height: var(--matcha-avatar-status-sm, 10px); }
243
-
244
- .matcha-avatar-md &,
245
- .matcha-avatar-medium & { width: var(--matcha-avatar-status-md, 12px); height: var(--matcha-avatar-status-md, 12px); }
246
-
247
- .matcha-avatar-lg &,
248
- .matcha-avatar-large & { width: var(--matcha-avatar-status-lg, 14px); height: var(--matcha-avatar-status-lg, 14px); }
249
-
250
- .matcha-avatar-xl & { width: var(--matcha-avatar-status-xl, 16px); height: var(--matcha-avatar-status-xl, 16px); }
251
-
252
- .matcha-avatar-2xl &,
253
- .matcha-avatar-huge & { width: var(--matcha-avatar-status-2xl, 18px); height: var(--matcha-avatar-status-2xl, 18px); }
254
-
255
- // Cores estruturais — fallback hardcoded pra funcionar mesmo sem tema.
256
- &.matcha-avatar-status--online { background-color: var(--matcha-color-success, #16a34a); }
257
- &.matcha-avatar-status--offline { background-color: var(--matcha-color-text-placeholder, #9ca3af); }
258
- &.matcha-avatar-status--busy { background-color: var(--matcha-color-danger, #dc2626); }
356
+ // Size scales with avatar — keyed off [size] do host, não classe.
357
+ matcha-avatar[size="tiny"] & { width: var(--matcha-avatar-status-xs, 8px); height: var(--matcha-avatar-status-xs, 8px); }
358
+ matcha-avatar[size="small"] & { width: var(--matcha-avatar-status-sm, 10px); height: var(--matcha-avatar-status-sm, 10px); }
359
+ matcha-avatar[size="medium"] & { width: var(--matcha-avatar-status-md, 12px); height: var(--matcha-avatar-status-md, 12px); }
360
+ matcha-avatar[size="large"] & { width: var(--matcha-avatar-status-lg, 14px); height: var(--matcha-avatar-status-lg, 14px); }
361
+ matcha-avatar[size="huge"] & { width: var(--matcha-avatar-status-2xl, 18px); height: var(--matcha-avatar-status-2xl, 18px); }
259
362
  }
260
363
 
261
- // ── "Nome ao lado" (showName) ───────────────────────────────────────────────
262
- // Root: `display: contents` por padrão — transparente no layout, idêntico a
263
- // hoje (só a bolinha conta como box). Vira inline-flex (bolinha + texto lado
264
- // a lado) só quando showTextStack (showName + hasName) — ver component.
265
- .matcha-avatar-root {
266
- display: contents;
267
-
268
- &--inline {
269
- display: inline-flex;
270
- align-items: center;
271
- gap: var(--matcha-space-100, 8px);
272
- min-width: 0;
273
- }
274
-
275
- // Stacked (hero/profile header) — bolinha + texto empilhados, centralizados.
276
- // Substitui a composição manual <header><matcha-avatar/><h1/><p/></header>.
277
- &--stacked {
278
- display: inline-flex;
279
- flex-direction: column;
280
- align-items: center;
281
- text-align: center;
282
- gap: var(--matcha-space-100, 8px);
283
- }
284
- }
285
-
286
- .matcha-avatar-text {
287
- display: flex;
288
- flex-direction: column;
289
- min-width: 0;
290
-
291
- &__primary {
292
- color: var(--matcha-color-text-primary);
293
- font-weight: var(--matcha-weight-medium, 500);
294
- overflow: hidden;
295
- text-overflow: ellipsis;
296
- white-space: nowrap;
297
- }
298
-
299
- &__caption {
300
- color: var(--matcha-color-text-muted);
301
- font-weight: var(--matcha-weight-regular, 400);
302
- font-variant-numeric: tabular-nums;
303
- overflow: hidden;
304
- text-overflow: ellipsis;
305
- white-space: nowrap;
306
- }
307
- }
308
-
309
- // Equilíbrio tipográfico por tamanho do avatar — seletor de irmão contra as
310
- // classes de tamanho já existentes na bolinha (`.matcha-avatar-<size>`), sem
311
- // duplicar a classe de tamanho no host. 5 tiers, escala proporcional ao avatar.
312
- .matcha-avatar-tiny ~ .matcha-avatar-text,
313
- .matcha-avatar-xs ~ .matcha-avatar-text {
314
- .matcha-avatar-text__primary { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
315
- .matcha-avatar-text__caption { font-size: var(--matcha-text-xs, 11px); line-height: var(--matcha-leading-xs, 14px); }
316
- }
317
-
318
- .matcha-avatar-small ~ .matcha-avatar-text,
319
- .matcha-avatar-md ~ .matcha-avatar-text {
320
- .matcha-avatar-text__primary { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
321
- .matcha-avatar-text__caption { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
322
- }
323
-
324
- .matcha-avatar-medium ~ .matcha-avatar-text,
325
- .matcha-avatar-lg ~ .matcha-avatar-text {
326
- .matcha-avatar-text__primary { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
327
- .matcha-avatar-text__caption { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
328
- }
329
-
330
- .matcha-avatar-large ~ .matcha-avatar-text,
331
- .matcha-avatar-xl ~ .matcha-avatar-text {
332
- .matcha-avatar-text__primary { font-size: var(--matcha-text-xl, 18px); line-height: var(--matcha-leading-xl, 24px); }
333
- .matcha-avatar-text__caption { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
334
- }
335
-
336
- .matcha-avatar-huge ~ .matcha-avatar-text,
337
- .matcha-avatar-2xl ~ .matcha-avatar-text {
338
- .matcha-avatar-text__primary { font-size: var(--matcha-text-title-lg, 20px); line-height: var(--matcha-leading-title-lg, 28px); }
339
- .matcha-avatar-text__caption { font-size: var(--matcha-text-xl, 18px); line-height: var(--matcha-leading-xl, 24px); }
340
- }
341
-
342
- // ── Stacked (hero/profile header) — tipografia maior, negrito, centralizada.
343
- // Classe composta (.matcha-avatar-text.matcha-avatar-text--stacked) tem mais
344
- // especificidade que a escada inline acima — sobrescreve sem depender de ordem.
345
- .matcha-avatar-tiny ~ .matcha-avatar-text.matcha-avatar-text--stacked,
346
- .matcha-avatar-xs ~ .matcha-avatar-text.matcha-avatar-text--stacked {
347
- .matcha-avatar-text__primary { font-size: var(--matcha-text-title-sm, 16px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-sm, 22px); }
348
- .matcha-avatar-text__caption { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
349
- }
350
-
351
- .matcha-avatar-small ~ .matcha-avatar-text.matcha-avatar-text--stacked,
352
- .matcha-avatar-md ~ .matcha-avatar-text.matcha-avatar-text--stacked {
353
- .matcha-avatar-text__primary { font-size: var(--matcha-text-title-sm, 16px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-sm, 22px); }
354
- .matcha-avatar-text__caption { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
355
- }
356
-
357
- .matcha-avatar-medium ~ .matcha-avatar-text.matcha-avatar-text--stacked,
358
- .matcha-avatar-lg ~ .matcha-avatar-text.matcha-avatar-text--stacked {
359
- .matcha-avatar-text__primary { font-size: var(--matcha-text-title-md, 18px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-md, 24px); }
360
- .matcha-avatar-text__caption { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
361
- }
362
-
363
- .matcha-avatar-large ~ .matcha-avatar-text.matcha-avatar-text--stacked,
364
- .matcha-avatar-xl ~ .matcha-avatar-text.matcha-avatar-text--stacked {
365
- .matcha-avatar-text__primary { font-size: var(--matcha-text-title-md, 18px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-md, 24px); }
366
- .matcha-avatar-text__caption { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
367
- }
368
-
369
- .matcha-avatar-huge ~ .matcha-avatar-text.matcha-avatar-text--stacked,
370
- .matcha-avatar-2xl ~ .matcha-avatar-text.matcha-avatar-text--stacked {
371
- .matcha-avatar-text__primary { font-size: var(--matcha-text-title-lg, 20px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-lg, 28px); }
372
- .matcha-avatar-text__caption { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
373
- }
364
+ // Cores estruturais fallback hardcoded pra funcionar mesmo sem tema.
365
+ matcha-avatar[status="online"] .matcha-avatar-status { background-color: var(--matcha-color-success, #16a34a); }
366
+ matcha-avatar[status="offline"] .matcha-avatar-status { background-color: var(--matcha-color-text-placeholder, #9ca3af); }
367
+ matcha-avatar[status="busy"] .matcha-avatar-status { background-color: var(--matcha-color-danger, #dc2626); }
374
368
 
375
369
  // ── Theme mixin ─────────────────────────────────────────────────────────────
376
370
 
377
371
  @mixin matcha-avatar-theme($theme) {
378
- .matcha-avatar {
379
- // Placeholder: SVG usa fill="currentColor" e herda do host. A classe de
380
- // cor (.blue/.orange/etc) define color=foreground + background=cor cheia,
381
- // então o icon vazado fica visível na cor escolhida pelo usuário.
382
- // Sem fallback hardcoded aqui — quando o user não passa color, o @Input
383
- // default 'blue' resolve via .blue do matcha-style.css.
384
-
385
- &.matcha-avatar--disabled,
386
- &.color-disabled {
387
- background-color: var(--matcha-color-disabled-bg);
388
- color: var(--matcha-color-disabled-fg);
389
- }
372
+ matcha-avatar[disabled] .matcha-avatar,
373
+ .matcha-avatar.color-disabled {
374
+ background-color: var(--matcha-color-disabled-bg);
375
+ color: var(--matcha-color-disabled-fg);
390
376
  }
391
377
 
392
378
  // Status border-color por tema (estrutural já resolve cores de fundo via tokens).
@@ -404,12 +390,12 @@ matcha-avatar[ring]:not([ring="neutral"]) .matcha-avatar {
404
390
  @media (forced-colors: active) {
405
391
  .matcha-avatar {
406
392
  border: 1px solid CanvasText;
393
+ }
407
394
 
408
- &.matcha-avatar--disabled,
409
- &.color-disabled {
410
- opacity: 0.5;
411
- border-color: GrayText;
412
- }
395
+ matcha-avatar[disabled] .matcha-avatar,
396
+ .matcha-avatar.color-disabled {
397
+ opacity: 0.5;
398
+ border-color: GrayText;
413
399
  }
414
400
 
415
401
  // Status dot — em high-contrast as 3 cores ficam idênticas. Compensamos
@@ -417,16 +403,16 @@ matcha-avatar[ring]:not([ring="neutral"]) .matcha-avatar {
417
403
  .matcha-avatar-status {
418
404
  background: SelectedItem !important;
419
405
  border: 2px solid Canvas !important;
406
+ }
420
407
 
421
- &.matcha-avatar-status--offline {
422
- background: Canvas !important;
423
- border: 2px solid CanvasText !important;
424
- }
408
+ matcha-avatar[status="offline"] .matcha-avatar-status {
409
+ background: Canvas !important;
410
+ border: 2px solid CanvasText !important;
411
+ }
425
412
 
426
- &.matcha-avatar-status--busy {
427
- background: SelectedItem !important;
428
- box-shadow: 0 0 0 2px Canvas, 0 0 0 4px CanvasText;
429
- }
413
+ matcha-avatar[status="busy"] .matcha-avatar-status {
414
+ background: SelectedItem !important;
415
+ box-shadow: 0 0 0 2px Canvas, 0 0 0 4px CanvasText;
430
416
  }
431
417
  }
432
418
 
@@ -82,6 +82,30 @@
82
82
 
83
83
  //disabled false
84
84
  &:not([disabled="true"]) {
85
+
86
+ // Default do componente (inactiveColor='basic') — não é cor de paleta
87
+ // (--matcha-color-basic não existe): inativo neutro com tokens de
88
+ // superfície/texto. Sem este branch, o toggle "pelado" (sem
89
+ // inactiveColor) não casava com regra nenhuma e o inativo ficava
90
+ // filled da própria cor, indistinguível do ativo.
91
+ &[inactivecolor="basic"] {
92
+ .button-group {
93
+
94
+ button[matcha-button],
95
+ a[matcha-button] {
96
+ &:not([active]) {
97
+ color: var(--matcha-color-text-secondary);
98
+ background: transparent;
99
+ box-shadow: 0 0 0 2px var(--matcha-color-surface-border) inset;
100
+
101
+ .ripple {
102
+ background: var(--matcha-color-fg-alpha); // ok: legacy ripple color token
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+
85
109
  @each $colorName in $color-functions {
86
110
  &[inactivecolor="#{'' + $colorName}"] {
87
111
  .button-group {
@@ -136,6 +136,7 @@ a[matcha-link] {
136
136
  text-shadow: none;
137
137
  text-align: center;
138
138
  text-wrap: nowrap;
139
+ text-decoration: none; // reset do underline default quando o host é <a> (variant != link)
139
140
  display: flex;
140
141
  justify-content: center;
141
142
  align-items: center;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inchurch/matcha-theme",
3
- "version": "22.10.0",
3
+ "version": "22.11.0",
4
4
  "description": "Themes for matcha-design-system",
5
5
  "main": "main.scss",
6
6
  "scripts": {