rl-core-front 0.18.6 → 0.18.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rl-core-front",
3
- "version": "0.18.6",
3
+ "version": "0.18.7",
4
4
  "description": "Telas e componentes Next.js do core: login com 2FA, usuários, RBAC, auditoria, logs e listagens com filtro dinâmico",
5
5
  "author": "Rodrigo Liberti",
6
6
  "license": "MIT",
@@ -34,6 +34,7 @@ import {
34
34
  import type {
35
35
  CSSProperties,
36
36
  JSX,
37
+ MouseEvent as ReactMouseEvent,
37
38
  PointerEvent as ReactPointerEvent,
38
39
  } from "react";
39
40
  import { Fragment, useEffect, useMemo, useRef, useState } from "react";
@@ -468,9 +469,40 @@ const CELL_MAX_WIDTH = "24rem";
468
469
  * cortaria botão de ação. A que declara `wrap` também: nela a quebra é o
469
470
  * desenho.
470
471
  */
471
- function cellStyle(columnDef: {
472
- meta?: unknown;
473
- }): { className?: string; style?: CSSProperties } {
472
+ /** A célula (ou o que ela tem dentro) não coube e está cortada. */
473
+ function isClipped(cell: HTMLElement): boolean {
474
+ if (cell.scrollWidth > cell.clientWidth) {
475
+ return true;
476
+ }
477
+
478
+ return Array.from(cell.children).some(
479
+ (child) => child.scrollWidth > child.clientWidth,
480
+ );
481
+ }
482
+
483
+ /**
484
+ * Abre a célula sob o cursor — se houver o que abrir.
485
+ *
486
+ * A medição acontece aqui, e não em cada render: enquanto ninguém passa o
487
+ * mouse, isto não custa nada. E mexer na `dataset` em vez de subir estado
488
+ * evita re-renderizar a tabela inteira a cada célula que o ponteiro cruza.
489
+ */
490
+ function expandIfClipped(event: ReactMouseEvent<HTMLTableCellElement>): void {
491
+ if (isClipped(event.currentTarget)) {
492
+ event.currentTarget.dataset.expand = "true";
493
+ }
494
+ }
495
+
496
+ function collapse(event: ReactMouseEvent<HTMLTableCellElement>): void {
497
+ delete event.currentTarget.dataset.expand;
498
+ }
499
+
500
+ function cellStyle(columnDef: { meta?: unknown }): {
501
+ className?: string;
502
+ style?: CSSProperties;
503
+ onMouseEnter?: (event: ReactMouseEvent<HTMLTableCellElement>) => void;
504
+ onMouseLeave?: (event: ReactMouseEvent<HTMLTableCellElement>) => void;
505
+ } {
474
506
  const meta = columnDef.meta as DataTableColumnMeta | undefined;
475
507
 
476
508
  if (meta?.shrink || meta?.wrap) {
@@ -487,16 +519,24 @@ function cellStyle(columnDef: {
487
519
  aparecem nos dois casos.
488
520
  */
489
521
  /*
490
- E o mouse em cima devolve o texto inteiro: no hovero `white-space`
491
- muda, a frase volta a quebrar e a célula cresce em altura. É o mesmo gesto
492
- das descrições do Financeiro — sem `title`, que só aparece depois de um
493
- segundo parado, e sem tooltip flutuante, que sairia da tabela e taparia a
494
- linha de baixo.
522
+ E o mouse em cima devolve o texto inteiro mas **na célula que está de
523
+ fato cortada**.
524
+
525
+ Com `hover:` puro, passar o mouse por uma célula que cabia inteira a
526
+ fazia quebrar em duas linhas do mesmo jeito, e a linha inteira pulava sob o
527
+ cursor. CSS não sabe se houve corte; quem sabe é o layout já calculado, daí
528
+ a medição no `mouseenter` — que não custa render nenhum enquanto ninguém
529
+ passa o mouse. O `data-expand` liga as duas regras abaixo.
530
+
531
+ Sem `title`, que só aparece depois de um segundo parado, e sem tooltip
532
+ flutuante, que sairia da tabela e taparia a linha de baixo.
495
533
  */
496
534
  return {
497
535
  className:
498
- "truncate hover:whitespace-normal [&>*]:truncate hover:[&>*]:whitespace-normal",
536
+ "truncate [&>*]:truncate data-[expand=true]:whitespace-normal data-[expand=true]:[&>*]:whitespace-normal",
499
537
  style: { maxWidth: meta?.maxWidth ?? CELL_MAX_WIDTH },
538
+ onMouseEnter: expandIfClipped,
539
+ onMouseLeave: collapse,
500
540
  };
501
541
  }
502
542