@inchurch/matcha-theme 22.3.0 → 22.4.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.
@@ -55,6 +55,9 @@
55
55
  --matcha-table-border-header: var(--matcha-border-thin, 2px);
56
56
  --matcha-table-border-row: var(--matcha-border-hairline, 1px);
57
57
  --matcha-table-bordered-radius: var(--matcha-radius-md, 4px);
58
+ // Escala de card (não a mesma de --matcha-table-bordered-radius, que é só
59
+ // pro inset border fino) — roundedTop arredonda o CONTAINER inteiro.
60
+ --matcha-table-rounded-top-radius: var(--matcha-radius-xl, 16px);
58
61
 
59
62
  // ── Surface colors ────────────────────────────────────────────────────
60
63
  --matcha-table-cell-bg: var(--matcha-color-surface-card);
@@ -113,12 +116,6 @@
113
116
  --matcha-table-resize-indicator-width: var(--matcha-border-hairline, 1px);
114
117
  --matcha-table-resize-indicator-height: 50%;
115
118
  --matcha-table-resize-indicator-top: 25%;
116
-
117
- // ── Sticky cols shadow ────────────────────────────────────────────────
118
- --matcha-table-sticky-shadow-offset: var(--matcha-space-100, 8px);
119
- --matcha-table-sticky-shadow-blur: var(--matcha-space-200, 16px);
120
- --matcha-table-sticky-shadow-color: var(--matcha-color-elevation-shadow, #000);
121
- --matcha-table-sticky-shadow-alpha: 16%;
122
119
  }
123
120
 
124
121
  // ── Base — display table nativo + typography via vars ─────────────────
@@ -351,28 +348,39 @@
351
348
  }
352
349
  }
353
350
 
354
- // ── Modifiers via host classes (Angular bind quando striped/hover/etc) ─
351
+ // ── Modifiers via atributo no host (Angular @HostBinding, ver
352
+ // table.component.ts) ──────────────────────────────────────────────────
353
+ // Cada modifier tem 2 seletores alternativos: `&[x]` (forma legado — o
354
+ // host JÁ É `.matcha-table`, self) e `matcha-table[x] &` (forma elemento
355
+ // — o atributo mora no host `<matcha-table>`, mas o alvo real é o filho
356
+ // `.matcha-table` dentro do wrapper; CSS alcança via descendente, não
357
+ // precisa o atributo estar duplicado no filho).
355
358
  // Striped usa :where() pra dropar specificity do :nth-child — hover vence.
356
- &.matcha-table-striped tbody tr:where(:nth-child(even)) td {
359
+ &[striped] tbody tr:where(:nth-child(even)) td,
360
+ matcha-table[striped] & tbody tr:where(:nth-child(even)) td {
357
361
  --matcha-table-cell-bg: var(--matcha-table-row-bg-striped);
358
362
  }
359
363
 
360
- &.matcha-table-hover tbody tr:hover td {
364
+ &[hover] tbody tr:hover td,
365
+ matcha-table[hover] & tbody tr:hover td {
361
366
  --matcha-table-cell-bg: var(--matcha-table-row-bg-hover);
362
367
  }
363
368
 
364
369
  // Stripe-aware hover: row PAR ganha alpha mais forte pra preservar stripe.
365
- &.matcha-table-striped tbody tr:where(:nth-child(even)).is-clickable:hover td,
366
- &.matcha-table-striped.matcha-table-hover tbody tr:where(:nth-child(even)):hover td {
370
+ &[striped] tbody tr:where(:nth-child(even)).is-clickable:hover td,
371
+ matcha-table[striped] & tbody tr:where(:nth-child(even)).is-clickable:hover td,
372
+ &[striped][hover] tbody tr:where(:nth-child(even)):hover td,
373
+ matcha-table[striped][hover] & tbody tr:where(:nth-child(even)):hover td {
367
374
  --matcha-table-cell-bg: var(--matcha-table-row-bg-hover-striped);
368
375
  }
369
376
 
370
- // Variante de hover accent (input `rowHover="accent"` → classe host
371
- // `matcha-table-hover-accent`). Rebinda a var de hover no PRÓPRIO `<table>`,
377
+ // Variante de hover accent (input `rowHover="accent"` → atributo host
378
+ // `data-row-hover="accent"`). Rebinda a var de hover no PRÓPRIO `<table>`,
372
379
  // com especificidade acima do default — dispensa o consumer de furar o
373
380
  // encapsulamento com `::ng-deep`. Substitui o override manual repetido em
374
381
  // members/visitors/history/datas-comemorativas.
375
- &.matcha-table-hover-accent {
382
+ &[data-row-hover="accent"],
383
+ matcha-table[data-row-hover="accent"] & {
376
384
  --matcha-table-row-bg-hover: var(--matcha-color-accent-surface-hover);
377
385
  --matcha-table-row-bg-hover-striped: var(--matcha-color-accent-surface-hover);
378
386
  }
@@ -401,7 +409,12 @@
401
409
 
402
410
  // Bordered — box-shadow inset em vez de border real (não clipa shadows
403
411
  // externos das sticky cols, que projetam pra fora da <table>).
404
- &.matcha-table-bordered {
412
+ // Conhecido: em alguns casos (sticky-header/colunas fixas, forma
413
+ // elemento) o background opaco das cells pode encobrir parte deste
414
+ // traço — não resolvido nesta rodada (fora do escopo desta tarefa); se
415
+ // precisar de borda garantida num caso desses, use a utility class de
416
+ // borda (ex.: `b-1`) direto no consumo do componente.
417
+ &[bordered] {
405
418
  box-shadow: inset 0 0 0 var(--matcha-table-border-row)
406
419
  var(--matcha-table-border-color);
407
420
  border-radius: var(--matcha-table-bordered-radius);
@@ -413,11 +426,13 @@
413
426
  // stickyHeader é opt-in EXPLÍCITO, reabilita overflow-y:auto de propósito
414
427
  // + altura máxima (sem isso não há o que rolar, o header não tem contra o
415
428
  // que grudar). Altura configurável via var (default 70vh).
416
- &.matcha-table-sticky-header {
429
+ &[sticky-header],
430
+ matcha-table[sticky-header] & {
417
431
  max-height: var(--matcha-table-sticky-header-max-height, 70vh);
418
432
  overflow-y: auto;
419
433
  }
420
- &.matcha-table-sticky-header thead th {
434
+ &[sticky-header] thead th,
435
+ matcha-table[sticky-header] & thead th {
421
436
  position: sticky;
422
437
  top: 0;
423
438
  z-index: 1;
@@ -430,64 +445,59 @@
430
445
  &[data-size="spacious"] tbody td { height: var(--matcha-table-cell-height-spacious); }
431
446
 
432
447
  // ── Sticky columns (start/end) — canon scroll horizontal ──────────────
433
- // Shadow scroll-edge via color-mix() pra tokenizar funciona em light
434
- // E dark. Offsets/blur/cor todos via var.
448
+ // Performance: nada de box-shadow com blur nem background-image (gradient)
449
+ // aqui são caros de repaint/compositar MULTIPLICADOS por linha (uma
450
+ // tabela de 40+ linhas com 2 colunas sticky = 80 elementos), e causavam
451
+ // queda de FPS real no scroll (medido em produção). Custo mínimo:
452
+ // background-color sólido (fixo, não acompanha hover/tint — troca-se
453
+ // fidelidade visual por performance) + border 1px sólida no lugar da
454
+ // sombra de scroll-edge (borda é essencialmente grátis pro compositor,
455
+ // sombra com blur não é).
435
456
  //
436
- // :not(.matcha-table-sticky-header) — combinar sticky column COM sticky
437
- // header exige que a cell de CANTO (cabeçalho da coluna fixa) fique sticky
438
- // nos dois eixos (top E left/right) ao mesmo tempo — inconsistente entre
439
- // browsers em cells de <table> (documentado no JSDoc do componente). Em vez
440
- // de deixar o canto quebrado (cabeçalho da coluna fixa não gruda, mostra
441
- // dado errado por trás), desliga a coluna fixa inteira quando stickyHeader
442
- // está ativo — só o header fixo (mais universalmente útil) permanece.
457
+ // :not([sticky-header])/:not(matcha-table[sticky-header] &) — combinar
458
+ // sticky column COM sticky header exige que a cell de CANTO (cabeçalho da
459
+ // coluna fixa) fique sticky nos dois eixos (top E left/right) ao mesmo
460
+ // tempo — inconsistente entre browsers em cells de <table> (documentado
461
+ // no JSDoc do componente). Em vez de deixar o canto quebrado, desliga a
462
+ // coluna fixa inteira quando stickyHeader está ativo o header fixo
463
+ // (mais universalmente útil) permanece. `sticky-header` agora é atributo
464
+ // no host — o 2º `:not()` cobre o caso em que o host é o wrapper (forma
465
+ // elemento, `sticky-header` não está no `.matcha-table` em si, está no
466
+ // `<matcha-table>` ancestral). `data-sticky-start`/`-end` continuam só no
467
+ // nó real (mirrorAttributesToRealTable), não precisam de alternativa.
443
468
  @for $i from 1 through 4 {
444
- &[data-sticky-start="#{$i}"]:not(.matcha-table-sticky-header) {
469
+ &[data-sticky-start="#{$i}"]:not([sticky-header]):not(matcha-table[sticky-header] &) {
445
470
  thead th:nth-child(-n+#{$i}),
446
471
  tbody tr td:nth-child(-n+#{$i}) {
447
472
  position: sticky;
448
473
  z-index: 2;
449
- // --matcha-table-cell-bg em hover/rowHover="accent"/striped é um TINT
450
- // translúcido (rgba ~12-18%) — correto pra cells normais (nada sólido
451
- // atrás), mas cells sticky têm conteúdo real rolando por baixo. Duas
452
- // camadas: background-color sempre opaco, background-image pinta o
453
- // tint (mesma var, já cascade certo) por cima.
454
474
  background-color: var(--matcha-color-surface-card);
455
- background-image: linear-gradient(var(--matcha-table-cell-bg), var(--matcha-table-cell-bg));
456
475
  }
457
- // Última cell do grupo sticky-start projeta shadow scroll-edge.
476
+ // Última cell do grupo sticky-start marca o scroll-edge com borda fina.
458
477
  thead th:nth-child(#{$i}),
459
478
  tbody tr td:nth-child(#{$i}) {
460
- box-shadow: var(--matcha-table-sticky-shadow-offset) 0
461
- var(--matcha-table-sticky-shadow-blur)
462
- calc(-1 * var(--matcha-table-sticky-shadow-offset))
463
- color-mix(in srgb, var(--matcha-table-sticky-shadow-color)
464
- var(--matcha-table-sticky-shadow-alpha), transparent);
479
+ border-right: var(--matcha-border-hairline, 1px) solid var(--matcha-color-surface-border);
465
480
  }
466
481
  }
467
482
 
468
- &[data-sticky-end="#{$i}"]:not(.matcha-table-sticky-header) {
483
+ &[data-sticky-end="#{$i}"]:not([sticky-header]):not(matcha-table[sticky-header] &) {
469
484
  thead th:nth-last-child(-n+#{$i}),
470
485
  tbody tr td:nth-last-child(-n+#{$i}) {
471
486
  position: sticky;
472
487
  z-index: 2;
473
488
  background-color: var(--matcha-color-surface-card);
474
- background-image: linear-gradient(var(--matcha-table-cell-bg), var(--matcha-table-cell-bg));
475
489
  }
476
490
  thead th:nth-last-child(#{$i}),
477
491
  tbody tr td:nth-last-child(#{$i}) {
478
- box-shadow: calc(-1 * var(--matcha-table-sticky-shadow-offset)) 0
479
- var(--matcha-table-sticky-shadow-blur)
480
- calc(-1 * var(--matcha-table-sticky-shadow-offset))
481
- color-mix(in srgb, var(--matcha-table-sticky-shadow-color)
482
- var(--matcha-table-sticky-shadow-alpha), transparent);
492
+ border-left: var(--matcha-border-hairline, 1px) solid var(--matcha-color-surface-border);
483
493
  }
484
494
  }
485
495
  }
486
496
 
487
- &[data-sticky-start]:not(.matcha-table-sticky-header) thead th:first-child,
488
- &[data-sticky-start]:not(.matcha-table-sticky-header) tbody tr td:first-child { left: 0; }
489
- &[data-sticky-end]:not(.matcha-table-sticky-header) thead th:last-child,
490
- &[data-sticky-end]:not(.matcha-table-sticky-header) tbody tr td:last-child { right: 0; }
497
+ &[data-sticky-start]:not([sticky-header]):not(matcha-table[sticky-header] &) thead th:first-child,
498
+ &[data-sticky-start]:not([sticky-header]):not(matcha-table[sticky-header] &) tbody tr td:first-child { left: 0; }
499
+ &[data-sticky-end]:not([sticky-header]):not(matcha-table[sticky-header] &) thead th:last-child,
500
+ &[data-sticky-end]:not([sticky-header]):not(matcha-table[sticky-header] &) tbody tr td:last-child { right: 0; }
491
501
 
492
502
  // ── Variant accent (semantic row coloring) ────────────────────────────
493
503
  // Defaults canon Figma DSV3: equal=info, plus=success, minus=danger.
@@ -526,7 +536,8 @@
526
536
  }
527
537
 
528
538
  // ── Loading state global — pulse + aria-busy ─────────────────────────
529
- &.matcha-table-loading tbody tr {
539
+ &[loading] tbody tr,
540
+ matcha-table[loading] & tbody tr {
530
541
  animation: matcha-table-loading-pulse
531
542
  var(--matcha-table-loading-pulse-duration)
532
543
  ease-in-out infinite;
@@ -596,13 +607,38 @@
596
607
  // Sticky header — forma ELEMENTO (`<matcha-table>`, ver table.component.ts).
597
608
  // Aqui quem rola de verdade é `.matcha-table__scroll` (o wrapper), não a
598
609
  // `<table class="matcha-table">` interna — a altura máxima precisa ir no
599
- // wrapper. `:has()` alcança o pai a partir da tabela filha (já usado no
600
- // showcase ver page-matcha-table.component.scss).
601
- .matcha-table__scroll:has(> table.matcha-table-sticky-header) {
610
+ // wrapper. `sticky-header` mora no HOST `<matcha-table>` (@HostBinding,
611
+ // não mais na `<table>` filha) — como o host é ANCESTRAL do wrapper, um
612
+ // descendente simples já alcança, sem precisar de `:has()`.
613
+ matcha-table[sticky-header] > .matcha-table__scroll {
602
614
  max-height: var(--matcha-table-sticky-header-max-height, 70vh);
603
615
  overflow-y: auto;
604
616
  }
605
617
 
618
+ // roundedTop — regra TOP-LEVEL (fora do bloco .matcha-table acima): alcança
619
+ // o host na forma legado (self, `.matcha-table[rounded-top]`, o próprio
620
+ // `<table>` é a superfície visual) e o wrapper de scroll na forma elemento
621
+ // (descendente a partir do host `<matcha-table rounded-top>` — só o
622
+ // wrapper precisa do radius, ele já clipa a `<table>` interna via
623
+ // overflow non-visible, a `<table>` em si não precisa do próprio radius).
624
+ //
625
+ // Fallback inline no 2º var() é OBRIGATÓRIO: --matcha-table-rounded-top-radius
626
+ // é declarada dentro do bloco `.matcha-table { }` acima — na forma elemento
627
+ // `.matcha-table__scroll` é PAI de `.matcha-table` (o wrapper envolve a
628
+ // table real), não descendente. CSS custom property só desce a árvore, não
629
+ // sobe — sem o fallback aqui a var nunca resolve nesse elemento (bug
630
+ // silencioso: sem erro, só o border-radius nunca aparece). O fallback ainda
631
+ // respeita um override do consumer, se ele setar a var em algum ancestral
632
+ // real do wrapper (ex.: no próprio host `<matcha-table>` ou em `:root`).
633
+ .matcha-table[rounded-top] {
634
+ border-top-left-radius: var(--matcha-table-rounded-top-radius);
635
+ border-top-right-radius: var(--matcha-table-rounded-top-radius);
636
+ }
637
+ matcha-table[rounded-top] .matcha-table__scroll {
638
+ border-top-left-radius: var(--matcha-table-rounded-top-radius, var(--matcha-radius-xl, 16px));
639
+ border-top-right-radius: var(--matcha-table-rounded-top-radius, var(--matcha-radius-xl, 16px));
640
+ }
641
+
606
642
  @keyframes matcha-table-loading-pulse {
607
643
  0%, 100% { opacity: 1; }
608
644
  50% { opacity: var(--matcha-table-loading-pulse-opacity-min); }
@@ -611,7 +647,8 @@
611
647
  // ── Reduced motion ────────────────────────────────────────────────────
612
648
  @media (prefers-reduced-motion: reduce) {
613
649
  .matcha-table tbody td,
614
- .matcha-table.matcha-table-loading tbody tr {
650
+ .matcha-table[loading] tbody tr,
651
+ matcha-table[loading] .matcha-table tbody tr {
615
652
  transition: none;
616
653
  animation: none;
617
654
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inchurch/matcha-theme",
3
- "version": "22.3.0",
3
+ "version": "22.4.0",
4
4
  "description": "Themes for matcha-design-system",
5
5
  "main": "main.scss",
6
6
  "scripts": {