@inchurch/matcha-theme 20.0.8 → 20.276.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.
Files changed (99) hide show
  1. package/abstracts/_colors.scss +404 -404
  2. package/abstracts/_elevation.scss +102 -102
  3. package/abstracts/_functions.scss +1212 -1212
  4. package/abstracts/_media-breakpoint.scss +23 -23
  5. package/abstracts/_typography.scss +127 -127
  6. package/base/_reset.scss +438 -438
  7. package/components/app-page-header.scss +260 -0
  8. package/components/matcha-accordion.scss +294 -157
  9. package/components/matcha-avatar.scss +171 -31
  10. package/components/matcha-badge.scss +4 -4
  11. package/components/matcha-breadcrumb.scss +232 -126
  12. package/components/matcha-button-toggle.scss +44 -0
  13. package/components/matcha-buttons.scss +908 -784
  14. package/components/matcha-calendar.scss +70 -2
  15. package/components/matcha-cards.scss +28 -2
  16. package/components/matcha-checkbox.scss +191 -490
  17. package/components/matcha-chip.scss +297 -212
  18. package/components/matcha-command-palette.scss +291 -63
  19. package/components/matcha-crop.scss +407 -172
  20. package/components/matcha-date.scss +81 -81
  21. package/components/matcha-divider.scss +86 -31
  22. package/components/matcha-drawer.scss +201 -50
  23. package/components/matcha-drop-image.scss +14 -0
  24. package/components/matcha-drop-list.scss +42 -1
  25. package/components/matcha-empty-state.scss +195 -83
  26. package/components/matcha-flag.scss +93 -52
  27. package/components/matcha-footer.scss +68 -164
  28. package/components/matcha-form-field.scss +52 -0
  29. package/components/matcha-form-section.scss +101 -101
  30. package/components/matcha-header.scss +135 -325
  31. package/components/matcha-highlight.scss +65 -197
  32. package/components/matcha-hint-text.scss +21 -0
  33. package/components/matcha-horizontal-tree.scss +317 -317
  34. package/components/matcha-icon.scss +17 -25
  35. package/components/matcha-list.scss +5 -5
  36. package/components/matcha-menu.scss +13 -0
  37. package/components/matcha-modal.scss +58 -84
  38. package/components/matcha-nav.scss +361 -230
  39. package/components/matcha-notification.scss +413 -197
  40. package/components/matcha-option.scss +79 -23
  41. package/components/matcha-paginator.scss +689 -235
  42. package/components/matcha-panel.scss +42 -26
  43. package/components/matcha-profile-card.scss +50 -50
  44. package/components/matcha-progress-bar.scss +257 -153
  45. package/components/matcha-radio.scss +244 -452
  46. package/components/matcha-scrollbox-shadow.scss +122 -122
  47. package/components/matcha-select.scss +3 -3
  48. package/components/matcha-skeleton.scss +18 -0
  49. package/components/matcha-slide-toggle.scss +47 -2
  50. package/components/matcha-slider.scss +172 -75
  51. package/components/matcha-snack-bar.scss +114 -121
  52. package/components/matcha-spinner.scss +76 -57
  53. package/components/matcha-status-pill.scss +82 -0
  54. package/components/matcha-stepper.scss +377 -177
  55. package/components/matcha-table.scss +569 -785
  56. package/components/matcha-tabs.scss +624 -469
  57. package/components/matcha-text-editor.scss +98 -144
  58. package/components/matcha-toolbar.scss +359 -206
  59. package/components/matcha-tooltip.scss +156 -62
  60. package/components/matcha-tree-view.scss +189 -0
  61. package/components/matcha-uploader.scss +240 -62
  62. package/fonts/manrope/manrope-latin-ext.woff2 +0 -0
  63. package/fonts/manrope/manrope-latin.woff2 +0 -0
  64. package/layout/matcha-page-layout.scss +776 -0
  65. package/main.scss +232 -261
  66. package/package.json +1 -1
  67. package/tokens/_animations-tokens.scss +37 -37
  68. package/tokens/_breakpoints-tokens.scss +35 -26
  69. package/tokens/_color-tokens.scss +1152 -1152
  70. package/tokens/_css-custom-properties.scss +650 -568
  71. package/tokens/_spacing-tokens.scss +94 -94
  72. package/vendors/angular-editor.scss +56 -56
  73. package/vendors/angular-material-fixes.scss +297 -297
  74. package/vendors/charts.scss +92 -92
  75. package/vendors/ng5-slider.scss +56 -56
  76. package/vendors/ngx-material-timepicker.scss +50 -50
  77. package/fonts/CircularStd-Black.eot +0 -0
  78. package/fonts/CircularStd-Black.svg +0 -3426
  79. package/fonts/CircularStd-Black.ttf +0 -0
  80. package/fonts/CircularStd-Black.woff +0 -0
  81. package/fonts/CircularStd-Black.woff2 +0 -0
  82. package/fonts/CircularStd-Bold.eot +0 -0
  83. package/fonts/CircularStd-Bold.otf +0 -0
  84. package/fonts/CircularStd-Bold.svg +0 -13532
  85. package/fonts/CircularStd-Bold.ttf +0 -0
  86. package/fonts/CircularStd-Bold.woff +0 -0
  87. package/fonts/CircularStd-Bold.woff2 +0 -0
  88. package/fonts/CircularStd-Medium.eot +0 -0
  89. package/fonts/CircularStd-Medium.otf +0 -0
  90. package/fonts/CircularStd-Medium.svg +0 -13511
  91. package/fonts/CircularStd-Medium.ttf +0 -0
  92. package/fonts/CircularStd-Medium.woff +0 -0
  93. package/fonts/CircularStd-Medium.woff2 +0 -0
  94. package/fonts/CircularStd-Regular.eot +0 -0
  95. package/fonts/CircularStd-Regular.otf +0 -0
  96. package/fonts/CircularStd-Regular.svg +0 -2378
  97. package/fonts/CircularStd-Regular.ttf +0 -0
  98. package/fonts/CircularStd-Regular.woff +0 -0
  99. package/fonts/CircularStd-Regular.woff2 +0 -0
@@ -1,785 +1,569 @@
1
- @use "sass:map";
2
-
3
- @mixin _matcha-table-theme-container-shadow-property($theme) {
4
- box-shadow:
5
- 0px -16px 0px 0px inset getSurface($theme),
6
- 20px 0 16px -24px inset rgba(#212121, 0.15), // ok: structural
7
- -20px 0 16px -24px inset rgba(#212121, 0.15), // ok: structural
8
- 0px 2px 2px 0px rgba(#212121, 0.035), // ok: structural
9
- 0px 2px 2px 0px rgba(#212121, 0.035), // ok: structural
10
- 0px 2px 2px 0px rgba(#212121, 0.035); // ok: structural
11
- }
12
-
13
- @mixin _matcha-table-theme-shadow-property($theme) {
14
- background: var(--matcha-color-surface, #{getSurface($theme)});
15
- background: linear-gradient(
16
- 90deg,
17
- getSurface($theme) 0px,
18
- getSurface($theme) 10px,
19
- rgba(#ffffff, 0) calc(0% + 110px), // ok: structural
20
- rgba(#ffffff, 0) calc(100% - 110px), // ok: structural
21
- getSurface($theme) calc(100% - 10px)
22
- );
23
- background: -moz-linear-gradient(
24
- 90deg,
25
- getSurface($theme) 0px,
26
- getSurface($theme) 10px,
27
- rgba(#ffffff, 0) calc(0% + 110px), // ok: structural
28
- rgba(#ffffff, 0) calc(100% - 110px), // ok: structural
29
- getSurface($theme) calc(100% - 10px)
30
- );
31
- background: -webkit-linear-gradient(
32
- 0deg,
33
- getSurface($theme) 0px,
34
- getSurface($theme) 10px,
35
- rgba(#ffffff, 0) calc(0% + 110px), // ok: structural
36
- rgba(#ffffff, 0) calc(100% - 110px), // ok: structural
37
- getSurface($theme) calc(100% - 10px)
38
- );
39
- }
40
-
41
- @mixin matcha-table-theme($theme) {
42
- $is-dark: map.get($theme, is-dark);
43
-
44
- // Vai direto na tag body
45
- body.is-mobile {
46
- .table-container {
47
- .table-container-shadow {
48
- overflow: auto;
49
- @include _matcha-table-theme-container-shadow-property($theme);
50
-
51
- .mat-table,
52
- .mat-sort {
53
- tbody {
54
- @include _matcha-table-theme-shadow-property($theme);
55
- }
56
- }
57
- }
58
- }
59
- }
60
-
61
- .table-container {
62
- width: 100%;
63
-
64
- .mat-table,
65
- .mat-sort {
66
- .published {
67
- color: getGreen($theme);
68
- }
69
-
70
- .notPublished {
71
- color: getAmber($theme);
72
- }
73
- }
74
-
75
- .table-container-shadow {
76
- overflow: auto;
77
- background: var(--matcha-color-surface, #{getSurface($theme)});
78
- border-radius: var(--matcha-radius-lg, 8px);
79
- @include _matcha-table-theme-container-shadow-property($theme);
80
-
81
- .mat-table,
82
- .mat-sort {
83
- tbody {
84
- @include _matcha-table-theme-shadow-property($theme);
85
- }
86
- }
87
-
88
- &.ps--active-x {
89
- @include _matcha-table-theme-container-shadow-property($theme);
90
-
91
- .mat-table,
92
- .mat-sort {
93
- @include _matcha-table-theme-shadow-property($theme);
94
- }
95
- }
96
- }
97
-
98
- .mat-table,
99
- .mat-sort,
100
- .mat-expansion-panel {
101
- thead {
102
- background: var(--matcha-color-surface, #{getSurface($theme)});
103
-
104
- th {
105
- height: var(--matcha-space-800, 64px);
106
- }
107
- }
108
-
109
- tr {
110
- &.mat-row {
111
- // &:nth-child(even){background: map-get($background, card);}
112
- &:nth-child(odd) {
113
- background: getBackgroundAlpha($theme);
114
- }
115
- }
116
-
117
- td,
118
- th {
119
- touch-action: unset !important;
120
- font-size: var(--matcha-text-body-md, 14px);
121
-
122
- &:first-child {
123
- padding-left: var(--matcha-space-300, 24px);
124
- }
125
-
126
- .clickable {
127
- cursor: pointer;
128
- }
129
- }
130
- }
131
-
132
- .td-duble-line {
133
- height: var(--matcha-space-600, 48px);
134
- }
135
-
136
- .td-with-image,
137
- .td-with-checkbox,
138
- .td-with-icon,
139
- .td-duble-line {
140
- display: flex;
141
- align-items: center;
142
-
143
- .td-text-aside {
144
- display: inline-block;
145
- width: calc(100% - var(--matcha-space-600, 48px));
146
- }
147
-
148
- .avatar {
149
- width: var(--matcha-space-600, 48px);
150
- min-width: var(--matcha-space-600, 48px);
151
- height: var(--matcha-space-600, 48px);
152
- line-height: var(--matcha-space-600, 48px);
153
- border-width: 0;
154
- margin-right: var(--matcha-space-300, 24px);
155
- }
156
-
157
- .thumbnail {
158
- width: calc(var(--matcha-space-600, 48px) + var(--matcha-space-300, 24px)); // 72
159
- min-width: calc(var(--matcha-space-600, 48px) + var(--matcha-space-300, 24px));
160
- height: var(--matcha-space-600, 48px);
161
- border-radius: var(--matcha-radius-lg, 8px);
162
- margin: 0 var(--matcha-space-100, 8px) 0 0;
163
-
164
- &-portrait {
165
- width: var(--matcha-avatar-lg, 56px);
166
- min-width: var(--matcha-avatar-lg, 56px);
167
- height: calc(var(--matcha-space-600, 48px) + var(--matcha-space-300, 24px)); // 72
168
- border-radius: var(--matcha-radius-lg, 8px);
169
- margin: 0 var(--matcha-space-100, 8px) 0 0;
170
- }
171
- }
172
- }
173
-
174
- .mat-header-cell {
175
- color: var(--matcha-color-fg, #{getForeground($theme)});
176
- font-family: var(--matcha-font-family);
177
- font-weight: 500;
178
- font-size: var(--matcha-text-body-md, 14px);
179
- padding-left: var(--matcha-space-100, 8px);
180
- padding-right: var(--matcha-space-100, 8px);
181
- border-bottom: var(--matcha-border-hairline, 1px) solid var(--matcha-color-border, #{getDisabled($theme)});
182
- }
183
-
184
- .mat-cell {
185
- color: var(--matcha-color-text-label, #{getBlueGrey($theme)});
186
- font-size: var(--matcha-text-body-md, 14px);
187
- padding-left: var(--matcha-space-100, 8px);
188
- padding-right: var(--matcha-space-100, 8px);
189
- white-space: nowrap;
190
- overflow: hidden;
191
- text-overflow: ellipsis;
192
- text-align: start;
193
- border-bottom: var(--matcha-border-hairline, 1px) solid var(--matcha-color-border, #{getDisabled($theme)});
194
-
195
- &.cdk-column-menu {
196
- text-align: left;
197
- }
198
- }
199
-
200
- .last {
201
- display: flex;
202
- justify-content: space-between;
203
- width: 100%;
204
- align-items: center;
205
-
206
- span {
207
- overflow: hidden;
208
- text-overflow: ellipsis;
209
- }
210
-
211
- mat-menu {
212
- display: none;
213
- }
214
- }
215
- }
216
-
217
- table {
218
- width: 100%;
219
- }
220
-
221
- .badge {
222
- border-radius: var(--matcha-radius-lg, 8px);
223
- padding: var(--matcha-space-100, 8px);
224
- color: var(--matcha-color-text-inverse, #{getForegroundInverse($theme)});
225
-
226
- &.live-badge {
227
- background-color: getCyan($theme);
228
- font-size: var(--matcha-text-body-md, 14px);
229
- }
230
-
231
- &.cell-badge {
232
- background-color: getPurple($theme);
233
- font-size: var(--matcha-text-body-md, 14px);
234
- }
235
-
236
- &.cult-badge {
237
- background-color: getBlue($theme);
238
- font-size: var(--matcha-text-body-md, 14px);
239
- }
240
-
241
- &.new-visitor-badge {
242
- background-color: var(--matcha-color-primary, #{getPrimary($theme)});
243
- color: var(--matcha-color-accent-contrast, #{getPrimaryContrast($theme)});
244
- font-size: var(--matcha-text-body-md, 14px);
245
- line-height: var(--matcha-leading-caption, 14px);
246
- display: inline-block;
247
- width: auto;
248
- }
249
- }
250
- }
251
-
252
- // X-Large devices (big desktops, 1440px and up < 1920)
253
- @include media-breakpoint('gt-md') {
254
- .table-container {
255
- .mat-table,
256
- .mat-sort {
257
- .mat-cell {
258
- font-size: var(--matcha-text-title-sm, 16px);
259
- }
260
- }
261
- }
262
- }
263
-
264
- //---------------------------------------------------------------------------
265
- // ESTILOS PARA O COMPONENTE MATCHA-TABLE
266
- //---------------------------------------------------------------------------
267
- // Estilos para tabelas nativas com a classe matcha-table
268
-
269
- .matcha-table {
270
- display: flex;
271
- flex-direction: column;
272
- width: 100%;
273
- gap: var(--matcha-space-200, 16px);
274
- border-collapse: collapse;
275
- border-spacing: 0;
276
- }
277
-
278
- // Vai direto na tag body
279
- body.is-mobile {
280
- .matcha-table {
281
- .matcha-table-container-shadow {
282
- overflow: auto;
283
- @include _matcha-table-theme-container-shadow-property($theme);
284
- table.matcha-table-content {
285
- tbody {
286
- @include _matcha-table-theme-shadow-property($theme);
287
- }
288
- }
289
- }
290
- }
291
- }
292
-
293
- // Estrutura
294
- // matcha-table
295
- // matcha-table-container
296
- // matcha-table-container-shadow
297
- // table.matcha-table-content
298
- // thead
299
- // tbody
300
-
301
- .matcha-table {
302
- --table-row-height: 64px; // comfortable = default (alinhado com Figma)
303
- --table-shadow-alpha: rgba(#{getForeground($theme)}, 0.05);
304
- .matcha-table-container-shadow {
305
- overflow: auto;
306
- background: var(--matcha-color-surface, #{getSurface($theme)});
307
- border-radius: var(--matcha-radius-lg, 8px);
308
- @include _matcha-table-theme-container-shadow-property($theme);
309
-
310
- table.matcha-table-content {
311
- width: 100%;
312
- border-collapse: collapse;
313
- border-spacing: 0;
314
- @include _matcha-table-theme-shadow-property($theme);
315
- thead {
316
- th {
317
- height: var(--table-row-height);
318
- background: var(--matcha-color-surface-hover, #{getBackgroundAlpha($theme)});
319
- color: var(--matcha-color-fg, #{getForeground($theme)});
320
- font-family: var(--matcha-font-family);
321
- font-weight: 600; // SemiBold (Figma Header)
322
- font-size: var(--matcha-text-body-md, 14px);
323
- text-align: left;
324
- padding-left: var(--matcha-space-300, 24px);
325
- padding-right: var(--matcha-space-200, 16px);
326
- border-bottom: var(--matcha-border-hairline, 1px) solid var(--matcha-color-border, #{getDisabled($theme)});
327
- }
328
- }
329
-
330
- tbody {
331
- tr {
332
- height: var(--table-row-height);
333
- // &:nth-child(even){background: map-get($background, card);}
334
- // &:nth-child(odd) {
335
- // background: getBackgroundAlpha($theme);
336
- // }
337
-
338
-
339
-
340
- td{
341
- color: var(--matcha-color-text-label, #{getBlueGrey($theme)});
342
- font-family: var(--matcha-font-family);
343
- font-size: var(--matcha-text-body-md, 14px); // body-md (Figma)
344
- padding-left: var(--matcha-space-100, 8px);
345
- padding-right: var(--matcha-space-100, 8px);
346
- white-space: nowrap;
347
- text-overflow: ellipsis;
348
- text-align: start;
349
- border-bottom: var(--matcha-border-hairline, 1px) solid var(--matcha-color-border, #{getDisabled($theme)});
350
- touch-action: unset !important;
351
- min-width: 120px;
352
-
353
- &:first-child {
354
- padding-left: var(--matcha-space-300, 24px);
355
- }
356
-
357
- }
358
- }
359
-
360
- // esse é um caso especifico para as tabelas que tem aninhamento de itens
361
- tr {
362
- &.equal {
363
-
364
- td,
365
- th {
366
- &:first-child {
367
- box-shadow: 4px 0 0 0 inset getBlue($theme), 10px 0 10px -10px getDisabled($theme);
368
- }
369
- }
370
-
371
- &.child-item {
372
-
373
- td,
374
- th {
375
- &:first-child {
376
- box-shadow: 4px 0 0 0 inset getBlueAlpha($theme), 10px 0 10px -10px getDisabled($theme);
377
- }
378
- }
379
- }
380
- }
381
-
382
- &.plus {
383
-
384
- td,
385
- th {
386
- &:first-child {
387
- box-shadow: 4px 0 0 0 inset getGreen($theme), 10px 0 10px -10px getDisabled($theme);
388
- }
389
- }
390
-
391
- &.child-item {
392
- td,
393
- th {
394
- &:first-child {
395
- box-shadow: 4px 0 0 0 inset getGreenAlpha($theme), 10px 0 10px -10px getDisabled($theme);
396
- }
397
- }
398
- }
399
- }
400
-
401
- &.minus {
402
-
403
- td,
404
- th {
405
- &:first-child {
406
- box-shadow: 4px 0 0 0 inset getRed($theme), 10px 0 10px -10px getDisabled($theme);
407
- }
408
- }
409
-
410
- &.child-item {
411
-
412
- td,
413
- th {
414
- &:first-child {
415
- box-shadow: 4px 0 0 0 inset getRedAlpha($theme), 10px 0 10px -10px getDisabled($theme);
416
- }
417
- }
418
- }
419
- }
420
- }
421
- }
422
- }
423
- }
424
- }
425
-
426
- // X-Large devices (big desktops, 1440px and up < 1920)
427
- @include media-breakpoint('gt-md') {
428
- .matcha-table {
429
- .matcha-table-container-shadow {
430
- table.matcha-table-content {
431
- .td {
432
- font-size: var(--matcha-text-title-sm, 16px);
433
- }
434
- }
435
- }
436
- }
437
- }
438
-
439
- // Variações de tamanho/densidade
440
- .matcha-table-compact {
441
- .matcha-table-container-shadow {
442
- table.matcha-table-content {
443
- --table-row-height: 48px;
444
-
445
- thead th {
446
- height: var(--table-row-height);
447
- padding-top: var(--matcha-space-100, 8px);
448
- padding-bottom: var(--matcha-space-100, 8px);
449
- font-size: var(--matcha-text-body-md, 14px);
450
- }
451
-
452
- tbody tr {
453
- height: var(--table-row-height);
454
-
455
- td {
456
- padding-top: var(--matcha-space-100, 8px);
457
- padding-bottom: var(--matcha-space-100, 8px);
458
- font-size: var(--matcha-text-body-md, 14px);
459
- }
460
- }
461
- }
462
- }
463
- }
464
-
465
- .matcha-table-comfortable {
466
- // Estilo padrão de densidade (já aplicado na estrutura base)
467
- .matcha-table-container-shadow {
468
- table.matcha-table-content {
469
- --table-row-height: 64px;
470
-
471
- thead th {
472
- height: var(--table-row-height);
473
- padding-top: var(--matcha-space-150, 12px);
474
- padding-bottom: var(--matcha-space-150, 12px);
475
- }
476
-
477
- tbody tr {
478
- height: var(--table-row-height);
479
-
480
- td {
481
- padding-top: var(--matcha-space-150, 12px);
482
- padding-bottom: var(--matcha-space-150, 12px);
483
- }
484
- }
485
- }
486
- }
487
- }
488
-
489
- .matcha-table-spacious {
490
- .matcha-table-container-shadow {
491
- table.matcha-table-content {
492
- --table-row-height: 80px;
493
-
494
- thead th {
495
- height: var(--table-row-height);
496
- padding-top: var(--matcha-space-200, 16px);
497
- padding-bottom: var(--matcha-space-200, 16px);
498
- font-size: var(--matcha-text-title-md, 18px);
499
- }
500
-
501
- tbody tr {
502
- height: var(--table-row-height);
503
-
504
- td {
505
- padding-top: var(--matcha-space-200, 16px);
506
- padding-bottom: var(--matcha-space-200, 16px);
507
- font-size: var(--matcha-text-title-md, 18px);
508
- }
509
- }
510
- }
511
- }
512
- }
513
-
514
- // Linhas zebras
515
- .matcha-table-striped {
516
- .matcha-table-container-shadow {
517
- table.matcha-table-content {
518
- tbody tr {
519
- &:nth-child(odd) {
520
- background: var(--table-shadow-alpha);
521
- }
522
-
523
- &:nth-child(even) {
524
- background: transparent;
525
- }
526
- }
527
- }
528
- }
529
- }
530
-
531
- // Hover nas linhas — Template A: tr é a área interativa
532
- .matcha-table-hover {
533
- .matcha-table-container-shadow {
534
- table.matcha-table-content {
535
- tbody tr {
536
- position: relative;
537
- overflow: hidden;
538
- cursor: pointer;
539
-
540
- &::before {
541
- content: '';
542
- position: absolute;
543
- inset: 0;
544
- background: currentColor;
545
- opacity: 0;
546
- border-radius: inherit;
547
- pointer-events: none;
548
- transition: opacity var(--matcha-duration-instant, 80ms) linear;
549
- }
550
-
551
- &:hover:not([disabled])::before { opacity: var(--matcha-state-hover, 0.08); }
552
- &:active:not([disabled])::before { opacity: var(--matcha-state-active, 0.12); }
553
- &[disabled] { pointer-events: none; cursor: default; }
554
-
555
- @media (prefers-reduced-motion: reduce) {
556
- &::before { transition: none; }
557
- }
558
-
559
- &:focus-visible:not([disabled]) {
560
- outline: var(--matcha-state-focus-ring-width, 2px) solid var(--matcha-color-accent, #{getAccent($theme)});
561
- outline-offset: var(--matcha-state-focus-ring-offset, 2px);
562
- }
563
- }
564
- }
565
- }
566
- }
567
-
568
- // Bordas visíveis
569
- .matcha-table-bordered {
570
- .matcha-table-container-shadow {
571
- table.matcha-table-content {
572
- border: var(--matcha-border-hairline, 1px) solid var(--matcha-color-border, #{getDisabled($theme)});
573
-
574
- thead th {
575
- border-bottom: var(--matcha-border-hairline, 1px) solid var(--matcha-color-border, #{getDisabled($theme)});
576
- border-right: var(--matcha-border-hairline, 1px) solid var(--matcha-color-border, #{getDisabled($theme)});
577
-
578
- &:last-child {
579
- border-right: none;
580
- }
581
- }
582
-
583
- tbody tr {
584
- td {
585
- border-bottom: var(--matcha-border-hairline, 1px) solid var(--matcha-color-border, #{getDisabled($theme)});
586
- border-right: var(--matcha-border-hairline, 1px) solid var(--matcha-color-border, #{getDisabled($theme)});
587
-
588
- &:last-child {
589
- border-right: none;
590
- }
591
- }
592
-
593
- &:last-child td {
594
- border-bottom: none;
595
- }
596
- }
597
- }
598
- }
599
- }
600
-
601
- // Cabeçalho fixo (sticky)
602
- .matcha-table-sticky-header {
603
- .matcha-table-container-shadow {
604
- table.matcha-table-content {
605
- thead {
606
- position: sticky;
607
- top: 0;
608
- z-index: 10;
609
- display: table-header-group;
610
- }
611
-
612
- thead th {
613
- position: sticky;
614
- top: 0;
615
- z-index: 11;
616
- box-shadow: 0 2px 4px var(--table-shadow-alpha);
617
- }
618
- }
619
- }
620
- }
621
-
622
- // Colunas fixas (sticky columns) - primeira coluna fixa por padrão quando há scroll
623
- .matcha-table-sticky-start {
624
- .matcha-table-container-shadow {
625
- table.matcha-table-content {
626
- thead th:first-child,
627
- tbody tr td:first-child {
628
- position: sticky;
629
- left: 0;
630
- z-index: 5;
631
- background: var(--matcha-color-surface, #{getSurface($theme)});
632
- }
633
-
634
- thead th:first-child {
635
- z-index: 15;
636
- box-shadow: 10px 0 10px -10px getDisabled($theme);
637
-
638
- }
639
-
640
- tbody tr td:first-child {
641
- box-shadow: 10px 0 10px -10px getDisabled($theme);
642
-
643
- }
644
- }
645
- }
646
-
647
- // Para múltiplas colunas fixas no início
648
- &.matcha-table-sticky-start-2 {
649
- .matcha-table-container-shadow {
650
- table.matcha-table-content {
651
- thead th:nth-child(1),
652
- thead th:nth-child(2),
653
- tbody tr td:nth-child(1),
654
- tbody tr td:nth-child(2) {
655
- position: sticky;
656
- z-index: 5;
657
- background: var(--matcha-color-surface, #{getSurface($theme)});
658
- }
659
-
660
- thead th:nth-child(1),
661
- tbody tr td:nth-child(1) {
662
- left: 0;
663
- z-index: 15;
664
- box-shadow: 2px 0 4px var(--table-shadow-alpha);
665
- }
666
-
667
- thead th:nth-child(2),
668
- tbody tr td:nth-child(2) {
669
- left: 200px; // Ajustar conforme largura da primeira coluna
670
- z-index: 14;
671
- box-shadow: 2px 0 4px var(--table-shadow-alpha);
672
- }
673
- }
674
- }
675
- }
676
-
677
- &.matcha-table-sticky-start-3 {
678
- .matcha-table-container-shadow {
679
- table.matcha-table-content {
680
- thead th:nth-child(1),
681
- thead th:nth-child(2),
682
- thead th:nth-child(3),
683
- tbody tr td:nth-child(1),
684
- tbody tr td:nth-child(2),
685
- tbody tr td:nth-child(3) {
686
- position: sticky;
687
- z-index: 5;
688
- background: var(--matcha-color-surface, #{getSurface($theme)});
689
- }
690
-
691
- thead th:nth-child(1),
692
- tbody tr td:nth-child(1) {
693
- left: 0;
694
- z-index: 17;
695
- box-shadow: 2px 0 4px var(--table-shadow-alpha);
696
- }
697
-
698
- thead th:nth-child(2),
699
- tbody tr td:nth-child(2) {
700
- left: 200px;
701
- z-index: 16;
702
- box-shadow: 2px 0 4px var(--table-shadow-alpha);
703
- }
704
-
705
- thead th:nth-child(3),
706
- tbody tr td:nth-child(3) {
707
- left: 400px;
708
- z-index: 15;
709
- box-shadow: 2px 0 4px var(--table-shadow-alpha);
710
- }
711
- }
712
- }
713
- }
714
- }
715
-
716
- .matcha-table-sticky-end {
717
- .matcha-table-container-shadow {
718
- table.matcha-table-content {
719
- thead th:last-child,
720
- tbody tr td:last-child {
721
- position: sticky;
722
- right: 0;
723
- z-index: 5;
724
- background: var(--matcha-color-surface, #{getSurface($theme)});
725
- }
726
-
727
- thead th:last-child {
728
- z-index: 15;
729
- box-shadow: -2px 0 4px var(--table-shadow-alpha);
730
- }
731
-
732
- tbody tr td:last-child {
733
- box-shadow: -2px 0 2px var(--table-shadow-alpha);
734
- }
735
- }
736
- }
737
-
738
- // Para múltiplas colunas fixas no final
739
- &.matcha-table-sticky-end-2 {
740
- .matcha-table-container-shadow {
741
- table.matcha-table-content {
742
- thead th:nth-last-child(1),
743
- thead th:nth-last-child(2),
744
- tbody tr td:nth-last-child(1),
745
- tbody tr td:nth-last-child(2) {
746
- position: sticky;
747
- z-index: 5;
748
- background: var(--matcha-color-surface, #{getSurface($theme)});
749
- }
750
-
751
- thead th:nth-last-child(1),
752
- tbody tr td:nth-last-child(1) {
753
- right: 0;
754
- z-index: 15;
755
- box-shadow: -2px 0 4px var(--table-shadow-alpha);
756
- }
757
-
758
- thead th:nth-last-child(2),
759
- tbody tr td:nth-last-child(2) {
760
- right: 200px; // Ajustar conforme largura da última coluna
761
- z-index: 14;
762
- box-shadow: -2px 0 4px var(--table-shadow-alpha);
763
- }
764
- }
765
- }
766
- }
767
- }
768
-
769
- // ── Alinhamento de colunas (espelhado com Figma Alinhamento variant) ──
770
- .matcha-table {
771
- .matcha-table-container-shadow {
772
- table.matcha-table-content {
773
- th.text-center,
774
- td.text-center {
775
- text-align: center;
776
- }
777
-
778
- th.text-right,
779
- td.text-right {
780
- text-align: right;
781
- }
782
- }
783
- }
784
- }
785
- }
1
+ @use "sass:map";
2
+
3
+ // =============================================================================
4
+ // matcha-table — `<table matcha-table>` directive (1:1 Figma DSV3 15641:275)
5
+ //
6
+ // API canon:
7
+ // <table matcha-table size="comfortable" striped hover bordered stickyHeader
8
+ // [stickyStart]="N" [stickyEnd]="N" [loading]="isLoading">
9
+ // <thead><tr><th>...</th></tr></thead>
10
+ // <tbody><tr><td>...</td></tr></tbody>
11
+ // </table>
12
+ //
13
+ // Companion directives (a11y automática):
14
+ // [matcha-table-sortable] em <th> — aria-sort + tabindex + keyboard
15
+ // [matcha-table-clickable] em <tr> — tabindex + Enter/Space + (rowClick)
16
+ //
17
+ // Helpers CSS-only:
18
+ // td.numeric → tabular-nums
19
+ // td.truncate ellipsis (text overflow)
20
+ // td[data-alinhamento] / td.text-{center,right} alinhamento
21
+ // tr.equal/.plus/.minus → variant semantic accent (cor via CSS var)
22
+ // tr.child-item → indent + accent esmaecido
23
+ // tr.is-selected → highlight
24
+ // =============================================================================
25
+
26
+ @mixin matcha-table-modern($theme) {
27
+ $is-dark: map.get($theme, is-dark);
28
+
29
+ // ═══════════════════════════════════════════════════════════════════════
30
+ // CSS vars do componente — única fonte de verdade. ZERO literal hardcoded
31
+ // fora deste bloco. Consumer override qualquer um no escopo do <table>.
32
+ // ═══════════════════════════════════════════════════════════════════════
33
+ table.matcha-table {
34
+ // ── Dimensions ────────────────────────────────────────────────────────
35
+ // Calibrado pra density moderna (Stripe/Linear/Notion). Comfortable era 52
36
+ // antes apertado em telas wide. 58px equilibra densidade × respiro.
37
+ --matcha-table-cell-height-compact: var(--matcha-space-500, 40px);
38
+ --matcha-table-cell-height-comfortable: 58px;
39
+ --matcha-table-cell-height-spacious: var(--matcha-space-800, 64px);
40
+ // Padding uniforme L/R — assimétrico cria sensação de "primeira coluna
41
+ // afastada do resto". 16px ambos lados é canon moderno.
42
+ --matcha-table-cell-padding-x-left: var(--matcha-space-200, 16px);
43
+ --matcha-table-cell-padding-x-right: var(--matcha-space-200, 16px);
44
+ --matcha-table-cell-min-width: var(--matcha-space-1500, 120px);
45
+ --matcha-table-paginator-spacing: var(--matcha-space-300, 24px);
46
+
47
+ // ── Typography (modern density Stripe/Linear) ─────────────────────────
48
+ --matcha-table-font-size: 13px;
49
+ --matcha-table-font-line-height: 18px;
50
+ --matcha-table-header-font-size: var(--matcha-text-body-sm, 12px);
51
+ --matcha-table-header-font-line-height: var(--matcha-leading-body-sm, 16px);
52
+ --matcha-table-header-letter-spacing: 0.04em;
53
+
54
+ // ── Borders / radius ──────────────────────────────────────────────────
55
+ --matcha-table-border-color: var(--matcha-color-interaction-disabled-border);
56
+ --matcha-table-border-header: var(--matcha-border-thin, 2px);
57
+ --matcha-table-border-row: var(--matcha-border-hairline, 1px);
58
+ --matcha-table-bordered-radius: var(--matcha-radius-md, 4px);
59
+
60
+ // ── Surface colors ────────────────────────────────────────────────────
61
+ --matcha-table-cell-bg: var(--matcha-color-surface-card);
62
+ --matcha-table-row-bg-selected: var(--matcha-color-accent-alpha-12,
63
+ rgba(#{getAccent($theme)}, 0.12));
64
+ --matcha-table-row-bg-striped: var(--matcha-color-surface-card-alt,
65
+ rgba(#{getForeground($theme)}, 0.02));
66
+ // Hover NÃO usa surface-table-row-hover token (tá próximo demais de surface-card
67
+ // em dark e fica imperceptível). Calibrado pra delta visível mesmo sobre stripe.
68
+ // CSS custom property values são TEXTO LITERAL pro Sass — fn calls Sass
69
+ // dentro NÃO são avaliadas. Precisa interpolação `#{}` pra forçar Sass a
70
+ // evaluar `getForeground($theme)` ANTES do output. Sem isso, o valor sai
71
+ // literal no bundle (ex: `rgba(getForeground($theme), 0.12)`) e o browser
72
+ // descarta como invalid CSS (= chevron invisível, hover sem cor, etc).
73
+ --matcha-table-row-bg-hover: rgba(#{getForeground($theme)}, 0.12);
74
+ --matcha-table-row-bg-hover-striped: rgba(#{getForeground($theme)}, 0.18);
75
+ --matcha-table-header-bg-hover: rgba(#{getForeground($theme)}, 0.10);
76
+
77
+ // ── Sort indicator colors ─────────────────────────────────────────────
78
+ // Inactive usa alpha 0.45 no foreground — claramente VISÍVEL como "ali tem
79
+ // sort", sem competir com texto do header. Hover/ativo passa pra accent full.
80
+ --matcha-table-sort-icon-color: rgba(#{getForeground($theme)}, 0.45);
81
+ --matcha-table-sort-icon-color-active: var(--matcha-color-accent, #{getAccent($theme)});
82
+ --matcha-table-sort-icon-size: var(--matcha-space-250, 20px);
83
+
84
+ // ── Empty cell placeholder ────────────────────────────────────────────
85
+ --matcha-table-empty-cell-text: var(--matcha-color-text-muted,
86
+ rgba(#{getForeground($theme)}, 0.5));
87
+
88
+ // ── Variant accent (semantic row) ─────────────────────────────────────
89
+ --matcha-table-variant-accent-width: var(--matcha-space-050, 4px);
90
+ --matcha-table-row-accent-child-opacity: 0.5;
91
+ --matcha-table-selected-accent-width: var(--matcha-border-thin, 2px);
92
+ --matcha-table-selected-accent-color: var(--matcha-color-accent, #{getAccent($theme)});
93
+
94
+ // ── Column width hints (utility classes col-*) ────────────────────────
95
+ --matcha-table-col-checkbox-width: var(--matcha-space-600, 48px);
96
+ --matcha-table-col-id-width: var(--matcha-space-1000, 80px);
97
+ --matcha-table-col-narrow-width: var(--matcha-space-1500, 120px);
98
+ --matcha-table-col-medium-width: var(--matcha-space-2500, 200px);
99
+
100
+ // ── States / animations ───────────────────────────────────────────────
101
+ --matcha-table-disabled-opacity: var(--matcha-state-disabled-opacity, 0.5);
102
+ --matcha-table-loading-pulse-duration: var(--matcha-duration-slow, 1500ms);
103
+ --matcha-table-loading-pulse-opacity-min: 0.5;
104
+ --matcha-table-transition-duration: var(--matcha-duration-instant, 80ms);
105
+ --matcha-table-focus-ring-width: var(--matcha-state-focus-ring-width, 2px);
106
+ --matcha-table-focus-ring-color: var(--matcha-color-accent, #{getAccent($theme)});
107
+
108
+ // ── Empty state row (matcha-table-empty directive) ────────────────────
109
+ --matcha-table-empty-padding-y: var(--matcha-space-500, 40px);
110
+ --matcha-table-empty-padding-x: var(--matcha-space-300, 24px);
111
+
112
+ // ── Resize handle (matcha-table-resizable directive) ──────────────────
113
+ --matcha-table-resize-handle-width: var(--matcha-space-100, 8px);
114
+ --matcha-table-resize-indicator-width: var(--matcha-border-hairline, 1px);
115
+ --matcha-table-resize-indicator-height: 50%;
116
+ --matcha-table-resize-indicator-top: 25%;
117
+
118
+ // ── Sticky cols shadow ────────────────────────────────────────────────
119
+ --matcha-table-sticky-shadow-offset: var(--matcha-space-100, 8px);
120
+ --matcha-table-sticky-shadow-blur: var(--matcha-space-200, 16px);
121
+ --matcha-table-sticky-shadow-color: var(--matcha-color-elevation-shadow, #000);
122
+ --matcha-table-sticky-shadow-alpha: 16%;
123
+ }
124
+
125
+ // ── Base — display table nativo + typography via vars ─────────────────
126
+ table.matcha-table {
127
+ display: table;
128
+ width: 100%;
129
+ border-collapse: collapse;
130
+ border-spacing: 0;
131
+ font-family: var(--matcha-font-family);
132
+ font-size: var(--matcha-table-font-size);
133
+ line-height: var(--matcha-table-font-line-height);
134
+ font-weight: var(--matcha-weight-regular, 400);
135
+ color: var(--matcha-color-text-secondary,
136
+ rgba(getForeground($theme), 0.7));
137
+
138
+ // ── Header cells (text/primary, border-bottom 2px, height 64) ────────
139
+ thead th {
140
+ box-sizing: border-box;
141
+ height: var(--matcha-table-cell-height-comfortable);
142
+ min-width: var(--matcha-table-cell-min-width);
143
+ padding: 0
144
+ var(--matcha-table-cell-padding-x-right)
145
+ 0
146
+ var(--matcha-table-cell-padding-x-left);
147
+ background: var(--matcha-table-cell-bg);
148
+ color: var(--matcha-color-text-primary,
149
+ var(--matcha-color-fg, #{getForeground($theme)}));
150
+ // Header menor que body — hierarquia "metadado" vs "conteúdo".
151
+ font-size: var(--matcha-table-header-font-size);
152
+ line-height: var(--matcha-table-header-font-line-height);
153
+ font-weight: var(--matcha-weight-semibold, 600);
154
+ letter-spacing: var(--matcha-table-header-letter-spacing);
155
+ text-align: left;
156
+ vertical-align: middle;
157
+ border-bottom: var(--matcha-table-border-header) solid
158
+ var(--matcha-table-border-color);
159
+
160
+ // Alinhamento — aceita data-attr canon DSV3 + utility classes legacy
161
+ &[data-alinhamento="center"], &.text-center { text-align: center; }
162
+ &[data-alinhamento="right"], &.text-right { text-align: right; }
163
+
164
+ // ── Sortable hint ([matcha-table-sortable] directive seta os attrs) ──
165
+ &[data-sortable] {
166
+ cursor: pointer;
167
+ user-select: none;
168
+ // SEMPRE reserva espaço pro chevron (mesmo inativo) — chevron entra/sai
169
+ // via opacity. Sem padding condicional → texto NÃO desloca no hover.
170
+ padding-right: calc(var(--matcha-table-cell-padding-x-right) +
171
+ var(--matcha-table-sort-icon-size));
172
+ position: relative;
173
+
174
+ // Hover NÃO muda bg do header — bg-change era o que fazia o user
175
+ // perceber "movimento" quando o chevron entrava ao mesmo tempo.
176
+ // Manter header estático no hover, só chevron aparece com opacity.
177
+ // Cursor pointer + chevron fade já comunicam interatividade.
178
+
179
+ // Sort indicators — SVG 1:1 com `matcha/icon/arrow` (figma-icons.ts).
180
+ // Estado inativo (none) = INVISÍVEL (opacity 0). Aparece no hover do header
181
+ // com opacity faded, full quando ativo (asc/desc). Pattern canon Stripe/Linear:
182
+ // sortable em todas as colunas, mas indicador só na que tá ordenando.
183
+ &::after {
184
+ content: '';
185
+ position: absolute;
186
+ right: var(--matcha-table-cell-padding-x-right);
187
+ top: 50%;
188
+ transform: translateY(-50%);
189
+ width: var(--matcha-table-sort-icon-size);
190
+ height: var(--matcha-table-sort-icon-size);
191
+ background: var(--matcha-table-sort-icon-color);
192
+ transition: background-color var(--matcha-table-transition-duration) linear;
193
+ mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M11 7.82499L6.1 12.725C5.9 12.925 5.66667 13.0208 5.4 13.0125C5.13333 13.0042 4.9 12.9 4.7 12.7C4.51667 12.5 4.42083 12.2667 4.4125 12C4.40417 11.7333 4.5 11.5 4.7 11.3L11.3 4.69999C11.4 4.59999 11.5083 4.52915 11.625 4.48749C11.7417 4.44582 11.8667 4.42499 12 4.42499C12.1333 4.42499 12.2583 4.44582 12.375 4.48749C12.4917 4.52915 12.6 4.59999 12.7 4.69999L19.3 11.3C19.4833 11.4833 19.575 11.7125 19.575 11.9875C19.575 12.2625 19.4833 12.5 19.3 12.7C19.1 12.9 18.8625 13 18.5875 13C18.3125 13 18.075 12.9 17.875 12.7L13 7.82499V19C13 19.2833 12.9042 19.5208 12.7125 19.7125C12.5208 19.9042 12.2833 20 12 20C11.7167 20 11.4792 19.9042 11.2875 19.7125C11.0958 19.5208 11 19.2833 11 19V7.82499Z'/></svg>")
194
+ center/contain no-repeat;
195
+ }
196
+
197
+ // Hover no header — chevron escurece pra foreground full (já visível
198
+ // muted antes via alpha 0.45). Reforça que tá interativo.
199
+ &:hover::after {
200
+ background: var(--matcha-color-text-primary,
201
+ var(--matcha-color-fg, #{getForeground($theme)}));
202
+ }
203
+
204
+ // Padding-right SEMPRE reserva espaço pro chevron. Antes ajustava
205
+ // condicionalmente (sem padding extra no inativo) — causava text
206
+ // "dançar" 20px ao hover quando padding crescia pra acomodar arrow.
207
+ // Mantém estável: chevron entra via opacity, sem reflow do texto.
208
+
209
+ &[data-sort-direction="asc"]::after {
210
+ mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M11 7.82499L6.1 12.725C5.9 12.925 5.66667 13.0208 5.4 13.0125C5.13333 13.0042 4.9 12.9 4.7 12.7C4.51667 12.5 4.42083 12.2667 4.4125 12C4.40417 11.7333 4.5 11.5 4.7 11.3L11.3 4.69999C11.4 4.59999 11.5083 4.52915 11.625 4.48749C11.7417 4.44582 11.8667 4.42499 12 4.42499C12.1333 4.42499 12.2583 4.44582 12.375 4.48749C12.4917 4.52915 12.6 4.59999 12.7 4.69999L19.3 11.3C19.4833 11.4833 19.575 11.7125 19.575 11.9875C19.575 12.2625 19.4833 12.5 19.3 12.7C19.1 12.9 18.8625 13 18.5875 13C18.3125 13 18.075 12.9 17.875 12.7L13 7.82499V19C13 19.2833 12.9042 19.5208 12.7125 19.7125C12.5208 19.9042 12.2833 20 12 20C11.7167 20 11.4792 19.9042 11.2875 19.7125C11.0958 19.5208 11 19.2833 11 19V7.82499Z'/></svg>")
211
+ center/contain no-repeat;
212
+ background: var(--matcha-table-sort-icon-color-active);
213
+ }
214
+
215
+ &[data-sort-direction="desc"]::after {
216
+ mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M11 16.175V5C11 4.71667 11.0958 4.47917 11.2875 4.2875C11.4792 4.09583 11.7167 4 12 4C12.2833 4 12.5208 4.09583 12.7125 4.2875C12.9042 4.47917 13 4.71667 13 5V16.175L17.9 11.275C18.1 11.075 18.3333 10.9792 18.6 10.9875C18.8667 10.9958 19.1 11.1 19.3 11.3C19.4833 11.5 19.5792 11.7333 19.5875 12C19.5958 12.2667 19.5 12.5 19.3 12.7L12.7 19.3C12.6 19.4 12.4917 19.4708 12.375 19.5125C12.2583 19.5542 12.1333 19.575 12 19.575C11.8667 19.575 11.7417 19.5542 11.625 19.5125C11.5083 19.4708 11.4 19.4 11.3 19.3L4.7 12.7C4.51667 12.5167 4.425 12.2875 4.425 12.0125C4.425 11.7375 4.51667 11.5 4.7 11.3C4.9 11.1 5.1375 11 5.4125 11C5.6875 11 5.925 11.1 6.125 11.3L11 16.175Z'/></svg>")
217
+ center/contain no-repeat;
218
+ background: var(--matcha-table-sort-icon-color-active);
219
+ }
220
+
221
+ // Header right-aligned com sort — chevron vem ANTES do texto (canon).
222
+ &[data-alinhamento="right"], &.text-right {
223
+ padding-right: var(--matcha-table-cell-padding-x-right);
224
+ padding-left: calc(var(--matcha-table-cell-padding-x-left) +
225
+ var(--matcha-table-sort-icon-size));
226
+
227
+ &::after {
228
+ right: auto;
229
+ left: var(--matcha-table-cell-padding-x-left);
230
+ }
231
+ }
232
+
233
+ // Focus ring quando keyboard-navigated (tabindex via directive).
234
+ &:focus-visible {
235
+ outline: var(--matcha-table-focus-ring-width) solid
236
+ var(--matcha-table-focus-ring-color);
237
+ outline-offset: calc(-1 * var(--matcha-table-focus-ring-width));
238
+ }
239
+ }
240
+ }
241
+
242
+ // ── Body cells ────────────────────────────────────────────────────────
243
+ tbody td {
244
+ box-sizing: border-box;
245
+ height: var(--matcha-table-cell-height-comfortable);
246
+ min-width: var(--matcha-table-cell-min-width);
247
+ padding: 0
248
+ var(--matcha-table-cell-padding-x-right)
249
+ 0
250
+ var(--matcha-table-cell-padding-x-left);
251
+ background: var(--matcha-table-cell-bg);
252
+ color: var(--matcha-color-text-secondary,
253
+ rgba(getForeground($theme), 0.7));
254
+ vertical-align: middle;
255
+ border-bottom: var(--matcha-table-border-row) solid
256
+ var(--matcha-table-border-color);
257
+ transition: background-color var(--matcha-table-transition-duration) linear;
258
+
259
+ &[data-alinhamento="center"], &.text-center { text-align: center; }
260
+ &[data-alinhamento="right"], &.text-right { text-align: right; }
261
+
262
+ // Helper: tabular-nums (alinha decimais)
263
+ &[data-numeric], &.numeric {
264
+ font-variant-numeric: tabular-nums;
265
+ font-feature-settings: 'tnum';
266
+ }
267
+
268
+ // Helper: ellipsis (texto longo)
269
+ &[data-truncate], &.truncate {
270
+ max-width: 0;
271
+ white-space: nowrap;
272
+ overflow: hidden;
273
+ text-overflow: ellipsis;
274
+ }
275
+
276
+ // Helper: cells vazias preenchidas com "—" muted (canon moderno).
277
+ &:empty::after {
278
+ content: '—';
279
+ color: var(--matcha-table-empty-cell-text);
280
+ }
281
+ }
282
+
283
+ // ── Column width hints (aplicar em <th> — <td> herda pela coluna) ─────
284
+ thead th,
285
+ tbody td {
286
+ &.col-checkbox { width: var(--matcha-table-col-checkbox-width); text-align: center; }
287
+ &.col-id { width: var(--matcha-table-col-id-width); }
288
+ &.col-narrow { width: var(--matcha-table-col-narrow-width); }
289
+ &.col-medium { width: var(--matcha-table-col-medium-width); }
290
+ // Actions / icon-buttons — shrink-to-content (1% truque de table layout).
291
+ // Children inline horizontal right-aligned (canon Figma: edit/delete lado a
292
+ // lado, não stackados).
293
+ //
294
+ // Importante: `.matcha-button` tem `display: flex` (block-level) que faria
295
+ // os icon-buttons empilharem verticalmente. Override via selector descendant
296
+ // com specificity maior pra forçar inline-flex no contexto de actions cell.
297
+ //
298
+ // Padding-right ZERO no body — icon-button já tem click target padding
299
+ // interno; somar padding ao td empurraria os botões pra ESQUERDA do edge
300
+ // do header "Ações". Alinhamento perfeito: button box-right = cell-right.
301
+ // Actions / icon-buttons — shrink-to-content (1% truque de table layout).
302
+ // Children inline horizontal LEFT-aligned (header text "Ações" alinha
303
+ // naturalmente acima do primeiro ícone). Padding uniforme L/R com resto
304
+ // da table.
305
+ &.col-actions {
306
+ width: 1%;
307
+ white-space: nowrap;
308
+ text-align: left;
309
+
310
+ > .matcha-button,
311
+ > button[matcha-icon-button],
312
+ > * {
313
+ display: inline-flex;
314
+ vertical-align: middle;
315
+ }
316
+ > * + * {
317
+ margin-left: var(--matcha-space-050, 4px);
318
+ }
319
+ }
320
+ // Greedy = espaço residual (default, classe explícita pra documentação).
321
+ &.col-greedy { width: auto; }
322
+ }
323
+
324
+ // ── Paginator alinhado após table (convention) ────────────────────────
325
+ // Sem margin-top — paginator gruda no border-bottom da última row.
326
+ // Spacing visual vem dos paddings internos do próprio matcha-paginator.
327
+ .matcha-table-paginator,
328
+ & + matcha-paginator {
329
+ display: block;
330
+ margin-top: 0;
331
+ }
332
+
333
+ // ── Row clickable ([matcha-table-clickable] directive seta tabindex)
334
+ tbody tr.is-clickable {
335
+ cursor: pointer;
336
+
337
+ &:hover td {
338
+ --matcha-table-cell-bg: var(--matcha-table-row-bg-hover);
339
+ }
340
+
341
+ &:focus-visible {
342
+ outline: var(--matcha-table-focus-ring-width) solid
343
+ var(--matcha-table-focus-ring-color);
344
+ outline-offset: calc(-1 * var(--matcha-table-focus-ring-width));
345
+ }
346
+ }
347
+
348
+ // ── Modifiers via host classes (Angular bind quando striped/hover/etc) ─
349
+ // Striped usa :where() pra dropar specificity do :nth-child — hover vence.
350
+ &.matcha-table-striped tbody tr:where(:nth-child(even)) td {
351
+ --matcha-table-cell-bg: var(--matcha-table-row-bg-striped);
352
+ }
353
+
354
+ &.matcha-table-hover tbody tr:hover td {
355
+ --matcha-table-cell-bg: var(--matcha-table-row-bg-hover);
356
+ }
357
+
358
+ // Stripe-aware hover: row PAR ganha alpha mais forte pra preservar stripe.
359
+ &.matcha-table-striped tbody tr:where(:nth-child(even)).is-clickable:hover td,
360
+ &.matcha-table-striped.matcha-table-hover tbody tr:where(:nth-child(even)):hover td {
361
+ --matcha-table-cell-bg: var(--matcha-table-row-bg-hover-striped);
362
+ }
363
+
364
+ tbody tr.is-selected td {
365
+ --matcha-table-cell-bg: var(--matcha-table-row-bg-selected);
366
+ }
367
+ // Selected row ganha border-left accent affordance canon Linear/Notion.
368
+ // No <tr> → não some com stickyStart. Usa ::after pra coexistir com
369
+ // ::before do variant accent sem conflito.
370
+ tbody tr.is-selected {
371
+ position: relative;
372
+
373
+ &::after {
374
+ content: '';
375
+ position: absolute;
376
+ top: 0;
377
+ left: 0;
378
+ width: var(--matcha-table-selected-accent-width);
379
+ height: 100%;
380
+ background: var(--matcha-table-selected-accent-color);
381
+ pointer-events: none;
382
+ z-index: 2; // acima do variant accent (z-index 1)
383
+ }
384
+ }
385
+
386
+ // Bordered — box-shadow inset em vez de border real (não clipa shadows
387
+ // externos das sticky cols, que projetam pra fora da <table>).
388
+ &.matcha-table-bordered {
389
+ box-shadow: inset 0 0 0 var(--matcha-table-border-row)
390
+ var(--matcha-table-border-color);
391
+ border-radius: var(--matcha-table-bordered-radius);
392
+ }
393
+
394
+ // Sticky header (vertical scroll)
395
+ &.matcha-table-sticky-header thead th {
396
+ position: sticky;
397
+ top: 0;
398
+ z-index: 1;
399
+ }
400
+
401
+ // Size variants (data-size cascateia altura)
402
+ &[data-size="compact"] thead th,
403
+ &[data-size="compact"] tbody td { height: var(--matcha-table-cell-height-compact); }
404
+ &[data-size="spacious"] thead th,
405
+ &[data-size="spacious"] tbody td { height: var(--matcha-table-cell-height-spacious); }
406
+
407
+ // ── Sticky columns (start/end) — canon scroll horizontal ──────────────
408
+ // Shadow scroll-edge via color-mix() pra tokenizar — funciona em light
409
+ // E dark. Offsets/blur/cor todos via var.
410
+ @for $i from 1 through 4 {
411
+ &[data-sticky-start="#{$i}"] {
412
+ thead th:nth-child(-n+#{$i}),
413
+ tbody tr td:nth-child(-n+#{$i}) {
414
+ position: sticky;
415
+ z-index: 2;
416
+ background: var(--matcha-table-cell-bg);
417
+ }
418
+ // Última cell do grupo sticky-start projeta shadow scroll-edge.
419
+ thead th:nth-child(#{$i}),
420
+ tbody tr td:nth-child(#{$i}) {
421
+ box-shadow: var(--matcha-table-sticky-shadow-offset) 0
422
+ var(--matcha-table-sticky-shadow-blur)
423
+ calc(-1 * var(--matcha-table-sticky-shadow-offset))
424
+ color-mix(in srgb, var(--matcha-table-sticky-shadow-color)
425
+ var(--matcha-table-sticky-shadow-alpha), transparent);
426
+ }
427
+ }
428
+
429
+ &[data-sticky-end="#{$i}"] {
430
+ thead th:nth-last-child(-n+#{$i}),
431
+ tbody tr td:nth-last-child(-n+#{$i}) {
432
+ position: sticky;
433
+ z-index: 2;
434
+ background: var(--matcha-table-cell-bg);
435
+ }
436
+ thead th:nth-last-child(#{$i}),
437
+ tbody tr td:nth-last-child(#{$i}) {
438
+ box-shadow: calc(-1 * var(--matcha-table-sticky-shadow-offset)) 0
439
+ var(--matcha-table-sticky-shadow-blur)
440
+ calc(-1 * var(--matcha-table-sticky-shadow-offset))
441
+ color-mix(in srgb, var(--matcha-table-sticky-shadow-color)
442
+ var(--matcha-table-sticky-shadow-alpha), transparent);
443
+ }
444
+ }
445
+ }
446
+
447
+ &[data-sticky-start] thead th:first-child,
448
+ &[data-sticky-start] tbody tr td:first-child { left: 0; }
449
+ &[data-sticky-end] thead th:last-child,
450
+ &[data-sticky-end] tbody tr td:last-child { right: 0; }
451
+
452
+ // ── Variant accent (semantic row coloring) ────────────────────────────
453
+ // Defaults canon Figma DSV3: equal=info, plus=success, minus=danger.
454
+ // Accent vive no <tr> → NÃO some com stickyStart.
455
+ // `position: relative` em <tr> suportado em Chrome 80+, FF 87+, Safari 14+.
456
+ tr.equal { --matcha-table-row-accent-color: var(--matcha-color-info); }
457
+ tr.plus { --matcha-table-row-accent-color: var(--matcha-color-success); }
458
+ tr.minus { --matcha-table-row-accent-color: var(--matcha-color-danger); }
459
+
460
+ tbody tr[data-variant],
461
+ tbody tr.equal,
462
+ tbody tr.plus,
463
+ tbody tr.minus {
464
+ position: relative;
465
+
466
+ &::before {
467
+ content: '';
468
+ position: absolute;
469
+ top: 0;
470
+ left: 0;
471
+ width: var(--matcha-table-variant-accent-width);
472
+ height: 100%;
473
+ background: var(--matcha-table-row-accent-color, transparent);
474
+ pointer-events: none;
475
+ z-index: 1; // acima do bg da cell, abaixo do sticky shadow
476
+ }
477
+ }
478
+
479
+ // Child row (indent + accent esmaecido) — pattern tree/hierarquia.
480
+ tbody tr.child-item::before {
481
+ opacity: var(--matcha-table-row-accent-child-opacity);
482
+ }
483
+ tbody tr.child-item td:first-child {
484
+ padding-left: calc(var(--matcha-table-cell-padding-x-left) +
485
+ var(--matcha-space-200, 16px));
486
+ }
487
+
488
+ // ── Loading state global — pulse + aria-busy ─────────────────────────
489
+ &.matcha-table-loading tbody tr {
490
+ animation: matcha-table-loading-pulse
491
+ var(--matcha-table-loading-pulse-duration)
492
+ ease-in-out infinite;
493
+ pointer-events: none;
494
+ }
495
+
496
+ // ── Disabled state — row/cell ─────────────────────────────────────────
497
+ // Pattern canon Material/Polaris. A11y: também aplicar aria-disabled.
498
+ tbody tr[disabled], tbody tr.is-disabled,
499
+ tbody td[disabled], tbody td.is-disabled {
500
+ opacity: var(--matcha-table-disabled-opacity);
501
+ pointer-events: none;
502
+ cursor: not-allowed;
503
+ }
504
+
505
+ // ── Per-row loading (matcha-table-loading directive) ─────────────────
506
+ // Pulse só naquela row — optimistic save/delete sem bloquear a tabela.
507
+ tbody tr.is-loading {
508
+ animation: matcha-table-loading-pulse
509
+ var(--matcha-table-loading-pulse-duration)
510
+ ease-in-out infinite;
511
+ pointer-events: none;
512
+ }
513
+
514
+ // ── Empty state row (matcha-table-empty directive) ────────────────────
515
+ // Container pra <matcha-empty-state>. Directive seta colspan automático.
516
+ tbody tr.is-empty td {
517
+ padding: var(--matcha-table-empty-padding-y) var(--matcha-table-empty-padding-x);
518
+ text-align: center;
519
+ background: var(--matcha-table-cell-bg);
520
+ }
521
+
522
+ // ── Resizable column (matcha-table-resizable directive) ───────────────
523
+ // Handle invisível na borda direita. Hover mostra cursor + barra discreta.
524
+ thead th.is-resizable {
525
+ position: relative;
526
+
527
+ &::before {
528
+ content: '';
529
+ position: absolute;
530
+ top: var(--matcha-table-resize-indicator-top);
531
+ right: 0;
532
+ width: var(--matcha-table-resize-indicator-width);
533
+ height: var(--matcha-table-resize-indicator-height);
534
+ background: var(--matcha-table-border-color);
535
+ opacity: 0;
536
+ transition: opacity var(--matcha-table-transition-duration) linear;
537
+ }
538
+ &:hover::before { opacity: 1; }
539
+ }
540
+ thead th.is-resizable::after {
541
+ // Override do ::after do sort-indicator: handle de resize ocupa a borda.
542
+ // Col sortable + resizable é raro — consumer escolhe uma.
543
+ content: '';
544
+ position: absolute;
545
+ top: 0;
546
+ right: calc(-1 * var(--matcha-table-resize-handle-width) / 2);
547
+ width: var(--matcha-table-resize-handle-width);
548
+ height: 100%;
549
+ cursor: col-resize;
550
+ z-index: 3;
551
+ background: transparent;
552
+ mask: none;
553
+ }
554
+ }
555
+
556
+ @keyframes matcha-table-loading-pulse {
557
+ 0%, 100% { opacity: 1; }
558
+ 50% { opacity: var(--matcha-table-loading-pulse-opacity-min); }
559
+ }
560
+
561
+ // ── Reduced motion ────────────────────────────────────────────────────
562
+ @media (prefers-reduced-motion: reduce) {
563
+ table.matcha-table tbody td,
564
+ table.matcha-table.matcha-table-loading tbody tr {
565
+ transition: none;
566
+ animation: none;
567
+ }
568
+ }
569
+ }