@inchurch/matcha-theme 21.4.0 → 22.1.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.
- package/abstracts/_colors.scss +236 -236
- package/abstracts/_elevation.scss +108 -108
- package/abstracts/_functions.scss +321 -321
- package/abstracts/_media-breakpoint.scss +26 -26
- package/abstracts/_theme-api.scss +219 -219
- package/abstracts/_typography.scss +128 -128
- package/base/_reset.scss +446 -445
- package/components/app-page-header.scss +260 -260
- package/components/matcha-accordion.scss +293 -293
- package/components/matcha-audio-player.scss +31 -31
- package/components/matcha-autocomplete.scss +145 -145
- package/components/matcha-avatar.scss +440 -301
- package/components/matcha-badge.scss +120 -120
- package/components/matcha-breadcrumb.scss +231 -231
- package/components/matcha-button-toggle.scss +383 -384
- package/components/matcha-buttons.scss +913 -913
- package/components/matcha-calendar.scss +218 -218
- package/components/matcha-cards.scss +230 -230
- package/components/matcha-chart-card.scss +53 -53
- package/components/matcha-checkbox.scss +255 -255
- package/components/matcha-chip.scss +292 -292
- package/components/matcha-color-pick.scss +34 -34
- package/components/matcha-command-palette.scss +316 -316
- package/components/matcha-contact.scss +35 -0
- package/components/matcha-crop.scss +406 -406
- package/components/matcha-date.scss +81 -81
- package/components/matcha-divider.scss +100 -100
- package/components/matcha-draggable.scss +23 -23
- package/components/matcha-drawer.scss +376 -376
- package/components/matcha-drop-image.scss +14 -14
- package/components/matcha-drop-list.scss +430 -430
- package/components/matcha-emoji.scss +69 -69
- package/components/matcha-empty-state.scss +230 -230
- package/components/matcha-file-uploader.scss +471 -471
- package/components/matcha-flag.scss +103 -103
- package/components/matcha-footer.scss +91 -91
- package/components/matcha-form-field.scss +606 -606
- package/components/matcha-form-section.scss +100 -100
- package/components/matcha-header.scss +135 -135
- package/components/matcha-highlight.scss +164 -164
- package/components/matcha-hint-text.scss +90 -90
- package/components/matcha-horizontal-tree.scss +316 -316
- package/components/matcha-icon.scss +98 -98
- package/components/matcha-image.scss +61 -61
- package/components/matcha-list.scss +211 -211
- package/components/matcha-menu.scss +99 -99
- package/components/matcha-modal.scss +210 -210
- package/components/matcha-nav.scss +581 -581
- package/components/matcha-notification.scss +413 -413
- package/components/matcha-option.scss +170 -170
- package/components/matcha-page-builder.scss +4196 -4196
- package/components/matcha-paginator.scss +689 -689
- package/components/matcha-panel.scss +194 -194
- package/components/matcha-profile-card.scss +50 -50
- package/components/matcha-progress-bar.scss +313 -313
- package/components/matcha-radio.scss +320 -320
- package/components/matcha-ripple.scss +7 -7
- package/components/matcha-scrollbar.scss +33 -33
- package/components/matcha-scrollbox-shadow.scss +120 -120
- package/components/matcha-section.scss +102 -102
- package/components/matcha-select-multiple.scss +56 -56
- package/components/matcha-select.scss +667 -667
- package/components/matcha-skeleton.scss +155 -155
- package/components/matcha-slide-toggle.scss +369 -369
- package/components/matcha-slider.scss +285 -285
- package/components/matcha-snack-bar.scss +259 -259
- package/components/matcha-spin.scss +164 -164
- package/components/matcha-spinner.scss +97 -97
- package/components/matcha-status-pill.scss +38 -18
- package/components/matcha-stepper.scss +376 -376
- package/components/matcha-table-cell.scss +49 -41
- package/components/matcha-table.scss +579 -579
- package/components/matcha-tabs.scss +600 -600
- package/components/matcha-text-editor.scss +105 -105
- package/components/matcha-time.scss +33 -33
- package/components/matcha-timepicker.scss +13 -13
- package/components/matcha-toolbar.scss +359 -359
- package/components/matcha-tooltip.scss +224 -224
- package/components/matcha-tree-view.scss +257 -257
- package/layout/matcha-page-layout.scss +778 -778
- package/main.scss +331 -329
- package/package.json +1 -1
- package/tokens/_animations-tokens.scss +37 -37
- package/tokens/_breakpoints-tokens.scss +35 -35
- package/tokens/_color-tokens.scss +274 -274
- package/tokens/_elevation-tokens.scss +33 -33
- package/tokens/_emit-tokens.scss +324 -324
- package/tokens/_material-palette.scss +1149 -1149
- package/tokens/_primitives.scss +98 -98
- package/tokens/_semantic-aliases.scss +120 -120
- package/tokens/_spacing-tokens.scss +94 -94
- package/tokens/_static-tokens.scss +137 -137
- package/tokens/_typography-tokens.scss +65 -65
- package/vendors/charts.scss +90 -90
|
@@ -1,600 +1,600 @@
|
|
|
1
|
-
@use "matcha-buttons" as *;
|
|
2
|
-
@use "sass:map";
|
|
3
|
-
|
|
4
|
-
@mixin _colorize-inactive-type-basic($theme, $color-functions) {
|
|
5
|
-
&[inactivetype="basic"] {
|
|
6
|
-
@each $colorName in $color-functions {
|
|
7
|
-
&[inactivecolor="#{'' + $colorName}"] {
|
|
8
|
-
.button-group matcha-tab-item {
|
|
9
|
-
|
|
10
|
-
button[matcha-button],
|
|
11
|
-
a[matcha-button] {
|
|
12
|
-
&:not([active-item="true"]) {
|
|
13
|
-
background: var(--matcha-color-surface);
|
|
14
|
-
color: var(--matcha-color-#{$colorName});
|
|
15
|
-
box-shadow: 0 0 0 0px inset;
|
|
16
|
-
|
|
17
|
-
.ripple {
|
|
18
|
-
background: var(--matcha-color-#{$colorName}-alpha); // ok: legacy ripple color token
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
&[disabled],
|
|
27
|
-
&[disabled]:not([disabled="false"]),
|
|
28
|
-
&[disabled="true"] {
|
|
29
|
-
&:not([active-item="true"]) {
|
|
30
|
-
.button-group matcha-tab-item {
|
|
31
|
-
|
|
32
|
-
button[matcha-button],
|
|
33
|
-
a[matcha-button] {
|
|
34
|
-
@include disabled-basic-button($theme);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
@mixin _colorize-inactive-type-outline($theme, $color-functions) {
|
|
43
|
-
&[inactivetype="outline"] {
|
|
44
|
-
|
|
45
|
-
//disabled false
|
|
46
|
-
&:not([disabled="true"]) {
|
|
47
|
-
@each $colorName in $color-functions {
|
|
48
|
-
&[inactivecolor="#{'' + $colorName}"] {
|
|
49
|
-
.button-group matcha-tab-item {
|
|
50
|
-
|
|
51
|
-
button[matcha-button],
|
|
52
|
-
a[matcha-button] {
|
|
53
|
-
|
|
54
|
-
//botão não ativo
|
|
55
|
-
&:not([active-item="true"]) {
|
|
56
|
-
color: var(--matcha-color-#{$colorName});
|
|
57
|
-
background: transparent;
|
|
58
|
-
box-shadow: 0 0 0 2px var(--matcha-color-#{$colorName}) inset;
|
|
59
|
-
|
|
60
|
-
.ripple {
|
|
61
|
-
background: var(--matcha-color-#{$colorName}-alpha); // ok: legacy ripple color token
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
//disabled true
|
|
71
|
-
&[disabled],
|
|
72
|
-
&[disabled]:not([disabled="false"]),
|
|
73
|
-
&[disabled="true"] {
|
|
74
|
-
>.button-group matcha-tab-item {
|
|
75
|
-
|
|
76
|
-
button[matcha-button],
|
|
77
|
-
a[matcha-button] {
|
|
78
|
-
|
|
79
|
-
//botão não ativo
|
|
80
|
-
&:not([active-item="true"]) {
|
|
81
|
-
@include disabled-outline-button($theme);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
@mixin _colorize-inactive-type-alpha($theme, $color-functions) {
|
|
90
|
-
&[inactivetype="alpha"] {
|
|
91
|
-
@each $colorName in $color-functions {
|
|
92
|
-
&[inactivecolor="#{'' + $colorName}"] {
|
|
93
|
-
.button-group matcha-tab-item {
|
|
94
|
-
|
|
95
|
-
button[matcha-button],
|
|
96
|
-
a[matcha-button] {
|
|
97
|
-
&:not([active-item="true"]) {
|
|
98
|
-
color: var(--matcha-color-#{$colorName});
|
|
99
|
-
background: var(--matcha-color-#{$colorName}-alpha);
|
|
100
|
-
box-shadow: 0 0 0 0px;
|
|
101
|
-
|
|
102
|
-
.ripple {
|
|
103
|
-
background: var(--matcha-color-#{$colorName}-contrast-alpha); // ok: legacy ripple color token
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
&[disabled],
|
|
112
|
-
&[disabled]:not([disabled="false"]),
|
|
113
|
-
&[disabled="true"] {
|
|
114
|
-
.button-group matcha-tab-item {
|
|
115
|
-
|
|
116
|
-
button[matcha-button],
|
|
117
|
-
a[matcha-button] {
|
|
118
|
-
|
|
119
|
-
//botão não ativo
|
|
120
|
-
&:not([active-item="true"]) {
|
|
121
|
-
@include disabled-alpha-button($theme);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
@mixin _colorize-inactive-type-link($theme, $color-functions) {
|
|
130
|
-
|
|
131
|
-
&[inactivetype="link"] {
|
|
132
|
-
@each $colorName in $color-functions {
|
|
133
|
-
&[inactivecolor="#{'' + $colorName}"] {
|
|
134
|
-
.button-group matcha-tab-item {
|
|
135
|
-
|
|
136
|
-
button[matcha-button],
|
|
137
|
-
a[matcha-button] {
|
|
138
|
-
&:not([active-item="true"]) {
|
|
139
|
-
|
|
140
|
-
background: transparent;
|
|
141
|
-
color: var(--matcha-color-#{$colorName});
|
|
142
|
-
box-shadow: 0 0 0 0px;
|
|
143
|
-
|
|
144
|
-
.ripple {
|
|
145
|
-
background: var(--matcha-color-#{$colorName}-alpha); // ok: legacy ripple color token
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
&[disabled],
|
|
155
|
-
&[disabled]:not([disabled="false"]),
|
|
156
|
-
&[disabled="true"] {
|
|
157
|
-
.button-group matcha-tab-item {
|
|
158
|
-
|
|
159
|
-
button[matcha-button],
|
|
160
|
-
a[matcha-button] {
|
|
161
|
-
|
|
162
|
-
//botão não ativo
|
|
163
|
-
&:not([active-item="true"]) {
|
|
164
|
-
@include disabled-link-button($theme);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
@mixin matcha-tabs($theme) {
|
|
176
|
-
// Nomes de cor (semânticas + paleta). As cores vêm de var(--matcha-color-*)
|
|
177
|
-
// emitidas no tema — sem getRed/$theme compile-time. Value-preserving.
|
|
178
|
-
$color-functions: "red", "pink", "purple", "deep-purple", "indigo", "blue", "light-blue", "cyan", "teal",
|
|
179
|
-
"green", "light-green", "lime", "yellow", "amber", "orange", "deep-orange", "brown", "grey", "blue-grey",
|
|
180
|
-
"primary", "accent", "success", "warn", "danger", "info", "disabled";
|
|
181
|
-
|
|
182
|
-
matcha-tabs {
|
|
183
|
-
display: flex;
|
|
184
|
-
@include _colorize-inactive-type-basic($theme, $color-functions);
|
|
185
|
-
@include _colorize-inactive-type-outline($theme, $color-functions);
|
|
186
|
-
@include _colorize-inactive-type-alpha($theme, $color-functions);
|
|
187
|
-
@include _colorize-inactive-type-link($theme, $color-functions);
|
|
188
|
-
|
|
189
|
-
.button-group matcha-tab-item {
|
|
190
|
-
button[matcha-button],
|
|
191
|
-
a[matcha-button] {
|
|
192
|
-
&:focus-visible:not([disabled]):not([disabled="true"]) {
|
|
193
|
-
outline: var(--matcha-state-focus-ring-width, 2px) solid var(--matcha-color-accent);
|
|
194
|
-
outline-offset: var(--matcha-state-focus-ring-offset, 2px);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
&[disabled],
|
|
200
|
-
&[disabled]:not([disabled="false"]),
|
|
201
|
-
&[disabled="true"] {
|
|
202
|
-
.button-group matcha-tab-item {
|
|
203
|
-
|
|
204
|
-
button[matcha-button],
|
|
205
|
-
a[matcha-button] {
|
|
206
|
-
&[active-item="true"] {
|
|
207
|
-
|
|
208
|
-
&[outline],
|
|
209
|
-
&[outline]:not([outline="false"]),
|
|
210
|
-
&[outline="true"] {
|
|
211
|
-
@include disabled-outline-button($theme);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
&[basic],
|
|
215
|
-
&[basic]:not([basic="false"]),
|
|
216
|
-
&[basic="true"] {
|
|
217
|
-
@include disabled-basic-button($theme);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
&[alpha],
|
|
221
|
-
&[alpha]:not([alpha="false"]),
|
|
222
|
-
&[alpha="true"] {
|
|
223
|
-
@include disabled-alpha-button($theme);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
&[link],
|
|
227
|
-
&[link]:not([link="false"]),
|
|
228
|
-
&[link="true"] {
|
|
229
|
-
@include disabled-link-button($theme);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
.button-group {
|
|
240
|
-
&.gap-0 {
|
|
241
|
-
gap: 0 !important;
|
|
242
|
-
|
|
243
|
-
// Ajuste border-radius quando gap = 0
|
|
244
|
-
matcha-tab-item:first-child button[matcha-button] {
|
|
245
|
-
border-top-right-radius: 0;
|
|
246
|
-
border-bottom-right-radius: 0;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
matcha-tab-item:last-child button[matcha-button] {
|
|
250
|
-
border-top-left-radius: 0;
|
|
251
|
-
border-bottom-left-radius: 0;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
matcha-tab-item:not(:first-child):not(:last-child) button[matcha-button] {
|
|
255
|
-
border-radius: 0;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// =============================================================================
|
|
261
|
-
// MODERNIZED TAB STYLES — 1:1 Figma DSV3 matcha/tabs/tab (15768:76)
|
|
262
|
-
// Tipo: Underline (só horizontal) · Card (horizontal + vertical)
|
|
263
|
-
// Estado: Default · Selecionado · Disabled
|
|
264
|
-
// Ícone: opcional
|
|
265
|
-
// =============================================================================
|
|
266
|
-
|
|
267
|
-
@mixin matcha-tabs-modern($theme) {
|
|
268
|
-
|
|
269
|
-
// ── Component-level tokens (overridable pelo consumer via CSS vars) ───
|
|
270
|
-
matcha-tabs {
|
|
271
|
-
--matcha-tab-min-width-underline: var(--matcha-space-1500, 120px);
|
|
272
|
-
--matcha-tab-min-width-card-horizontal: 107px;
|
|
273
|
-
--matcha-tab-min-width-card-vertical: var(--matcha-space-1100, 88px);
|
|
274
|
-
--matcha-tab-close-size: var(--matcha-icon-size-xs, 14px);
|
|
275
|
-
--matcha-tab-state-opacity-hover: var(--matcha-state-hover, 0.08);
|
|
276
|
-
--matcha-tab-state-opacity-active: var(--matcha-state-active, 0.12);
|
|
277
|
-
--matcha-tab-state-opacity-disabled: var(--matcha-state-opacity-disabled, 0.5);
|
|
278
|
-
--matcha-tab-focus-halo: 4px;
|
|
279
|
-
--matcha-tab-focus-halo-alpha: 0.16;
|
|
280
|
-
|
|
281
|
-
// Layout do host — canon WAI-ARIA tablist:
|
|
282
|
-
// horizontal → nav em cima, content embaixo (column)
|
|
283
|
-
// vertical → nav à esquerda, content à direita (row, sidenav-like)
|
|
284
|
-
// Override do legacy `matcha-tabs { display: flex }` que assumia row sempre
|
|
285
|
-
// (legado button-group). Aria-orientation vem do host binding do component.
|
|
286
|
-
flex-direction: column;
|
|
287
|
-
// 24px (space-300) é o vertical rhythm canon entre blocos no painel —
|
|
288
|
-
// mesmo gap entre seções dentro do content. Evita "tab↔content maior que
|
|
289
|
-
// section↔section" que rompe a hierarquia visual.
|
|
290
|
-
gap: var(--matcha-space-300, 24px);
|
|
291
|
-
|
|
292
|
-
&[aria-orientation="vertical"] {
|
|
293
|
-
flex-direction: row;
|
|
294
|
-
gap: var(--matcha-space-300, 24px);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// ── Underline Tab (1:1 Figma DSV3 — border per item) ──────────────────
|
|
299
|
-
// Cada item tem bg surface-card + border-bottom 4px (surface-border default,
|
|
300
|
-
// accent selected). Container não tem border próprio (canon Figma).
|
|
301
|
-
// Sliding indicator absoluto desliza entre tabs (Material 3 style).
|
|
302
|
-
// Sempre horizontal (vertical não é canon).
|
|
303
|
-
.matcha-tab-underline {
|
|
304
|
-
display: flex;
|
|
305
|
-
align-items: stretch;
|
|
306
|
-
background: transparent;
|
|
307
|
-
position: relative;
|
|
308
|
-
|
|
309
|
-
// Mobile-friendly horizontal scroll
|
|
310
|
-
&.matcha-tab-scrollable {
|
|
311
|
-
overflow-x: auto;
|
|
312
|
-
scrollbar-width: thin;
|
|
313
|
-
-webkit-overflow-scrolling: touch;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// ── Sliding indicator (Material 3 magic underline) ──
|
|
317
|
-
// Cantos retos + 2px de altura (canon Figma — sem rounded).
|
|
318
|
-
.matcha-tab-indicator {
|
|
319
|
-
position: absolute;
|
|
320
|
-
bottom: 0;
|
|
321
|
-
left: var(--matcha-tab-indicator-left, 0);
|
|
322
|
-
width: var(--matcha-tab-indicator-width, 0);
|
|
323
|
-
height: var(--matcha-border-thin, 2px);
|
|
324
|
-
background: var(--matcha-color-accent);
|
|
325
|
-
border-radius: 0;
|
|
326
|
-
transition:
|
|
327
|
-
left var(--matcha-duration-fast, 200ms) var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)),
|
|
328
|
-
width var(--matcha-duration-fast, 200ms) var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1));
|
|
329
|
-
pointer-events: none;
|
|
330
|
-
z-index: 1;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
.matcha-tab-item {
|
|
334
|
-
display: flex;
|
|
335
|
-
align-items: center;
|
|
336
|
-
justify-content: center;
|
|
337
|
-
gap: var(--matcha-space-100, 8px);
|
|
338
|
-
padding: var(--matcha-space-200, 16px) var(--matcha-space-500, 40px);
|
|
339
|
-
border: none;
|
|
340
|
-
// Border bottom 2px — per item (track surface-border, slider sobrepõe accent)
|
|
341
|
-
border-bottom: var(--matcha-border-thin, 2px) solid
|
|
342
|
-
var(--matcha-color-surface-border);
|
|
343
|
-
background: var(--matcha-color-surface-card);
|
|
344
|
-
cursor: pointer;
|
|
345
|
-
position: relative;
|
|
346
|
-
overflow: hidden;
|
|
347
|
-
font-family: var(--matcha-font-family);
|
|
348
|
-
font-size: var(--matcha-text-body-lg, 16px);
|
|
349
|
-
font-weight: var(--matcha-weight-regular, 400);
|
|
350
|
-
line-height: var(--matcha-leading-body-lg, 24px);
|
|
351
|
-
color: var(--matcha-color-text-secondary,
|
|
352
|
-
color-mix(in srgb, var(--matcha-color-fg) 70%, transparent));
|
|
353
|
-
white-space: nowrap;
|
|
354
|
-
flex-shrink: 0;
|
|
355
|
-
min-width: var(--matcha-tab-min-width-underline);
|
|
356
|
-
transition:
|
|
357
|
-
color var(--matcha-duration-fast, 200ms) var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
358
|
-
border-bottom-color var(--matcha-duration-fast, 200ms) var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
359
|
-
font-weight var(--matcha-duration-fast, 200ms) ease;
|
|
360
|
-
|
|
361
|
-
// State layer (hover + active visual feedback)
|
|
362
|
-
&::before {
|
|
363
|
-
content: '';
|
|
364
|
-
position: absolute;
|
|
365
|
-
inset: 0;
|
|
366
|
-
background: currentColor;
|
|
367
|
-
opacity: 0;
|
|
368
|
-
pointer-events: none;
|
|
369
|
-
transition: opacity var(--matcha-duration-instant, 80ms) linear;
|
|
370
|
-
}
|
|
371
|
-
&:hover:not(:disabled)::before { opacity: var(--matcha-tab-state-opacity-hover); }
|
|
372
|
-
&:active:not(:disabled)::before { opacity: var(--matcha-tab-state-opacity-active); }
|
|
373
|
-
|
|
374
|
-
// ── Selecionado (border-bottom muda pra accent ALÉM do sliding indicator
|
|
375
|
-
// — cobre 100% mesmo com subpixel mismatch do indicator) ──
|
|
376
|
-
&.active,
|
|
377
|
-
&[aria-selected="true"] {
|
|
378
|
-
color: var(--matcha-color-accent);
|
|
379
|
-
font-weight: var(--matcha-weight-semibold, 600);
|
|
380
|
-
line-height: var(--matcha-leading-title-sm, 22px);
|
|
381
|
-
border-bottom-color: var(--matcha-color-accent);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
// ── Disabled ──
|
|
385
|
-
&:disabled,
|
|
386
|
-
&[disabled] {
|
|
387
|
-
opacity: var(--matcha-tab-state-opacity-disabled);
|
|
388
|
-
pointer-events: none;
|
|
389
|
-
cursor: default;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// ── Focus ring polido (offset 4px + halo 16% alpha) ──
|
|
393
|
-
&:focus-visible {
|
|
394
|
-
outline: var(--matcha-state-focus-ring-width, 2px) solid
|
|
395
|
-
var(--matcha-color-accent);
|
|
396
|
-
outline-offset: var(--matcha-state-focus-ring-offset, 4px);
|
|
397
|
-
border-radius: var(--matcha-radius-sm, 4px);
|
|
398
|
-
box-shadow: 0 0 0 var(--matcha-tab-focus-halo)
|
|
399
|
-
color-mix(in srgb, var(--matcha-color-accent) calc(var(--matcha-tab-focus-halo-alpha) * 100%), transparent);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// ── Card Tab (canon Figma) ────────────────────────────────────────────
|
|
405
|
-
// Card 2px border accent quando selected · texto text-primary (NÃO accent).
|
|
406
|
-
// Suporta horizontal (default) e vertical (icon stacked).
|
|
407
|
-
.matcha-tab-card {
|
|
408
|
-
display: flex;
|
|
409
|
-
// Tamanho natural por item — stretch vertical antes esticava cards quando
|
|
410
|
-
// pai tinha altura expandida (bug reportado em pages com page-content flex-fill).
|
|
411
|
-
align-items: flex-start;
|
|
412
|
-
gap: var(--matcha-space-100, 8px);
|
|
413
|
-
flex-wrap: wrap;
|
|
414
|
-
|
|
415
|
-
// Equal-width layout — cada tab ocupa fatia igual da row (paginador-like).
|
|
416
|
-
// Habilitado via prop `equalWidth` no consumer. Icon stacked acima do label
|
|
417
|
-
// (look canon de paginator), independente de orientation do host.
|
|
418
|
-
&.matcha-tab-equal-width {
|
|
419
|
-
flex-wrap: nowrap;
|
|
420
|
-
|
|
421
|
-
.matcha-tab-item {
|
|
422
|
-
flex: 1 1 0;
|
|
423
|
-
min-width: 0;
|
|
424
|
-
flex-direction: column;
|
|
425
|
-
text-align: center;
|
|
426
|
-
padding: var(--matcha-space-150, 12px) var(--matcha-space-200, 16px);
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// Vertical layout — empilha icon + label
|
|
431
|
-
&.matcha-tab-vertical .matcha-tab-item {
|
|
432
|
-
flex-direction: column;
|
|
433
|
-
min-width: var(--matcha-tab-min-width-card-vertical);
|
|
434
|
-
padding: var(--matcha-space-100, 8px) var(--matcha-space-200, 16px);
|
|
435
|
-
text-align: center;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
.matcha-tab-item {
|
|
439
|
-
display: flex;
|
|
440
|
-
align-items: center;
|
|
441
|
-
justify-content: center;
|
|
442
|
-
gap: var(--matcha-space-100, 8px);
|
|
443
|
-
padding: var(--matcha-space-150, 12px) var(--matcha-space-200, 16px);
|
|
444
|
-
border: var(--matcha-border-thin, 1px) solid transparent;
|
|
445
|
-
// radius-lg (8px) escala 1:2 com cards (xl=16px) — hierarquia visual
|
|
446
|
-
// canon: atom interativo / container. Antes era md (4px), o que dava
|
|
447
|
-
// disparidade 1:4 e quebrava a leitura conjunta tabs + cards.
|
|
448
|
-
border-radius: var(--matcha-radius-lg, 8px);
|
|
449
|
-
background: var(--matcha-color-surface-card);
|
|
450
|
-
cursor: pointer;
|
|
451
|
-
position: relative;
|
|
452
|
-
overflow: hidden;
|
|
453
|
-
font-family: var(--matcha-font-family);
|
|
454
|
-
font-size: var(--matcha-text-body-md, 14px);
|
|
455
|
-
font-weight: var(--matcha-weight-regular, 400);
|
|
456
|
-
line-height: var(--matcha-leading-body-md, 20px);
|
|
457
|
-
color: var(--matcha-color-text-secondary,
|
|
458
|
-
color-mix(in srgb, var(--matcha-color-fg) 70%, transparent));
|
|
459
|
-
flex-shrink: 0;
|
|
460
|
-
min-width: var(--matcha-tab-min-width-card-horizontal);
|
|
461
|
-
transition:
|
|
462
|
-
border-color var(--matcha-duration-fast, 200ms) var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
463
|
-
color var(--matcha-duration-fast, 200ms) var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
464
|
-
transform var(--matcha-duration-instant, 80ms) ease;
|
|
465
|
-
|
|
466
|
-
// State layer
|
|
467
|
-
&::before {
|
|
468
|
-
content: '';
|
|
469
|
-
position: absolute;
|
|
470
|
-
inset: 0;
|
|
471
|
-
background: currentColor;
|
|
472
|
-
opacity: 0;
|
|
473
|
-
border-radius: inherit;
|
|
474
|
-
pointer-events: none;
|
|
475
|
-
transition: opacity var(--matcha-duration-instant, 80ms) linear;
|
|
476
|
-
}
|
|
477
|
-
&:hover:not(:disabled) {
|
|
478
|
-
&::before { opacity: var(--matcha-tab-state-opacity-hover); }
|
|
479
|
-
transform: translateY(calc(-1 * var(--matcha-border-hairline, 1px)));
|
|
480
|
-
}
|
|
481
|
-
&:active:not(:disabled)::before { opacity: var(--matcha-tab-state-opacity-active); }
|
|
482
|
-
|
|
483
|
-
// ── Selecionado (Figma: border accent · texto text-primary NÃO accent) ──
|
|
484
|
-
&.active,
|
|
485
|
-
&[aria-selected="true"] {
|
|
486
|
-
border-color: var(--matcha-color-accent);
|
|
487
|
-
color: var(--matcha-color-fg);
|
|
488
|
-
font-weight: var(--matcha-weight-medium, 500);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// ── Disabled ──
|
|
492
|
-
&:disabled,
|
|
493
|
-
&[disabled] {
|
|
494
|
-
opacity: var(--matcha-tab-state-opacity-disabled);
|
|
495
|
-
pointer-events: none;
|
|
496
|
-
cursor: default;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
// ── Focus ring polido ──
|
|
500
|
-
&:focus-visible {
|
|
501
|
-
outline: var(--matcha-state-focus-ring-width, 2px) solid
|
|
502
|
-
var(--matcha-color-accent);
|
|
503
|
-
outline-offset: var(--matcha-border-thin, 2px);
|
|
504
|
-
box-shadow: 0 0 0 var(--matcha-tab-focus-halo)
|
|
505
|
-
color-mix(in srgb, var(--matcha-color-accent) calc(var(--matcha-tab-focus-halo-alpha) * 100%), transparent);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// ── Icon inside tab items ──
|
|
511
|
-
.matcha-tab-underline,
|
|
512
|
-
.matcha-tab-card {
|
|
513
|
-
.matcha-tab-item matcha-icon { flex-shrink: 0; }
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// ── Badge (notificações, contagens) ───────────────────────────────────
|
|
517
|
-
.matcha-tab-item__badge {
|
|
518
|
-
display: inline-flex;
|
|
519
|
-
align-items: center;
|
|
520
|
-
justify-content: center;
|
|
521
|
-
min-width: var(--matcha-space-250, 20px);
|
|
522
|
-
height: var(--matcha-space-250, 20px);
|
|
523
|
-
padding: 0 var(--matcha-space-075, 6px);
|
|
524
|
-
background: var(--matcha-color-accent);
|
|
525
|
-
color: var(--matcha-color-accent-text-on,
|
|
526
|
-
var(--matcha-color-accent-contrast));
|
|
527
|
-
border-radius: var(--matcha-radius-pill, 9999px);
|
|
528
|
-
font-size: var(--matcha-text-body-xs, 11px);
|
|
529
|
-
font-weight: var(--matcha-weight-semibold, 600);
|
|
530
|
-
line-height: 1;
|
|
531
|
-
flex-shrink: 0;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// ── Close button (closable tabs) ──────────────────────────────────────
|
|
535
|
-
.matcha-tab-item__close {
|
|
536
|
-
display: inline-flex;
|
|
537
|
-
align-items: center;
|
|
538
|
-
justify-content: center;
|
|
539
|
-
width: var(--matcha-space-300, 24px);
|
|
540
|
-
height: var(--matcha-space-300, 24px);
|
|
541
|
-
border-radius: 50%;
|
|
542
|
-
color: var(--matcha-color-text-secondary,
|
|
543
|
-
color-mix(in srgb, var(--matcha-color-fg) 70%, transparent));
|
|
544
|
-
transition:
|
|
545
|
-
background-color var(--matcha-duration-instant, 80ms) ease,
|
|
546
|
-
color var(--matcha-duration-instant, 80ms) ease;
|
|
547
|
-
flex-shrink: 0;
|
|
548
|
-
cursor: pointer;
|
|
549
|
-
margin-left: var(--matcha-space-050, 4px);
|
|
550
|
-
|
|
551
|
-
&:hover {
|
|
552
|
-
background: var(--matcha-color-surface-hover,
|
|
553
|
-
color-mix(in srgb, var(--matcha-color-fg) 8%, transparent));
|
|
554
|
-
color: var(--matcha-color-fg);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
&:focus-visible {
|
|
558
|
-
outline: var(--matcha-state-focus-ring-width, 2px) solid
|
|
559
|
-
var(--matcha-color-accent);
|
|
560
|
-
outline-offset: var(--matcha-border-thin, 2px);
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
svg {
|
|
564
|
-
display: block;
|
|
565
|
-
width: var(--matcha-tab-close-size, 14px);
|
|
566
|
-
height: var(--matcha-tab-close-size, 14px);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// ── Mobile: reset min-width pra evitar overflow + auto-scroll ───────────
|
|
572
|
-
@media (max-width: 639px) {
|
|
573
|
-
.matcha-tab-underline .matcha-tab-item,
|
|
574
|
-
.matcha-tab-card .matcha-tab-item {
|
|
575
|
-
min-width: auto;
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
// ── Mobile: Underline auto-scrollable em viewports estreitos ────────────
|
|
580
|
-
@media (max-width: 639px) {
|
|
581
|
-
.matcha-tab-underline:not(.matcha-tab-scrollable) {
|
|
582
|
-
overflow-x: auto;
|
|
583
|
-
scrollbar-width: thin;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
// ── Reduced motion (WCAG 2.2.2) ─────────────────────────────────────────
|
|
588
|
-
@media (prefers-reduced-motion: reduce) {
|
|
589
|
-
.matcha-tab-underline .matcha-tab-item,
|
|
590
|
-
.matcha-tab-underline .matcha-tab-item::before,
|
|
591
|
-
.matcha-tab-card .matcha-tab-item,
|
|
592
|
-
.matcha-tab-card .matcha-tab-item::before,
|
|
593
|
-
.matcha-tab-indicator,
|
|
594
|
-
.matcha-tab-item__close {
|
|
595
|
-
transition: none;
|
|
596
|
-
}
|
|
597
|
-
.matcha-tab-card .matcha-tab-item:hover {
|
|
598
|
-
transform: none;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
1
|
+
@use "matcha-buttons" as *;
|
|
2
|
+
@use "sass:map";
|
|
3
|
+
|
|
4
|
+
@mixin _colorize-inactive-type-basic($theme, $color-functions) {
|
|
5
|
+
&[inactivetype="basic"] {
|
|
6
|
+
@each $colorName in $color-functions {
|
|
7
|
+
&[inactivecolor="#{'' + $colorName}"] {
|
|
8
|
+
.button-group matcha-tab-item {
|
|
9
|
+
|
|
10
|
+
button[matcha-button],
|
|
11
|
+
a[matcha-button] {
|
|
12
|
+
&:not([active-item="true"]) {
|
|
13
|
+
background: var(--matcha-color-surface);
|
|
14
|
+
color: var(--matcha-color-#{$colorName});
|
|
15
|
+
box-shadow: 0 0 0 0px inset;
|
|
16
|
+
|
|
17
|
+
.ripple {
|
|
18
|
+
background: var(--matcha-color-#{$colorName}-alpha); // ok: legacy ripple color token
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&[disabled],
|
|
27
|
+
&[disabled]:not([disabled="false"]),
|
|
28
|
+
&[disabled="true"] {
|
|
29
|
+
&:not([active-item="true"]) {
|
|
30
|
+
.button-group matcha-tab-item {
|
|
31
|
+
|
|
32
|
+
button[matcha-button],
|
|
33
|
+
a[matcha-button] {
|
|
34
|
+
@include disabled-basic-button($theme);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@mixin _colorize-inactive-type-outline($theme, $color-functions) {
|
|
43
|
+
&[inactivetype="outline"] {
|
|
44
|
+
|
|
45
|
+
//disabled false
|
|
46
|
+
&:not([disabled="true"]) {
|
|
47
|
+
@each $colorName in $color-functions {
|
|
48
|
+
&[inactivecolor="#{'' + $colorName}"] {
|
|
49
|
+
.button-group matcha-tab-item {
|
|
50
|
+
|
|
51
|
+
button[matcha-button],
|
|
52
|
+
a[matcha-button] {
|
|
53
|
+
|
|
54
|
+
//botão não ativo
|
|
55
|
+
&:not([active-item="true"]) {
|
|
56
|
+
color: var(--matcha-color-#{$colorName});
|
|
57
|
+
background: transparent;
|
|
58
|
+
box-shadow: 0 0 0 2px var(--matcha-color-#{$colorName}) inset;
|
|
59
|
+
|
|
60
|
+
.ripple {
|
|
61
|
+
background: var(--matcha-color-#{$colorName}-alpha); // ok: legacy ripple color token
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//disabled true
|
|
71
|
+
&[disabled],
|
|
72
|
+
&[disabled]:not([disabled="false"]),
|
|
73
|
+
&[disabled="true"] {
|
|
74
|
+
>.button-group matcha-tab-item {
|
|
75
|
+
|
|
76
|
+
button[matcha-button],
|
|
77
|
+
a[matcha-button] {
|
|
78
|
+
|
|
79
|
+
//botão não ativo
|
|
80
|
+
&:not([active-item="true"]) {
|
|
81
|
+
@include disabled-outline-button($theme);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@mixin _colorize-inactive-type-alpha($theme, $color-functions) {
|
|
90
|
+
&[inactivetype="alpha"] {
|
|
91
|
+
@each $colorName in $color-functions {
|
|
92
|
+
&[inactivecolor="#{'' + $colorName}"] {
|
|
93
|
+
.button-group matcha-tab-item {
|
|
94
|
+
|
|
95
|
+
button[matcha-button],
|
|
96
|
+
a[matcha-button] {
|
|
97
|
+
&:not([active-item="true"]) {
|
|
98
|
+
color: var(--matcha-color-#{$colorName});
|
|
99
|
+
background: var(--matcha-color-#{$colorName}-alpha);
|
|
100
|
+
box-shadow: 0 0 0 0px;
|
|
101
|
+
|
|
102
|
+
.ripple {
|
|
103
|
+
background: var(--matcha-color-#{$colorName}-contrast-alpha); // ok: legacy ripple color token
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&[disabled],
|
|
112
|
+
&[disabled]:not([disabled="false"]),
|
|
113
|
+
&[disabled="true"] {
|
|
114
|
+
.button-group matcha-tab-item {
|
|
115
|
+
|
|
116
|
+
button[matcha-button],
|
|
117
|
+
a[matcha-button] {
|
|
118
|
+
|
|
119
|
+
//botão não ativo
|
|
120
|
+
&:not([active-item="true"]) {
|
|
121
|
+
@include disabled-alpha-button($theme);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@mixin _colorize-inactive-type-link($theme, $color-functions) {
|
|
130
|
+
|
|
131
|
+
&[inactivetype="link"] {
|
|
132
|
+
@each $colorName in $color-functions {
|
|
133
|
+
&[inactivecolor="#{'' + $colorName}"] {
|
|
134
|
+
.button-group matcha-tab-item {
|
|
135
|
+
|
|
136
|
+
button[matcha-button],
|
|
137
|
+
a[matcha-button] {
|
|
138
|
+
&:not([active-item="true"]) {
|
|
139
|
+
|
|
140
|
+
background: transparent;
|
|
141
|
+
color: var(--matcha-color-#{$colorName});
|
|
142
|
+
box-shadow: 0 0 0 0px;
|
|
143
|
+
|
|
144
|
+
.ripple {
|
|
145
|
+
background: var(--matcha-color-#{$colorName}-alpha); // ok: legacy ripple color token
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
&[disabled],
|
|
155
|
+
&[disabled]:not([disabled="false"]),
|
|
156
|
+
&[disabled="true"] {
|
|
157
|
+
.button-group matcha-tab-item {
|
|
158
|
+
|
|
159
|
+
button[matcha-button],
|
|
160
|
+
a[matcha-button] {
|
|
161
|
+
|
|
162
|
+
//botão não ativo
|
|
163
|
+
&:not([active-item="true"]) {
|
|
164
|
+
@include disabled-link-button($theme);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@mixin matcha-tabs($theme) {
|
|
176
|
+
// Nomes de cor (semânticas + paleta). As cores vêm de var(--matcha-color-*)
|
|
177
|
+
// emitidas no tema — sem getRed/$theme compile-time. Value-preserving.
|
|
178
|
+
$color-functions: "red", "pink", "purple", "deep-purple", "indigo", "blue", "light-blue", "cyan", "teal",
|
|
179
|
+
"green", "light-green", "lime", "yellow", "amber", "orange", "deep-orange", "brown", "grey", "blue-grey",
|
|
180
|
+
"primary", "accent", "success", "warn", "danger", "info", "disabled";
|
|
181
|
+
|
|
182
|
+
matcha-tabs {
|
|
183
|
+
display: flex;
|
|
184
|
+
@include _colorize-inactive-type-basic($theme, $color-functions);
|
|
185
|
+
@include _colorize-inactive-type-outline($theme, $color-functions);
|
|
186
|
+
@include _colorize-inactive-type-alpha($theme, $color-functions);
|
|
187
|
+
@include _colorize-inactive-type-link($theme, $color-functions);
|
|
188
|
+
|
|
189
|
+
.button-group matcha-tab-item {
|
|
190
|
+
button[matcha-button],
|
|
191
|
+
a[matcha-button] {
|
|
192
|
+
&:focus-visible:not([disabled]):not([disabled="true"]) {
|
|
193
|
+
outline: var(--matcha-state-focus-ring-width, 2px) solid var(--matcha-color-accent);
|
|
194
|
+
outline-offset: var(--matcha-state-focus-ring-offset, 2px);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
&[disabled],
|
|
200
|
+
&[disabled]:not([disabled="false"]),
|
|
201
|
+
&[disabled="true"] {
|
|
202
|
+
.button-group matcha-tab-item {
|
|
203
|
+
|
|
204
|
+
button[matcha-button],
|
|
205
|
+
a[matcha-button] {
|
|
206
|
+
&[active-item="true"] {
|
|
207
|
+
|
|
208
|
+
&[outline],
|
|
209
|
+
&[outline]:not([outline="false"]),
|
|
210
|
+
&[outline="true"] {
|
|
211
|
+
@include disabled-outline-button($theme);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
&[basic],
|
|
215
|
+
&[basic]:not([basic="false"]),
|
|
216
|
+
&[basic="true"] {
|
|
217
|
+
@include disabled-basic-button($theme);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
&[alpha],
|
|
221
|
+
&[alpha]:not([alpha="false"]),
|
|
222
|
+
&[alpha="true"] {
|
|
223
|
+
@include disabled-alpha-button($theme);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
&[link],
|
|
227
|
+
&[link]:not([link="false"]),
|
|
228
|
+
&[link="true"] {
|
|
229
|
+
@include disabled-link-button($theme);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.button-group {
|
|
240
|
+
&.gap-0 {
|
|
241
|
+
gap: 0 !important;
|
|
242
|
+
|
|
243
|
+
// Ajuste border-radius quando gap = 0
|
|
244
|
+
matcha-tab-item:first-child button[matcha-button] {
|
|
245
|
+
border-top-right-radius: 0;
|
|
246
|
+
border-bottom-right-radius: 0;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
matcha-tab-item:last-child button[matcha-button] {
|
|
250
|
+
border-top-left-radius: 0;
|
|
251
|
+
border-bottom-left-radius: 0;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
matcha-tab-item:not(:first-child):not(:last-child) button[matcha-button] {
|
|
255
|
+
border-radius: 0;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// =============================================================================
|
|
261
|
+
// MODERNIZED TAB STYLES — 1:1 Figma DSV3 matcha/tabs/tab (15768:76)
|
|
262
|
+
// Tipo: Underline (só horizontal) · Card (horizontal + vertical)
|
|
263
|
+
// Estado: Default · Selecionado · Disabled
|
|
264
|
+
// Ícone: opcional
|
|
265
|
+
// =============================================================================
|
|
266
|
+
|
|
267
|
+
@mixin matcha-tabs-modern($theme) {
|
|
268
|
+
|
|
269
|
+
// ── Component-level tokens (overridable pelo consumer via CSS vars) ───
|
|
270
|
+
matcha-tabs {
|
|
271
|
+
--matcha-tab-min-width-underline: var(--matcha-space-1500, 120px);
|
|
272
|
+
--matcha-tab-min-width-card-horizontal: 107px;
|
|
273
|
+
--matcha-tab-min-width-card-vertical: var(--matcha-space-1100, 88px);
|
|
274
|
+
--matcha-tab-close-size: var(--matcha-icon-size-xs, 14px);
|
|
275
|
+
--matcha-tab-state-opacity-hover: var(--matcha-state-hover, 0.08);
|
|
276
|
+
--matcha-tab-state-opacity-active: var(--matcha-state-active, 0.12);
|
|
277
|
+
--matcha-tab-state-opacity-disabled: var(--matcha-state-opacity-disabled, 0.5);
|
|
278
|
+
--matcha-tab-focus-halo: 4px;
|
|
279
|
+
--matcha-tab-focus-halo-alpha: 0.16;
|
|
280
|
+
|
|
281
|
+
// Layout do host — canon WAI-ARIA tablist:
|
|
282
|
+
// horizontal → nav em cima, content embaixo (column)
|
|
283
|
+
// vertical → nav à esquerda, content à direita (row, sidenav-like)
|
|
284
|
+
// Override do legacy `matcha-tabs { display: flex }` que assumia row sempre
|
|
285
|
+
// (legado button-group). Aria-orientation vem do host binding do component.
|
|
286
|
+
flex-direction: column;
|
|
287
|
+
// 24px (space-300) é o vertical rhythm canon entre blocos no painel —
|
|
288
|
+
// mesmo gap entre seções dentro do content. Evita "tab↔content maior que
|
|
289
|
+
// section↔section" que rompe a hierarquia visual.
|
|
290
|
+
gap: var(--matcha-space-300, 24px);
|
|
291
|
+
|
|
292
|
+
&[aria-orientation="vertical"] {
|
|
293
|
+
flex-direction: row;
|
|
294
|
+
gap: var(--matcha-space-300, 24px);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// ── Underline Tab (1:1 Figma DSV3 — border per item) ──────────────────
|
|
299
|
+
// Cada item tem bg surface-card + border-bottom 4px (surface-border default,
|
|
300
|
+
// accent selected). Container não tem border próprio (canon Figma).
|
|
301
|
+
// Sliding indicator absoluto desliza entre tabs (Material 3 style).
|
|
302
|
+
// Sempre horizontal (vertical não é canon).
|
|
303
|
+
.matcha-tab-underline {
|
|
304
|
+
display: flex;
|
|
305
|
+
align-items: stretch;
|
|
306
|
+
background: transparent;
|
|
307
|
+
position: relative;
|
|
308
|
+
|
|
309
|
+
// Mobile-friendly horizontal scroll
|
|
310
|
+
&.matcha-tab-scrollable {
|
|
311
|
+
overflow-x: auto;
|
|
312
|
+
scrollbar-width: thin;
|
|
313
|
+
-webkit-overflow-scrolling: touch;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// ── Sliding indicator (Material 3 magic underline) ──
|
|
317
|
+
// Cantos retos + 2px de altura (canon Figma — sem rounded).
|
|
318
|
+
.matcha-tab-indicator {
|
|
319
|
+
position: absolute;
|
|
320
|
+
bottom: 0;
|
|
321
|
+
left: var(--matcha-tab-indicator-left, 0);
|
|
322
|
+
width: var(--matcha-tab-indicator-width, 0);
|
|
323
|
+
height: var(--matcha-border-thin, 2px);
|
|
324
|
+
background: var(--matcha-color-accent);
|
|
325
|
+
border-radius: 0;
|
|
326
|
+
transition:
|
|
327
|
+
left var(--matcha-duration-fast, 200ms) var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)),
|
|
328
|
+
width var(--matcha-duration-fast, 200ms) var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1));
|
|
329
|
+
pointer-events: none;
|
|
330
|
+
z-index: 1;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.matcha-tab-item {
|
|
334
|
+
display: flex;
|
|
335
|
+
align-items: center;
|
|
336
|
+
justify-content: center;
|
|
337
|
+
gap: var(--matcha-space-100, 8px);
|
|
338
|
+
padding: var(--matcha-space-200, 16px) var(--matcha-space-500, 40px);
|
|
339
|
+
border: none;
|
|
340
|
+
// Border bottom 2px — per item (track surface-border, slider sobrepõe accent)
|
|
341
|
+
border-bottom: var(--matcha-border-thin, 2px) solid
|
|
342
|
+
var(--matcha-color-surface-border);
|
|
343
|
+
background: var(--matcha-color-surface-card);
|
|
344
|
+
cursor: pointer;
|
|
345
|
+
position: relative;
|
|
346
|
+
overflow: hidden;
|
|
347
|
+
font-family: var(--matcha-font-family);
|
|
348
|
+
font-size: var(--matcha-text-body-lg, 16px);
|
|
349
|
+
font-weight: var(--matcha-weight-regular, 400);
|
|
350
|
+
line-height: var(--matcha-leading-body-lg, 24px);
|
|
351
|
+
color: var(--matcha-color-text-secondary,
|
|
352
|
+
color-mix(in srgb, var(--matcha-color-fg) 70%, transparent));
|
|
353
|
+
white-space: nowrap;
|
|
354
|
+
flex-shrink: 0;
|
|
355
|
+
min-width: var(--matcha-tab-min-width-underline);
|
|
356
|
+
transition:
|
|
357
|
+
color var(--matcha-duration-fast, 200ms) var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
358
|
+
border-bottom-color var(--matcha-duration-fast, 200ms) var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
359
|
+
font-weight var(--matcha-duration-fast, 200ms) ease;
|
|
360
|
+
|
|
361
|
+
// State layer (hover + active visual feedback)
|
|
362
|
+
&::before {
|
|
363
|
+
content: '';
|
|
364
|
+
position: absolute;
|
|
365
|
+
inset: 0;
|
|
366
|
+
background: currentColor;
|
|
367
|
+
opacity: 0;
|
|
368
|
+
pointer-events: none;
|
|
369
|
+
transition: opacity var(--matcha-duration-instant, 80ms) linear;
|
|
370
|
+
}
|
|
371
|
+
&:hover:not(:disabled)::before { opacity: var(--matcha-tab-state-opacity-hover); }
|
|
372
|
+
&:active:not(:disabled)::before { opacity: var(--matcha-tab-state-opacity-active); }
|
|
373
|
+
|
|
374
|
+
// ── Selecionado (border-bottom muda pra accent ALÉM do sliding indicator
|
|
375
|
+
// — cobre 100% mesmo com subpixel mismatch do indicator) ──
|
|
376
|
+
&.active,
|
|
377
|
+
&[aria-selected="true"] {
|
|
378
|
+
color: var(--matcha-color-accent);
|
|
379
|
+
font-weight: var(--matcha-weight-semibold, 600);
|
|
380
|
+
line-height: var(--matcha-leading-title-sm, 22px);
|
|
381
|
+
border-bottom-color: var(--matcha-color-accent);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// ── Disabled ──
|
|
385
|
+
&:disabled,
|
|
386
|
+
&[disabled] {
|
|
387
|
+
opacity: var(--matcha-tab-state-opacity-disabled);
|
|
388
|
+
pointer-events: none;
|
|
389
|
+
cursor: default;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// ── Focus ring polido (offset 4px + halo 16% alpha) ──
|
|
393
|
+
&:focus-visible {
|
|
394
|
+
outline: var(--matcha-state-focus-ring-width, 2px) solid
|
|
395
|
+
var(--matcha-color-accent);
|
|
396
|
+
outline-offset: var(--matcha-state-focus-ring-offset, 4px);
|
|
397
|
+
border-radius: var(--matcha-radius-sm, 4px);
|
|
398
|
+
box-shadow: 0 0 0 var(--matcha-tab-focus-halo)
|
|
399
|
+
color-mix(in srgb, var(--matcha-color-accent) calc(var(--matcha-tab-focus-halo-alpha) * 100%), transparent);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// ── Card Tab (canon Figma) ────────────────────────────────────────────
|
|
405
|
+
// Card 2px border accent quando selected · texto text-primary (NÃO accent).
|
|
406
|
+
// Suporta horizontal (default) e vertical (icon stacked).
|
|
407
|
+
.matcha-tab-card {
|
|
408
|
+
display: flex;
|
|
409
|
+
// Tamanho natural por item — stretch vertical antes esticava cards quando
|
|
410
|
+
// pai tinha altura expandida (bug reportado em pages com page-content flex-fill).
|
|
411
|
+
align-items: flex-start;
|
|
412
|
+
gap: var(--matcha-space-100, 8px);
|
|
413
|
+
flex-wrap: wrap;
|
|
414
|
+
|
|
415
|
+
// Equal-width layout — cada tab ocupa fatia igual da row (paginador-like).
|
|
416
|
+
// Habilitado via prop `equalWidth` no consumer. Icon stacked acima do label
|
|
417
|
+
// (look canon de paginator), independente de orientation do host.
|
|
418
|
+
&.matcha-tab-equal-width {
|
|
419
|
+
flex-wrap: nowrap;
|
|
420
|
+
|
|
421
|
+
.matcha-tab-item {
|
|
422
|
+
flex: 1 1 0;
|
|
423
|
+
min-width: 0;
|
|
424
|
+
flex-direction: column;
|
|
425
|
+
text-align: center;
|
|
426
|
+
padding: var(--matcha-space-150, 12px) var(--matcha-space-200, 16px);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Vertical layout — empilha icon + label
|
|
431
|
+
&.matcha-tab-vertical .matcha-tab-item {
|
|
432
|
+
flex-direction: column;
|
|
433
|
+
min-width: var(--matcha-tab-min-width-card-vertical);
|
|
434
|
+
padding: var(--matcha-space-100, 8px) var(--matcha-space-200, 16px);
|
|
435
|
+
text-align: center;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.matcha-tab-item {
|
|
439
|
+
display: flex;
|
|
440
|
+
align-items: center;
|
|
441
|
+
justify-content: center;
|
|
442
|
+
gap: var(--matcha-space-100, 8px);
|
|
443
|
+
padding: var(--matcha-space-150, 12px) var(--matcha-space-200, 16px);
|
|
444
|
+
border: var(--matcha-border-thin, 1px) solid transparent;
|
|
445
|
+
// radius-lg (8px) escala 1:2 com cards (xl=16px) — hierarquia visual
|
|
446
|
+
// canon: atom interativo / container. Antes era md (4px), o que dava
|
|
447
|
+
// disparidade 1:4 e quebrava a leitura conjunta tabs + cards.
|
|
448
|
+
border-radius: var(--matcha-radius-lg, 8px);
|
|
449
|
+
background: var(--matcha-color-surface-card);
|
|
450
|
+
cursor: pointer;
|
|
451
|
+
position: relative;
|
|
452
|
+
overflow: hidden;
|
|
453
|
+
font-family: var(--matcha-font-family);
|
|
454
|
+
font-size: var(--matcha-text-body-md, 14px);
|
|
455
|
+
font-weight: var(--matcha-weight-regular, 400);
|
|
456
|
+
line-height: var(--matcha-leading-body-md, 20px);
|
|
457
|
+
color: var(--matcha-color-text-secondary,
|
|
458
|
+
color-mix(in srgb, var(--matcha-color-fg) 70%, transparent));
|
|
459
|
+
flex-shrink: 0;
|
|
460
|
+
min-width: var(--matcha-tab-min-width-card-horizontal);
|
|
461
|
+
transition:
|
|
462
|
+
border-color var(--matcha-duration-fast, 200ms) var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
463
|
+
color var(--matcha-duration-fast, 200ms) var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
464
|
+
transform var(--matcha-duration-instant, 80ms) ease;
|
|
465
|
+
|
|
466
|
+
// State layer
|
|
467
|
+
&::before {
|
|
468
|
+
content: '';
|
|
469
|
+
position: absolute;
|
|
470
|
+
inset: 0;
|
|
471
|
+
background: currentColor;
|
|
472
|
+
opacity: 0;
|
|
473
|
+
border-radius: inherit;
|
|
474
|
+
pointer-events: none;
|
|
475
|
+
transition: opacity var(--matcha-duration-instant, 80ms) linear;
|
|
476
|
+
}
|
|
477
|
+
&:hover:not(:disabled) {
|
|
478
|
+
&::before { opacity: var(--matcha-tab-state-opacity-hover); }
|
|
479
|
+
transform: translateY(calc(-1 * var(--matcha-border-hairline, 1px)));
|
|
480
|
+
}
|
|
481
|
+
&:active:not(:disabled)::before { opacity: var(--matcha-tab-state-opacity-active); }
|
|
482
|
+
|
|
483
|
+
// ── Selecionado (Figma: border accent · texto text-primary NÃO accent) ──
|
|
484
|
+
&.active,
|
|
485
|
+
&[aria-selected="true"] {
|
|
486
|
+
border-color: var(--matcha-color-accent);
|
|
487
|
+
color: var(--matcha-color-fg);
|
|
488
|
+
font-weight: var(--matcha-weight-medium, 500);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// ── Disabled ──
|
|
492
|
+
&:disabled,
|
|
493
|
+
&[disabled] {
|
|
494
|
+
opacity: var(--matcha-tab-state-opacity-disabled);
|
|
495
|
+
pointer-events: none;
|
|
496
|
+
cursor: default;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// ── Focus ring polido ──
|
|
500
|
+
&:focus-visible {
|
|
501
|
+
outline: var(--matcha-state-focus-ring-width, 2px) solid
|
|
502
|
+
var(--matcha-color-accent);
|
|
503
|
+
outline-offset: var(--matcha-border-thin, 2px);
|
|
504
|
+
box-shadow: 0 0 0 var(--matcha-tab-focus-halo)
|
|
505
|
+
color-mix(in srgb, var(--matcha-color-accent) calc(var(--matcha-tab-focus-halo-alpha) * 100%), transparent);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// ── Icon inside tab items ──
|
|
511
|
+
.matcha-tab-underline,
|
|
512
|
+
.matcha-tab-card {
|
|
513
|
+
.matcha-tab-item matcha-icon { flex-shrink: 0; }
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// ── Badge (notificações, contagens) ───────────────────────────────────
|
|
517
|
+
.matcha-tab-item__badge {
|
|
518
|
+
display: inline-flex;
|
|
519
|
+
align-items: center;
|
|
520
|
+
justify-content: center;
|
|
521
|
+
min-width: var(--matcha-space-250, 20px);
|
|
522
|
+
height: var(--matcha-space-250, 20px);
|
|
523
|
+
padding: 0 var(--matcha-space-075, 6px);
|
|
524
|
+
background: var(--matcha-color-accent);
|
|
525
|
+
color: var(--matcha-color-accent-text-on,
|
|
526
|
+
var(--matcha-color-accent-contrast));
|
|
527
|
+
border-radius: var(--matcha-radius-pill, 9999px);
|
|
528
|
+
font-size: var(--matcha-text-body-xs, 11px);
|
|
529
|
+
font-weight: var(--matcha-weight-semibold, 600);
|
|
530
|
+
line-height: 1;
|
|
531
|
+
flex-shrink: 0;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// ── Close button (closable tabs) ──────────────────────────────────────
|
|
535
|
+
.matcha-tab-item__close {
|
|
536
|
+
display: inline-flex;
|
|
537
|
+
align-items: center;
|
|
538
|
+
justify-content: center;
|
|
539
|
+
width: var(--matcha-space-300, 24px);
|
|
540
|
+
height: var(--matcha-space-300, 24px);
|
|
541
|
+
border-radius: 50%;
|
|
542
|
+
color: var(--matcha-color-text-secondary,
|
|
543
|
+
color-mix(in srgb, var(--matcha-color-fg) 70%, transparent));
|
|
544
|
+
transition:
|
|
545
|
+
background-color var(--matcha-duration-instant, 80ms) ease,
|
|
546
|
+
color var(--matcha-duration-instant, 80ms) ease;
|
|
547
|
+
flex-shrink: 0;
|
|
548
|
+
cursor: pointer;
|
|
549
|
+
margin-left: var(--matcha-space-050, 4px);
|
|
550
|
+
|
|
551
|
+
&:hover {
|
|
552
|
+
background: var(--matcha-color-surface-hover,
|
|
553
|
+
color-mix(in srgb, var(--matcha-color-fg) 8%, transparent));
|
|
554
|
+
color: var(--matcha-color-fg);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
&:focus-visible {
|
|
558
|
+
outline: var(--matcha-state-focus-ring-width, 2px) solid
|
|
559
|
+
var(--matcha-color-accent);
|
|
560
|
+
outline-offset: var(--matcha-border-thin, 2px);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
svg {
|
|
564
|
+
display: block;
|
|
565
|
+
width: var(--matcha-tab-close-size, 14px);
|
|
566
|
+
height: var(--matcha-tab-close-size, 14px);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// ── Mobile: reset min-width pra evitar overflow + auto-scroll ───────────
|
|
572
|
+
@media (max-width: 639px) {
|
|
573
|
+
.matcha-tab-underline .matcha-tab-item,
|
|
574
|
+
.matcha-tab-card .matcha-tab-item {
|
|
575
|
+
min-width: auto;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// ── Mobile: Underline auto-scrollable em viewports estreitos ────────────
|
|
580
|
+
@media (max-width: 639px) {
|
|
581
|
+
.matcha-tab-underline:not(.matcha-tab-scrollable) {
|
|
582
|
+
overflow-x: auto;
|
|
583
|
+
scrollbar-width: thin;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// ── Reduced motion (WCAG 2.2.2) ─────────────────────────────────────────
|
|
588
|
+
@media (prefers-reduced-motion: reduce) {
|
|
589
|
+
.matcha-tab-underline .matcha-tab-item,
|
|
590
|
+
.matcha-tab-underline .matcha-tab-item::before,
|
|
591
|
+
.matcha-tab-card .matcha-tab-item,
|
|
592
|
+
.matcha-tab-card .matcha-tab-item::before,
|
|
593
|
+
.matcha-tab-indicator,
|
|
594
|
+
.matcha-tab-item__close {
|
|
595
|
+
transition: none;
|
|
596
|
+
}
|
|
597
|
+
.matcha-tab-card .matcha-tab-item:hover {
|
|
598
|
+
transform: none;
|
|
599
|
+
}
|
|
600
|
+
}
|