@lucasbernardosn/react-table 0.0.0-stage → 0.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/LICENSE +21 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/components/column-menu/column-menu-check.d.ts +8 -0
- package/dist/components/column-menu/column-menu-check.d.ts.map +1 -0
- package/dist/components/column-menu/column-menu-check.js +17 -0
- package/dist/components/column-menu/column-menu-check.js.map +1 -0
- package/dist/components/column-menu/column-menu-hide-item.d.ts +23 -0
- package/dist/components/column-menu/column-menu-hide-item.d.ts.map +1 -0
- package/dist/components/column-menu/column-menu-hide-item.js +28 -0
- package/dist/components/column-menu/column-menu-hide-item.js.map +1 -0
- package/dist/components/column-menu/column-menu-labels.d.ts +21 -0
- package/dist/components/column-menu/column-menu-labels.d.ts.map +1 -0
- package/dist/components/column-menu/column-menu-labels.js +14 -0
- package/dist/components/column-menu/column-menu-labels.js.map +1 -0
- package/dist/components/column-menu/column-menu-pin-items.d.ts +25 -0
- package/dist/components/column-menu/column-menu-pin-items.d.ts.map +1 -0
- package/dist/components/column-menu/column-menu-pin-items.js +65 -0
- package/dist/components/column-menu/column-menu-pin-items.js.map +1 -0
- package/dist/components/column-menu/column-menu-popup.d.ts +39 -0
- package/dist/components/column-menu/column-menu-popup.d.ts.map +1 -0
- package/dist/components/column-menu/column-menu-popup.js +66 -0
- package/dist/components/column-menu/column-menu-popup.js.map +1 -0
- package/dist/components/column-menu/column-menu-root.d.ts +34 -0
- package/dist/components/column-menu/column-menu-root.d.ts.map +1 -0
- package/dist/components/column-menu/column-menu-root.js +36 -0
- package/dist/components/column-menu/column-menu-root.js.map +1 -0
- package/dist/components/column-menu/column-menu-sort-items.d.ts +29 -0
- package/dist/components/column-menu/column-menu-sort-items.d.ts.map +1 -0
- package/dist/components/column-menu/column-menu-sort-items.js +61 -0
- package/dist/components/column-menu/column-menu-sort-items.js.map +1 -0
- package/dist/components/column-menu/column-menu-trigger.d.ts +23 -0
- package/dist/components/column-menu/column-menu-trigger.d.ts.map +1 -0
- package/dist/components/column-menu/column-menu-trigger.js +38 -0
- package/dist/components/column-menu/column-menu-trigger.js.map +1 -0
- package/dist/components/column-menu/index.d.ts +2 -0
- package/dist/components/column-menu/index.js +2 -0
- package/dist/components/column-menu/index.parts.d.ts +13 -0
- package/dist/components/column-menu/index.parts.d.ts.map +1 -0
- package/dist/components/column-menu/index.parts.js +20 -0
- package/dist/components/column-menu/index.parts.js.map +1 -0
- package/dist/components/columns-panel/columns-panel-item.d.ts +31 -0
- package/dist/components/columns-panel/columns-panel-item.d.ts.map +1 -0
- package/dist/components/columns-panel/columns-panel-item.js +92 -0
- package/dist/components/columns-panel/columns-panel-item.js.map +1 -0
- package/dist/components/columns-panel/columns-panel-root.d.ts +51 -0
- package/dist/components/columns-panel/columns-panel-root.d.ts.map +1 -0
- package/dist/components/columns-panel/columns-panel-root.js +134 -0
- package/dist/components/columns-panel/columns-panel-root.js.map +1 -0
- package/dist/components/columns-panel/get-columns-panel-column-order.d.ts +16 -0
- package/dist/components/columns-panel/get-columns-panel-column-order.d.ts.map +1 -0
- package/dist/components/columns-panel/get-columns-panel-column-order.js +24 -0
- package/dist/components/columns-panel/get-columns-panel-column-order.js.map +1 -0
- package/dist/components/columns-panel/index.d.ts +2 -0
- package/dist/components/columns-panel/index.js +2 -0
- package/dist/components/columns-panel/index.parts.d.ts +8 -0
- package/dist/components/columns-panel/index.parts.d.ts.map +1 -0
- package/dist/components/columns-panel/index.parts.js +12 -0
- package/dist/components/columns-panel/index.parts.js.map +1 -0
- package/dist/components/data-table/body/data-table-body.d.ts +58 -0
- package/dist/components/data-table/body/data-table-body.d.ts.map +1 -0
- package/dist/components/data-table/body/data-table-body.js +99 -0
- package/dist/components/data-table/body/data-table-body.js.map +1 -0
- package/dist/components/data-table/body/data-table-cell.d.ts +26 -0
- package/dist/components/data-table/body/data-table-cell.d.ts.map +1 -0
- package/dist/components/data-table/body/data-table-cell.js +80 -0
- package/dist/components/data-table/body/data-table-cell.js.map +1 -0
- package/dist/components/data-table/body/data-table-empty.d.ts +38 -0
- package/dist/components/data-table/body/data-table-empty.d.ts.map +1 -0
- package/dist/components/data-table/body/data-table-empty.js +71 -0
- package/dist/components/data-table/body/data-table-empty.js.map +1 -0
- package/dist/components/data-table/body/data-table-row-focus.d.ts +32 -0
- package/dist/components/data-table/body/data-table-row-focus.d.ts.map +1 -0
- package/dist/components/data-table/body/data-table-row-focus.js +58 -0
- package/dist/components/data-table/body/data-table-row-focus.js.map +1 -0
- package/dist/components/data-table/body/data-table-row.d.ts +67 -0
- package/dist/components/data-table/body/data-table-row.d.ts.map +1 -0
- package/dist/components/data-table/body/data-table-row.js +150 -0
- package/dist/components/data-table/body/data-table-row.js.map +1 -0
- package/dist/components/data-table/body/use-data-table-row-focus-recovery.d.ts +19 -0
- package/dist/components/data-table/body/use-data-table-row-focus-recovery.d.ts.map +1 -0
- package/dist/components/data-table/body/use-data-table-row-focus-recovery.js +64 -0
- package/dist/components/data-table/body/use-data-table-row-focus-recovery.js.map +1 -0
- package/dist/components/data-table/header/data-table-header-button.d.ts +25 -0
- package/dist/components/data-table/header/data-table-header-button.d.ts.map +1 -0
- package/dist/components/data-table/header/data-table-header-button.js +57 -0
- package/dist/components/data-table/header/data-table-header-button.js.map +1 -0
- package/dist/components/data-table/header/data-table-header-cell.d.ts +34 -0
- package/dist/components/data-table/header/data-table-header-cell.d.ts.map +1 -0
- package/dist/components/data-table/header/data-table-header-cell.js +97 -0
- package/dist/components/data-table/header/data-table-header-cell.js.map +1 -0
- package/dist/components/data-table/header/data-table-header-content.d.ts +21 -0
- package/dist/components/data-table/header/data-table-header-content.d.ts.map +1 -0
- package/dist/components/data-table/header/data-table-header-content.js +37 -0
- package/dist/components/data-table/header/data-table-header-content.js.map +1 -0
- package/dist/components/data-table/header/data-table-header-row.d.ts +15 -0
- package/dist/components/data-table/header/data-table-header-row.d.ts.map +1 -0
- package/dist/components/data-table/header/data-table-header-row.js +28 -0
- package/dist/components/data-table/header/data-table-header-row.js.map +1 -0
- package/dist/components/data-table/header/data-table-header.d.ts +46 -0
- package/dist/components/data-table/header/data-table-header.d.ts.map +1 -0
- package/dist/components/data-table/header/data-table-header.js +80 -0
- package/dist/components/data-table/header/data-table-header.js.map +1 -0
- package/dist/components/data-table/index.d.ts +2 -0
- package/dist/components/data-table/index.js +2 -0
- package/dist/components/data-table/index.parts.d.ts +32 -0
- package/dist/components/data-table/index.parts.d.ts.map +1 -0
- package/dist/components/data-table/index.parts.js +60 -0
- package/dist/components/data-table/index.parts.js.map +1 -0
- package/dist/components/data-table/loading/get-data-table-loading-without-rows.d.ts +16 -0
- package/dist/components/data-table/loading/get-data-table-loading-without-rows.d.ts.map +1 -0
- package/dist/components/data-table/loading/get-data-table-loading-without-rows.js +18 -0
- package/dist/components/data-table/loading/get-data-table-loading-without-rows.js.map +1 -0
- package/dist/components/data-table/loading/use-data-table-loading-inert.d.ts +16 -0
- package/dist/components/data-table/loading/use-data-table-loading-inert.d.ts.map +1 -0
- package/dist/components/data-table/loading/use-data-table-loading-inert.js +54 -0
- package/dist/components/data-table/loading/use-data-table-loading-inert.js.map +1 -0
- package/dist/components/data-table/loading/use-data-table-loading.d.ts +13 -0
- package/dist/components/data-table/loading/use-data-table-loading.d.ts.map +1 -0
- package/dist/components/data-table/loading/use-data-table-loading.js +40 -0
- package/dist/components/data-table/loading/use-data-table-loading.js.map +1 -0
- package/dist/components/data-table/pagination/data-table-page-button.d.ts +45 -0
- package/dist/components/data-table/pagination/data-table-page-button.d.ts.map +1 -0
- package/dist/components/data-table/pagination/data-table-page-button.js +67 -0
- package/dist/components/data-table/pagination/data-table-page-button.js.map +1 -0
- package/dist/components/data-table/pagination/data-table-page-size-select.d.ts +47 -0
- package/dist/components/data-table/pagination/data-table-page-size-select.d.ts.map +1 -0
- package/dist/components/data-table/pagination/data-table-page-size-select.js +68 -0
- package/dist/components/data-table/pagination/data-table-page-size-select.js.map +1 -0
- package/dist/components/data-table/pagination/data-table-page-status.d.ts +43 -0
- package/dist/components/data-table/pagination/data-table-page-status.d.ts.map +1 -0
- package/dist/components/data-table/pagination/data-table-page-status.js +48 -0
- package/dist/components/data-table/pagination/data-table-page-status.js.map +1 -0
- package/dist/components/data-table/pagination/data-table-pagination.d.ts +38 -0
- package/dist/components/data-table/pagination/data-table-pagination.d.ts.map +1 -0
- package/dist/components/data-table/pagination/data-table-pagination.js +87 -0
- package/dist/components/data-table/pagination/data-table-pagination.js.map +1 -0
- package/dist/components/data-table/pagination/data-table-row-range.d.ts +49 -0
- package/dist/components/data-table/pagination/data-table-row-range.d.ts.map +1 -0
- package/dist/components/data-table/pagination/data-table-row-range.js +63 -0
- package/dist/components/data-table/pagination/data-table-row-range.js.map +1 -0
- package/dist/components/data-table/pagination/data-table-selected-count.d.ts +37 -0
- package/dist/components/data-table/pagination/data-table-selected-count.d.ts.map +1 -0
- package/dist/components/data-table/pagination/data-table-selected-count.js +44 -0
- package/dist/components/data-table/pagination/data-table-selected-count.js.map +1 -0
- package/dist/components/data-table/pagination/use-data-table-page-scroll-reset.d.ts +15 -0
- package/dist/components/data-table/pagination/use-data-table-page-scroll-reset.d.ts.map +1 -0
- package/dist/components/data-table/pagination/use-data-table-page-scroll-reset.js +38 -0
- package/dist/components/data-table/pagination/use-data-table-page-scroll-reset.js.map +1 -0
- package/dist/components/data-table/resize/data-table-resize-handle.d.ts +48 -0
- package/dist/components/data-table/resize/data-table-resize-handle.d.ts.map +1 -0
- package/dist/components/data-table/resize/data-table-resize-handle.js +115 -0
- package/dist/components/data-table/resize/data-table-resize-handle.js.map +1 -0
- package/dist/components/data-table/resize/use-data-table-resize-scroll.d.ts +18 -0
- package/dist/components/data-table/resize/use-data-table-resize-scroll.d.ts.map +1 -0
- package/dist/components/data-table/resize/use-data-table-resize-scroll.js +55 -0
- package/dist/components/data-table/resize/use-data-table-resize-scroll.js.map +1 -0
- package/dist/components/data-table/root/data-table-grid-classes.d.ts +10 -0
- package/dist/components/data-table/root/data-table-grid-classes.d.ts.map +1 -0
- package/dist/components/data-table/root/data-table-grid-classes.js +22 -0
- package/dist/components/data-table/root/data-table-grid-classes.js.map +1 -0
- package/dist/components/data-table/root/data-table-root.d.ts +41 -0
- package/dist/components/data-table/root/data-table-root.d.ts.map +1 -0
- package/dist/components/data-table/root/data-table-root.js +72 -0
- package/dist/components/data-table/root/data-table-root.js.map +1 -0
- package/dist/components/data-table/root/data-table-scroll-area.d.ts +21 -0
- package/dist/components/data-table/root/data-table-scroll-area.d.ts.map +1 -0
- package/dist/components/data-table/root/data-table-scroll-area.js +127 -0
- package/dist/components/data-table/root/data-table-scroll-area.js.map +1 -0
- package/dist/components/data-table/root/get-data-table-column-layout.d.ts +45 -0
- package/dist/components/data-table/root/get-data-table-column-layout.d.ts.map +1 -0
- package/dist/components/data-table/root/get-data-table-column-layout.js +55 -0
- package/dist/components/data-table/root/get-data-table-column-layout.js.map +1 -0
- package/dist/components/data-table/root/get-data-table-column-pinning.d.ts +46 -0
- package/dist/components/data-table/root/get-data-table-column-pinning.d.ts.map +1 -0
- package/dist/components/data-table/root/get-data-table-column-pinning.js +46 -0
- package/dist/components/data-table/root/get-data-table-column-pinning.js.map +1 -0
- package/dist/components/data-table/root/get-data-table-scroll-parent.d.ts +13 -0
- package/dist/components/data-table/root/get-data-table-scroll-parent.d.ts.map +1 -0
- package/dist/components/data-table/root/get-data-table-scroll-parent.js +20 -0
- package/dist/components/data-table/root/get-data-table-scroll-parent.js.map +1 -0
- package/dist/components/data-table/root/use-data-table-column-layout.d.ts +25 -0
- package/dist/components/data-table/root/use-data-table-column-layout.d.ts.map +1 -0
- package/dist/components/data-table/root/use-data-table-column-layout.js +106 -0
- package/dist/components/data-table/root/use-data-table-column-layout.js.map +1 -0
- package/dist/components/data-table/root/use-data-table-header-offset.d.ts +15 -0
- package/dist/components/data-table/root/use-data-table-header-offset.d.ts.map +1 -0
- package/dist/components/data-table/root/use-data-table-header-offset.js +35 -0
- package/dist/components/data-table/root/use-data-table-header-offset.js.map +1 -0
- package/dist/components/data-table/selection/data-table-row-checkbox.d.ts +33 -0
- package/dist/components/data-table/selection/data-table-row-checkbox.d.ts.map +1 -0
- package/dist/components/data-table/selection/data-table-row-checkbox.js +50 -0
- package/dist/components/data-table/selection/data-table-row-checkbox.js.map +1 -0
- package/dist/components/data-table/selection/data-table-select-all-checkbox.d.ts +31 -0
- package/dist/components/data-table/selection/data-table-select-all-checkbox.d.ts.map +1 -0
- package/dist/components/data-table/selection/data-table-select-all-checkbox.js +44 -0
- package/dist/components/data-table/selection/data-table-select-all-checkbox.js.map +1 -0
- package/dist/components/data-table/selection/selection-column-def.d.ts +54 -0
- package/dist/components/data-table/selection/selection-column-def.d.ts.map +1 -0
- package/dist/components/data-table/selection/selection-column-def.js +55 -0
- package/dist/components/data-table/selection/selection-column-def.js.map +1 -0
- package/dist/components/data-table/sorting/data-table-sort-indicator.d.ts +26 -0
- package/dist/components/data-table/sorting/data-table-sort-indicator.d.ts.map +1 -0
- package/dist/components/data-table/sorting/data-table-sort-indicator.js +64 -0
- package/dist/components/data-table/sorting/data-table-sort-indicator.js.map +1 -0
- package/dist/components/data-table/sorting/data-table-sort-trigger.d.ts +31 -0
- package/dist/components/data-table/sorting/data-table-sort-trigger.d.ts.map +1 -0
- package/dist/components/data-table/sorting/data-table-sort-trigger.js +46 -0
- package/dist/components/data-table/sorting/data-table-sort-trigger.js.map +1 -0
- package/dist/components/data-table/toolbar/data-table-density-select.d.ts +39 -0
- package/dist/components/data-table/toolbar/data-table-density-select.d.ts.map +1 -0
- package/dist/components/data-table/toolbar/data-table-density-select.js +60 -0
- package/dist/components/data-table/toolbar/data-table-density-select.js.map +1 -0
- package/dist/components/data-table/toolbar/data-table-sort-column-select.d.ts +47 -0
- package/dist/components/data-table/toolbar/data-table-sort-column-select.d.ts.map +1 -0
- package/dist/components/data-table/toolbar/data-table-sort-column-select.js +78 -0
- package/dist/components/data-table/toolbar/data-table-sort-column-select.js.map +1 -0
- package/dist/components/data-table/toolbar/data-table-sort-direction-select.d.ts +40 -0
- package/dist/components/data-table/toolbar/data-table-sort-direction-select.d.ts.map +1 -0
- package/dist/components/data-table/toolbar/data-table-sort-direction-select.js +66 -0
- package/dist/components/data-table/toolbar/data-table-sort-direction-select.js.map +1 -0
- package/dist/features/active-row/active-row-feature.d.ts +22 -0
- package/dist/features/active-row/active-row-feature.d.ts.map +1 -0
- package/dist/features/active-row/active-row-feature.js +55 -0
- package/dist/features/active-row/active-row-feature.js.map +1 -0
- package/dist/features/active-row/active-row-feature.types.d.ts +64 -0
- package/dist/features/active-row/active-row-feature.types.d.ts.map +1 -0
- package/dist/features/active-row/active-row-feature.types.js +0 -0
- package/dist/features/column-alignment/column-alignment-feature.d.ts +23 -0
- package/dist/features/column-alignment/column-alignment-feature.d.ts.map +1 -0
- package/dist/features/column-alignment/column-alignment-feature.js +34 -0
- package/dist/features/column-alignment/column-alignment-feature.js.map +1 -0
- package/dist/features/column-alignment/column-alignment-feature.types.d.ts +34 -0
- package/dist/features/column-alignment/column-alignment-feature.types.d.ts.map +1 -0
- package/dist/features/column-alignment/column-alignment-feature.types.js +0 -0
- package/dist/features/index.d.ts +9 -0
- package/dist/features/index.js +5 -0
- package/dist/features/loading/loading-feature.d.ts +30 -0
- package/dist/features/loading/loading-feature.d.ts.map +1 -0
- package/dist/features/loading/loading-feature.js +48 -0
- package/dist/features/loading/loading-feature.js.map +1 -0
- package/dist/features/loading/loading-feature.types.d.ts +50 -0
- package/dist/features/loading/loading-feature.types.d.ts.map +1 -0
- package/dist/features/loading/loading-feature.types.js +0 -0
- package/dist/features/row-density/row-density-feature.d.ts +26 -0
- package/dist/features/row-density/row-density-feature.d.ts.map +1 -0
- package/dist/features/row-density/row-density-feature.js +44 -0
- package/dist/features/row-density/row-density-feature.js.map +1 -0
- package/dist/features/row-density/row-density-feature.types.d.ts +53 -0
- package/dist/features/row-density/row-density-feature.types.d.ts.map +1 -0
- package/dist/features/row-density/row-density-feature.types.js +0 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +0 -0
- package/dist/types/table-with.d.ts +96 -0
- package/dist/types/table-with.d.ts.map +1 -0
- package/dist/types/table-with.js +0 -0
- package/dist/utils/get-default-column-label.d.ts +17 -0
- package/dist/utils/get-default-column-label.d.ts.map +1 -0
- package/dist/utils/get-default-column-label.js +18 -0
- package/dist/utils/get-default-column-label.js.map +1 -0
- package/dist/utils/has-feature.d.ts +54 -0
- package/dist/utils/has-feature.d.ts.map +1 -0
- package/dist/utils/has-feature.js +55 -0
- package/dist/utils/has-feature.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/package.json +80 -3
- package/README.md +0 -3
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { useDataTableHeaderOffset } from "./use-data-table-header-offset.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { mergeStateClassNames, mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
|
|
4
|
+
import { useMemo } from "react";
|
|
5
|
+
import { ScrollArea } from "@lucasbernardosn/react-ui/layout/scroll-area";
|
|
6
|
+
import { mergeRefs } from "@lucasbernardosn/react-utils";
|
|
7
|
+
//#region src/components/data-table/root/data-table-scroll-area.tsx
|
|
8
|
+
/**
|
|
9
|
+
* A área de rolagem da tabela, montada com o `ScrollArea` da lib: `Root`, uma moldura com a
|
|
10
|
+
* borda, `Viewport`, `Content` e as barras. Os filhos vão no `Content`, e as props no `Root`.
|
|
11
|
+
*
|
|
12
|
+
* O viewport é o ancestral que rola, e é nele que o cabeçalho sticky se ancora. Na largura,
|
|
13
|
+
* abraça o grid e para no pai. Na altura, tem a das linhas: dentro de um pai com altura
|
|
14
|
+
* limitada, encolhe e as linhas rolam por dentro; sem limite, cresce e só rola na horizontal.
|
|
15
|
+
*
|
|
16
|
+
* As barras ficam numa faixa fora da moldura, só no eixo que transborda: não passam por cima das
|
|
17
|
+
* linhas, da seleção nem das colunas fixadas. A vertical começa abaixo do `DataTable.Header`,
|
|
18
|
+
* cuja altura é medida aqui.
|
|
19
|
+
*/
|
|
20
|
+
const DataTableScrollArea = (props) => {
|
|
21
|
+
const { className, children, ref, ...rest } = props;
|
|
22
|
+
const headerOffsetRef = useDataTableHeaderOffset();
|
|
23
|
+
/**
|
|
24
|
+
* O ref de quem usa e o da medida do cabeçalho, no mesmo elemento. Memoizado: um callback novo
|
|
25
|
+
* a cada render desligaria e religaria o observer.
|
|
26
|
+
*/
|
|
27
|
+
const rootRef = useMemo(() => mergeRefs(headerOffsetRef, ref), [headerOffsetRef, ref]);
|
|
28
|
+
return /* @__PURE__ */ jsxs(ScrollArea.Root, {
|
|
29
|
+
ref: rootRef,
|
|
30
|
+
"data-component": "DataTable.ScrollArea",
|
|
31
|
+
className: mergeStateClassNames([
|
|
32
|
+
"w-max",
|
|
33
|
+
"max-w-full",
|
|
34
|
+
"[--scroll-area-scrollbar-size:--spacing(3)]",
|
|
35
|
+
"[--scroll-area-scrollbar-inset:0px]",
|
|
36
|
+
"[--scroll-area-thumb-size:--spacing(1)]",
|
|
37
|
+
"pointer-fine:[--scroll-area-thumb-size:--spacing(1.5)]",
|
|
38
|
+
"data-has-overflow-y:pe-(--scroll-area-scrollbar-size)",
|
|
39
|
+
"data-has-overflow-x:pb-(--scroll-area-scrollbar-size)"
|
|
40
|
+
], className),
|
|
41
|
+
...rest,
|
|
42
|
+
children: [
|
|
43
|
+
/* @__PURE__ */ jsxs("div", {
|
|
44
|
+
className: mergeTwClassNames([
|
|
45
|
+
"h-full",
|
|
46
|
+
"relative",
|
|
47
|
+
"group/data-table-frame",
|
|
48
|
+
"overflow-clip",
|
|
49
|
+
"rounded-md",
|
|
50
|
+
"corner-squircle",
|
|
51
|
+
"border",
|
|
52
|
+
"border-gray-6",
|
|
53
|
+
"focus-ring-inside",
|
|
54
|
+
"[--focus-ring-offset:-1px]",
|
|
55
|
+
"ring-gray-12"
|
|
56
|
+
]),
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ jsx(ScrollArea.Viewport, {
|
|
59
|
+
focusRing: true,
|
|
60
|
+
className: "overscroll-x-contain scroll-pt-(--data-table-header-offset)",
|
|
61
|
+
children: /* @__PURE__ */ jsx(ScrollArea.Content, { children })
|
|
62
|
+
}),
|
|
63
|
+
/* @__PURE__ */ jsx("div", {
|
|
64
|
+
"aria-hidden": true,
|
|
65
|
+
"data-component": "DataTable.LoadingBar",
|
|
66
|
+
className: mergeTwClassNames([
|
|
67
|
+
"hidden",
|
|
68
|
+
"group-has-[[data-component='DataTable.Root'][data-loading]]/data-table-frame:block",
|
|
69
|
+
"pointer-events-none",
|
|
70
|
+
"absolute",
|
|
71
|
+
"inset-x-0",
|
|
72
|
+
"top-[calc(var(--data-table-header-offset,0px)-1px)]",
|
|
73
|
+
"z-30",
|
|
74
|
+
"h-0.5",
|
|
75
|
+
"overflow-hidden",
|
|
76
|
+
"before:content-['']",
|
|
77
|
+
"before:absolute",
|
|
78
|
+
"before:inset-y-0",
|
|
79
|
+
"before:w-2/5",
|
|
80
|
+
"before:rounded-full",
|
|
81
|
+
"before:bg-gray-11",
|
|
82
|
+
"not-motion-reduced:before:animate-progress-indeterminate",
|
|
83
|
+
"motion-reduced:before:w-full",
|
|
84
|
+
"motion-reduced:before:bg-gray-8"
|
|
85
|
+
])
|
|
86
|
+
}),
|
|
87
|
+
/* @__PURE__ */ jsx("div", {
|
|
88
|
+
"aria-hidden": true,
|
|
89
|
+
"data-component": "DataTable.ResizeGuide",
|
|
90
|
+
className: mergeTwClassNames([
|
|
91
|
+
"hidden",
|
|
92
|
+
"group-has-[[data-component='DataTable.ResizeHandle']:hover]/data-table-frame:block",
|
|
93
|
+
"group-has-[[data-component='DataTable.ResizeHandle'][data-resizing]]/data-table-frame:block",
|
|
94
|
+
"not-supports-[anchor-name:--a]:hidden!",
|
|
95
|
+
"pointer-events-none",
|
|
96
|
+
"absolute",
|
|
97
|
+
"inset-y-0",
|
|
98
|
+
"z-30",
|
|
99
|
+
"w-0.5",
|
|
100
|
+
"left-[anchor(left)]",
|
|
101
|
+
"-translate-x-1/2",
|
|
102
|
+
"[position-anchor:--data-table-resize-handle]",
|
|
103
|
+
"bg-gray-9",
|
|
104
|
+
"group-has-[[data-component='DataTable.ResizeHandle'][data-resizing]]/data-table-frame:bg-black",
|
|
105
|
+
"dark:group-has-[[data-component='DataTable.ResizeHandle'][data-resizing]]/data-table-frame:bg-white"
|
|
106
|
+
])
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
}),
|
|
110
|
+
/* @__PURE__ */ jsx(ScrollArea.Scrollbar, {
|
|
111
|
+
orientation: "vertical",
|
|
112
|
+
className: "mt-[calc(var(--data-table-header-offset,0px)+1px)]",
|
|
113
|
+
children: /* @__PURE__ */ jsx(ScrollArea.Thumb, {})
|
|
114
|
+
}),
|
|
115
|
+
/* @__PURE__ */ jsx(ScrollArea.Scrollbar, {
|
|
116
|
+
orientation: "horizontal",
|
|
117
|
+
children: /* @__PURE__ */ jsx(ScrollArea.Thumb, {})
|
|
118
|
+
}),
|
|
119
|
+
/* @__PURE__ */ jsx(ScrollArea.Corner, {})
|
|
120
|
+
]
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
DataTableScrollArea.displayName = "DataTable.ScrollArea";
|
|
124
|
+
//#endregion
|
|
125
|
+
export { DataTableScrollArea };
|
|
126
|
+
|
|
127
|
+
//# sourceMappingURL=data-table-scroll-area.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table-scroll-area.js","names":[],"sources":["../../../../src/components/data-table/root/data-table-scroll-area.tsx"],"sourcesContent":["import { ScrollArea } from '@lucasbernardosn/react-ui/layout/scroll-area';\nimport {\n mergeStateClassNames,\n mergeTwClassNames,\n} from '@lucasbernardosn/react-ui/utils';\nimport { mergeRefs } from '@lucasbernardosn/react-utils';\nimport { useMemo } from 'react';\nimport { useDataTableHeaderOffset } from './use-data-table-header-offset';\n\nexport type DataTableScrollAreaProps = ScrollArea.RootProps;\n\n/**\n * A área de rolagem da tabela, montada com o `ScrollArea` da lib: `Root`, uma moldura com a\n * borda, `Viewport`, `Content` e as barras. Os filhos vão no `Content`, e as props no `Root`.\n *\n * O viewport é o ancestral que rola, e é nele que o cabeçalho sticky se ancora. Na largura,\n * abraça o grid e para no pai. Na altura, tem a das linhas: dentro de um pai com altura\n * limitada, encolhe e as linhas rolam por dentro; sem limite, cresce e só rola na horizontal.\n *\n * As barras ficam numa faixa fora da moldura, só no eixo que transborda: não passam por cima das\n * linhas, da seleção nem das colunas fixadas. A vertical começa abaixo do `DataTable.Header`,\n * cuja altura é medida aqui.\n */\nexport const DataTableScrollArea = (props: DataTableScrollAreaProps) => {\n const { className, children, ref, ...rest } = props;\n\n const headerOffsetRef = useDataTableHeaderOffset();\n\n /**\n * O ref de quem usa e o da medida do cabeçalho, no mesmo elemento. Memoizado: um callback novo\n * a cada render desligaria e religaria o observer.\n */\n const rootRef = useMemo(\n () => mergeRefs(headerOffsetRef, ref),\n [headerOffsetRef, ref],\n );\n\n return (\n <ScrollArea.Root\n ref={rootRef}\n data-component=\"DataTable.ScrollArea\"\n className={mergeStateClassNames(\n [\n // Sem `flex-1`: a altura é a das linhas, e o `flex-shrink` do item para no pai. O\n // `overflow-hidden` do `ScrollArea.Root` zera o mínimo, e as linhas passam a rolar.\n\n // Abraça o grid, que mede pelo `min-width: fit-content` do `Content`, mais a faixa das\n // barras, e para no pai.\n 'w-max',\n 'max-w-full',\n\n // A faixa das barras: 12px sem recuo, com o polegar mais fino centralizado nela.\n '[--scroll-area-scrollbar-size:--spacing(3)]',\n '[--scroll-area-scrollbar-inset:0px]',\n '[--scroll-area-thumb-size:--spacing(1)]',\n 'pointer-fine:[--scroll-area-thumb-size:--spacing(1.5)]',\n\n // A faixa só existe no eixo que transborda. O Base UI põe as barras nas bordas do\n // `Root`, que com o padding caem fora da moldura.\n 'data-has-overflow-y:pe-(--scroll-area-scrollbar-size)',\n 'data-has-overflow-x:pb-(--scroll-area-scrollbar-size)',\n ],\n className,\n )}\n {...rest}\n >\n <div\n className={mergeTwClassNames([\n // A altura do `Root` sem a faixa de baixo, para o viewport rolar dentro dela.\n 'h-full',\n\n // Referência da barra do carregamento, que se posiciona aqui e lê o `data-loading` do grid.\n 'relative',\n 'group/data-table-frame',\n\n // A borda cerca só a tabela, e não a faixa das barras. Num elemento que não rola: no\n // viewport, ela subiria junto com as linhas. O `overflow-clip` recorta o cabeçalho\n // sticky contra o raio sem virar contêiner de rolagem, e o sticky segue no viewport.\n 'overflow-clip',\n 'rounded-md',\n 'corner-squircle',\n 'border',\n 'border-gray-6',\n\n // O anel do viewport, que se marca com `data-focus-ring`: o tema o pinta no pai\n // direto, que é esta moldura, e não mais o `Root`.\n 'focus-ring-inside',\n '[--focus-ring-offset:-1px]',\n 'ring-gray-12',\n ])}\n >\n <ScrollArea.Viewport\n focusRing={true}\n // O arrasto horizontal no fim do curso não vira \"voltar página\"; o eixo Y fica livre\n // para o pull to refresh. O `scroll-padding-top` faz a linha que recebe o foco parar\n // abaixo do cabeçalho sticky, e não embaixo dele.\n className=\"overscroll-x-contain scroll-pt-(--data-table-header-offset)\"\n >\n <ScrollArea.Content>{children}</ScrollArea.Content>\n </ScrollArea.Viewport>\n\n <div\n aria-hidden={true}\n data-component=\"DataTable.LoadingBar\"\n className={mergeTwClassNames([\n // A barra do carregamento (`data-loading` no `DataTable.Root`), na borda de baixo do\n // cabeçalho. Na moldura, e não no cabeçalho: não acompanha a rolagem horizontal e\n // cobre sempre a largura visível. O seletor nomeia o `Root`: o `Skeleton` do `ui`\n // também marca `data-loading`, e um dentro de uma célula acenderia a barra.\n 'hidden',\n \"group-has-[[data-component='DataTable.Root'][data-loading]]/data-table-frame:block\",\n 'pointer-events-none',\n 'absolute',\n 'inset-x-0',\n 'top-[calc(var(--data-table-header-offset,0px)-1px)]',\n 'z-30',\n 'h-0.5',\n 'overflow-hidden',\n\n // Sem progresso real, um trecho corre de um lado ao outro, sem pausa. A animação do\n // tema pede o trecho com 2/5 da largura. Com movimento reduzido, a barra fica parada\n // e inteira.\n \"before:content-['']\",\n 'before:absolute',\n 'before:inset-y-0',\n 'before:w-2/5',\n 'before:rounded-full',\n 'before:bg-gray-11',\n 'not-motion-reduced:before:animate-progress-indeterminate',\n 'motion-reduced:before:w-full',\n 'motion-reduced:before:bg-gray-8',\n ])}\n />\n\n <div\n aria-hidden={true}\n data-component=\"DataTable.ResizeGuide\"\n className={mergeTwClassNames([\n // A linha-guia do resize, na altura toda da tabela, presa à linha vertical da coluna\n // pela âncora que o `DataTable.ResizeHandle` marca no hover e no arrasto. Na moldura e\n // acima das fixadas: a borda da coluna pode passar por baixo de uma fixada, e a guia\n // segue à vista.\n 'hidden',\n \"group-has-[[data-component='DataTable.ResizeHandle']:hover]/data-table-frame:block\",\n \"group-has-[[data-component='DataTable.ResizeHandle'][data-resizing]]/data-table-frame:block\",\n // Sem anchor positioning, a guia ficaria no canto da moldura: fica só a linha do\n // handle, no cabeçalho.\n 'not-supports-[anchor-name:--a]:hidden!',\n 'pointer-events-none',\n 'absolute',\n 'inset-y-0',\n 'z-30',\n // No lugar da linha do handle: centrada nele, sobre a borda e 1px antes dela.\n 'w-0.5',\n 'left-[anchor(left)]',\n '-translate-x-1/2',\n '[position-anchor:--data-table-resize-handle]',\n 'bg-gray-9',\n \"group-has-[[data-component='DataTable.ResizeHandle'][data-resizing]]/data-table-frame:bg-black\",\n \"dark:group-has-[[data-component='DataTable.ResizeHandle'][data-resizing]]/data-table-frame:bg-white\",\n ])}\n />\n </div>\n\n <ScrollArea.Scrollbar\n orientation=\"vertical\"\n // Começa abaixo do cabeçalho sticky, na altura da primeira linha: a do cabeçalho mais a\n // borda de cima da moldura.\n className=\"mt-[calc(var(--data-table-header-offset,0px)+1px)]\"\n >\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n\n <ScrollArea.Scrollbar orientation=\"horizontal\">\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n\n <ScrollArea.Corner />\n </ScrollArea.Root>\n );\n};\n\nDataTableScrollArea.displayName = 'DataTable.ScrollArea';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAuBA,MAAa,uBAAuB,UAAoC;CACtE,MAAM,EAAE,WAAW,UAAU,KAAK,GAAG,SAAS;CAE9C,MAAM,kBAAkB,yBAAyB;;;;;CAMjD,MAAM,UAAU,cACR,UAAU,iBAAiB,GAAG,GACpC,CAAC,iBAAiB,GAAG,CACvB;CAEA,OACE,qBAAC,WAAW,MAAZ;EACE,KAAK;EACL,kBAAe;EACf,WAAW,qBACT;GAME;GACA;GAGA;GACA;GACA;GACA;GAIA;GACA;EACF,GACA,SACF;EACA,GAAI;EA1BN,UAAA;GA4BE,qBAAC,OAAD;IACE,WAAW,kBAAkB;KAE3B;KAGA;KACA;KAKA;KACA;KACA;KACA;KACA;KAIA;KACA;KACA;IACF,CAAC;IAvBH,UAAA;KAyBE,oBAAC,WAAW,UAAZ;MACE,WAAW;MAIX,WAAU;MAEV,UAAA,oBAAC,WAAW,SAAZ,EAAqB,SAA6B,CAAA;KAC/B,CAAA;KAErB,oBAAC,OAAD;MACE,eAAa;MACb,kBAAe;MACf,WAAW,kBAAkB;OAK3B;OACA;OACA;OACA;OACA;OACA;OACA;OACA;OACA;OAKA;OACA;OACA;OACA;OACA;OACA;OACA;OACA;OACA;MACF,CAAC;KACF,CAAA;KAED,oBAAC,OAAD;MACE,eAAa;MACb,kBAAe;MACf,WAAW,kBAAkB;OAK3B;OACA;OACA;OAGA;OACA;OACA;OACA;OACA;OAEA;OACA;OACA;OACA;OACA;OACA;OACA;MACF,CAAC;KACF,CAAA;IACE;;GAEL,oBAAC,WAAW,WAAZ;IACE,aAAY;IAGZ,WAAU;IAEV,UAAA,oBAAC,WAAW,OAAZ,CAAmB,CAAA;GACC,CAAA;GAEtB,oBAAC,WAAW,WAAZ;IAAsB,aAAY;IAChC,UAAA,oBAAC,WAAW,OAAZ,CAAmB,CAAA;GACC,CAAA;GAEtB,oBAAC,WAAW,QAAZ,CAAoB,CAAA;EACL;;AAErB;AAEA,oBAAoB,cAAc"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { TableWith } from "../../../types/table-with.js";
|
|
2
|
+
import "../../../types/index.js";
|
|
3
|
+
import { RowData, TableFeatures } from "@tanstack/react-table";
|
|
4
|
+
//#region src/components/data-table/root/get-data-table-column-layout.d.ts
|
|
5
|
+
/** O layout das colunas do grid, nos valores que o `Root` põe nas variáveis CSS. */
|
|
6
|
+
export type DataTableColumnLayout = {
|
|
7
|
+
/** A largura de cada coluna visível, em px, na ordem das células. */
|
|
8
|
+
template: string;
|
|
9
|
+
/** A soma das larguras, em px. */
|
|
10
|
+
width: string;
|
|
11
|
+
/**
|
|
12
|
+
* O deslocamento de cada coluna fixada, em px, pelo nome da variável que a célula dela lê: no
|
|
13
|
+
* início, a soma das fixadas antes dela; no fim, a das fixadas depois.
|
|
14
|
+
*/
|
|
15
|
+
offsets: Record<string, string>;
|
|
16
|
+
/**
|
|
17
|
+
* A largura das colunas fixadas de cada lado, em px: o `scroll-padding` lateral do contêiner que
|
|
18
|
+
* rola. Sem ele, o foco num elemento coberto por uma fixada não rola até ele, porque para o
|
|
19
|
+
* navegador o elemento já está na área visível.
|
|
20
|
+
*/
|
|
21
|
+
scrollPadding: {
|
|
22
|
+
start: string;
|
|
23
|
+
end: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* O layout das colunas visíveis, a partir dos headers folha: a linha de headers que
|
|
28
|
+
* particiona as colunas fixadas na mesma ordem de `row.getVisibleCells()`, então os tracks
|
|
29
|
+
* batem com as células.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* // Colunas visíveis de 44, 150 e 100px, com a primeira e a segunda fixadas no início:
|
|
34
|
+
* getDataTableColumnLayout(table);
|
|
35
|
+
* // → {
|
|
36
|
+
* // template: '44px 150px 100px',
|
|
37
|
+
* // width: '294px',
|
|
38
|
+
* // offsets: { '--data-table-pin-start-0': '0px', '--data-table-pin-start-1': '44px' },
|
|
39
|
+
* // scrollPadding: { start: '194px', end: '0px' },
|
|
40
|
+
* // }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare const getDataTableColumnLayout: <TFeatures extends TableFeatures, TData extends RowData>(table: TableWith<TFeatures, TData, "columnSizingFeature">) => DataTableColumnLayout;
|
|
44
|
+
//#endregion
|
|
45
|
+
//# sourceMappingURL=get-data-table-column-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-data-table-column-layout.d.ts","names":[],"sources":["../../../../src/components/data-table/root/get-data-table-column-layout.ts"],"mappings":";;;;;YASY;;EAEV;;EAEA;;;;;EAKA,SAAS;;;;;;EAMT;IAAiB;IAAe;;;;;;;;;;;;;;;;;;;;qBAoBrB,2BACX,kBAAkB,eAClB,cAAc,SAEd,OAAO,UAAU,WAAW,kCAC3B"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { hasHeaderFeature, hasTableFeature } from "../../../utils/has-feature.js";
|
|
2
|
+
import { getDataTableColumnPinning, getDataTablePinnedOffsetVariable } from "./get-data-table-column-pinning.js";
|
|
3
|
+
//#region src/components/data-table/root/get-data-table-column-layout.ts
|
|
4
|
+
/**
|
|
5
|
+
* O layout das colunas visíveis, a partir dos headers folha: a linha de headers que
|
|
6
|
+
* particiona as colunas fixadas na mesma ordem de `row.getVisibleCells()`, então os tracks
|
|
7
|
+
* batem com as células.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // Colunas visíveis de 44, 150 e 100px, com a primeira e a segunda fixadas no início:
|
|
12
|
+
* getDataTableColumnLayout(table);
|
|
13
|
+
* // → {
|
|
14
|
+
* // template: '44px 150px 100px',
|
|
15
|
+
* // width: '294px',
|
|
16
|
+
* // offsets: { '--data-table-pin-start-0': '0px', '--data-table-pin-start-1': '44px' },
|
|
17
|
+
* // scrollPadding: { start: '194px', end: '0px' },
|
|
18
|
+
* // }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
const getDataTableColumnLayout = (table) => {
|
|
22
|
+
/**
|
|
23
|
+
* O tipo já exige `columnSizingFeature`: isto é o caso sem TypeScript, em que uma coluna fora
|
|
24
|
+
* do template desalinharia o grid em silêncio.
|
|
25
|
+
*/
|
|
26
|
+
if (!hasTableFeature(table, "columnSizingFeature")) throw new Error("DataTable.Root: a tabela precisa de `columnSizingFeature` nas features.");
|
|
27
|
+
/**
|
|
28
|
+
* Com a feature registrada, todo header passa: o guard só estreita o header, que sai da tabela
|
|
29
|
+
* sem as features.
|
|
30
|
+
*/
|
|
31
|
+
const leafHeaders = (table.getHeaderGroups().at(-1)?.headers ?? []).filter((header) => hasHeaderFeature(header, "columnSizingFeature"));
|
|
32
|
+
/**
|
|
33
|
+
* Só das colunas visíveis, que são as que têm célula. O índice da variável é o da fixação, que
|
|
34
|
+
* a célula também lê.
|
|
35
|
+
*/
|
|
36
|
+
const offsets = leafHeaders.flatMap((header) => {
|
|
37
|
+
const pinning = getDataTableColumnPinning(header.column);
|
|
38
|
+
return pinning.position === "start" ? [[getDataTablePinnedOffsetVariable("start", pinning.index), `${header.column.getStart("start")}px`]] : pinning.position === "end" ? [[getDataTablePinnedOffsetVariable("end", pinning.index), `${header.column.getAfter("end")}px`]] : [];
|
|
39
|
+
});
|
|
40
|
+
/** A soma das larguras das colunas visíveis fixadas de um lado. */
|
|
41
|
+
const getPinnedWidth = (position) => leafHeaders.filter((header) => getDataTableColumnPinning(header.column).position === position).reduce((width, header) => width + header.getSize(), 0);
|
|
42
|
+
return {
|
|
43
|
+
template: leafHeaders.map((header) => `${header.getSize()}px`).join(" "),
|
|
44
|
+
width: `${table.getTotalSize()}px`,
|
|
45
|
+
offsets: Object.fromEntries(offsets),
|
|
46
|
+
scrollPadding: {
|
|
47
|
+
start: `${getPinnedWidth("start")}px`,
|
|
48
|
+
end: `${getPinnedWidth("end")}px`
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { getDataTableColumnLayout };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=get-data-table-column-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-data-table-column-layout.js","names":[],"sources":["../../../../src/components/data-table/root/get-data-table-column-layout.ts"],"sourcesContent":["import type { RowData, TableFeatures } from '@tanstack/react-table';\nimport type { TableWith } from '../../../types';\nimport { hasHeaderFeature, hasTableFeature } from '../../../utils';\nimport {\n getDataTableColumnPinning,\n getDataTablePinnedOffsetVariable,\n} from './get-data-table-column-pinning';\n\n/** O layout das colunas do grid, nos valores que o `Root` põe nas variáveis CSS. */\nexport type DataTableColumnLayout = {\n /** A largura de cada coluna visível, em px, na ordem das células. */\n template: string;\n /** A soma das larguras, em px. */\n width: string;\n /**\n * O deslocamento de cada coluna fixada, em px, pelo nome da variável que a célula dela lê: no\n * início, a soma das fixadas antes dela; no fim, a das fixadas depois.\n */\n offsets: Record<string, string>;\n /**\n * A largura das colunas fixadas de cada lado, em px: o `scroll-padding` lateral do contêiner que\n * rola. Sem ele, o foco num elemento coberto por uma fixada não rola até ele, porque para o\n * navegador o elemento já está na área visível.\n */\n scrollPadding: { start: string; end: string };\n};\n\n/**\n * O layout das colunas visíveis, a partir dos headers folha: a linha de headers que\n * particiona as colunas fixadas na mesma ordem de `row.getVisibleCells()`, então os tracks\n * batem com as células.\n *\n * @example\n * ```ts\n * // Colunas visíveis de 44, 150 e 100px, com a primeira e a segunda fixadas no início:\n * getDataTableColumnLayout(table);\n * // → {\n * // template: '44px 150px 100px',\n * // width: '294px',\n * // offsets: { '--data-table-pin-start-0': '0px', '--data-table-pin-start-1': '44px' },\n * // scrollPadding: { start: '194px', end: '0px' },\n * // }\n * ```\n */\nexport const getDataTableColumnLayout = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: TableWith<TFeatures, TData, 'columnSizingFeature'>,\n): DataTableColumnLayout => {\n /**\n * O tipo já exige `columnSizingFeature`: isto é o caso sem TypeScript, em que uma coluna fora\n * do template desalinharia o grid em silêncio.\n */\n if (!hasTableFeature(table, 'columnSizingFeature')) {\n throw new Error(\n 'DataTable.Root: a tabela precisa de `columnSizingFeature` nas features.',\n );\n }\n\n /**\n * Com a feature registrada, todo header passa: o guard só estreita o header, que sai da tabela\n * sem as features.\n */\n const leafHeaders = (table.getHeaderGroups().at(-1)?.headers ?? []).filter(\n (header) => hasHeaderFeature(header, 'columnSizingFeature'),\n );\n\n /**\n * Só das colunas visíveis, que são as que têm célula. O índice da variável é o da fixação, que\n * a célula também lê.\n */\n const offsets = leafHeaders.flatMap((header): [string, string][] => {\n const pinning = getDataTableColumnPinning(header.column);\n\n return pinning.position === 'start'\n ? [\n [\n getDataTablePinnedOffsetVariable('start', pinning.index),\n `${header.column.getStart('start')}px`,\n ],\n ]\n : pinning.position === 'end'\n ? [\n [\n getDataTablePinnedOffsetVariable('end', pinning.index),\n `${header.column.getAfter('end')}px`,\n ],\n ]\n : [];\n });\n\n /** A soma das larguras das colunas visíveis fixadas de um lado. */\n const getPinnedWidth = (position: 'start' | 'end') =>\n leafHeaders\n .filter(\n (header) =>\n getDataTableColumnPinning(header.column).position === position,\n )\n .reduce((width, header) => width + header.getSize(), 0);\n\n return {\n template: leafHeaders.map((header) => `${header.getSize()}px`).join(' '),\n width: `${table.getTotalSize()}px`,\n offsets: Object.fromEntries(offsets),\n scrollPadding: {\n start: `${getPinnedWidth('start')}px`,\n end: `${getPinnedWidth('end')}px`,\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA4CA,MAAa,4BAIX,UAC0B;;;;;CAK1B,IAAI,CAAC,gBAAgB,OAAO,qBAAqB,GAC/C,MAAM,IAAI,MACR,yEACF;;;;;CAOF,MAAM,eAAe,MAAM,gBAAgB,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,WAAW,CAAC,EAAA,CAAG,QACjE,WAAW,iBAAiB,QAAQ,qBAAqB,CAC5D;;;;;CAMA,MAAM,UAAU,YAAY,SAAS,WAA+B;EAClE,MAAM,UAAU,0BAA0B,OAAO,MAAM;EAEvD,OAAO,QAAQ,aAAa,UACxB,CACE,CACE,iCAAiC,SAAS,QAAQ,KAAK,GACvD,GAAG,OAAO,OAAO,SAAS,OAAO,EAAE,GACrC,CACF,IACA,QAAQ,aAAa,QACnB,CACE,CACE,iCAAiC,OAAO,QAAQ,KAAK,GACrD,GAAG,OAAO,OAAO,SAAS,KAAK,EAAE,GACnC,CACF,IACA,CAAC;CACT,CAAC;;CAGD,MAAM,kBAAkB,aACtB,YACG,QACE,WACC,0BAA0B,OAAO,MAAM,CAAC,CAAC,aAAa,QAC1D,CAAC,CACA,QAAQ,OAAO,WAAW,QAAQ,OAAO,QAAQ,GAAG,CAAC;CAE1D,OAAO;EACL,UAAU,YAAY,KAAK,WAAW,GAAG,OAAO,QAAQ,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG;EACvE,OAAO,GAAG,MAAM,aAAa,EAAE;EAC/B,SAAS,OAAO,YAAY,OAAO;EACnC,eAAe;GACb,OAAO,GAAG,eAAe,OAAO,EAAE;GAClC,KAAK,GAAG,eAAe,KAAK,EAAE;EAChC;CACF;AACF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Column, ColumnPinningPosition, RowData, TableFeatures } from "@tanstack/react-table";
|
|
2
|
+
import React from "react";
|
|
3
|
+
//#region src/components/data-table/root/get-data-table-column-pinning.d.ts
|
|
4
|
+
/** Onde uma coluna está fixada, e a posição dela entre as fixadas do mesmo lado. */
|
|
5
|
+
export type DataTableColumnPinning = {
|
|
6
|
+
/** O lado da fixação, ou `false` fora dela. */
|
|
7
|
+
position: ColumnPinningPosition;
|
|
8
|
+
/** O `column.getPinnedIndex()`: a posição no estado do pinning, que conta as escondidas. */
|
|
9
|
+
index: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* A fixação de uma coluna. Sem `columnPinningFeature`, a coluna não está fixada.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // Com `columnPinning: { start: ['select', 'name'], end: [] }`:
|
|
17
|
+
* getDataTableColumnPinning(table.getColumn('name'));
|
|
18
|
+
* // → { position: 'start', index: 1 }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare const getDataTableColumnPinning: <TFeatures extends TableFeatures, TData extends RowData, TValue>(column: Column<TFeatures, TData, TValue>) => DataTableColumnPinning;
|
|
22
|
+
/**
|
|
23
|
+
* O nome da variável com o deslocamento de uma coluna fixada: o `DataTable.Root` escreve, e a
|
|
24
|
+
* célula e o header da coluna leem. Os dois lados usam o mesmo índice, o da fixação, e batem
|
|
25
|
+
* mesmo com uma coluna fixada escondida.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* getDataTablePinnedOffsetVariable('start', 1);
|
|
30
|
+
* // → '--data-table-pin-start-1'
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const getDataTablePinnedOffsetVariable: (position: "start" | "end", index: number) => string;
|
|
34
|
+
/**
|
|
35
|
+
* O estilo de uma célula fixada: o deslocamento do lado dela, pela variável que o
|
|
36
|
+
* `DataTable.Root` escreve. Fora da fixação, nenhum.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* getDataTablePinnedStyle({ position: 'start', index: 1 });
|
|
41
|
+
* // → { insetInlineStart: 'var(--data-table-pin-start-1)' }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare const getDataTablePinnedStyle: (pinning: DataTableColumnPinning) => React.CSSProperties | undefined;
|
|
45
|
+
//#endregion
|
|
46
|
+
//# sourceMappingURL=get-data-table-column-pinning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-data-table-column-pinning.d.ts","names":[],"sources":["../../../../src/components/data-table/root/get-data-table-column-pinning.ts"],"mappings":";;;;YAUY;;EAEV,UAAU;;EAEV;;;;;;;;;;;;qBAaW,4BACX,kBAAkB,eAClB,cAAc,SACd,QAEA,QAAQ,OAAO,WAAW,OAAO,YAChC;;;;;;;;;;;;qBAgBU,mCACX,2BACA;;;;;;;;;;;qBAaW,0BACX,SAAS,2BACR,MAAM"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { hasColumnFeature } from "../../../utils/has-feature.js";
|
|
2
|
+
//#region src/components/data-table/root/get-data-table-column-pinning.ts
|
|
3
|
+
/**
|
|
4
|
+
* A fixação de uma coluna. Sem `columnPinningFeature`, a coluna não está fixada.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* // Com `columnPinning: { start: ['select', 'name'], end: [] }`:
|
|
9
|
+
* getDataTableColumnPinning(table.getColumn('name'));
|
|
10
|
+
* // → { position: 'start', index: 1 }
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
const getDataTableColumnPinning = (column) => hasColumnFeature(column, "columnPinningFeature") ? {
|
|
14
|
+
position: column.getIsPinned(),
|
|
15
|
+
index: column.getPinnedIndex()
|
|
16
|
+
} : {
|
|
17
|
+
position: false,
|
|
18
|
+
index: 0
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* O nome da variável com o deslocamento de uma coluna fixada: o `DataTable.Root` escreve, e a
|
|
22
|
+
* célula e o header da coluna leem. Os dois lados usam o mesmo índice, o da fixação, e batem
|
|
23
|
+
* mesmo com uma coluna fixada escondida.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* getDataTablePinnedOffsetVariable('start', 1);
|
|
28
|
+
* // → '--data-table-pin-start-1'
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
const getDataTablePinnedOffsetVariable = (position, index) => `--data-table-pin-${position}-${index}`;
|
|
32
|
+
/**
|
|
33
|
+
* O estilo de uma célula fixada: o deslocamento do lado dela, pela variável que o
|
|
34
|
+
* `DataTable.Root` escreve. Fora da fixação, nenhum.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* getDataTablePinnedStyle({ position: 'start', index: 1 });
|
|
39
|
+
* // → { insetInlineStart: 'var(--data-table-pin-start-1)' }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
const getDataTablePinnedStyle = (pinning) => pinning.position === "start" ? { insetInlineStart: `var(${getDataTablePinnedOffsetVariable("start", pinning.index)})` } : pinning.position === "end" ? { insetInlineEnd: `var(${getDataTablePinnedOffsetVariable("end", pinning.index)})` } : void 0;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { getDataTableColumnPinning, getDataTablePinnedOffsetVariable, getDataTablePinnedStyle };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=get-data-table-column-pinning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-data-table-column-pinning.js","names":[],"sources":["../../../../src/components/data-table/root/get-data-table-column-pinning.ts"],"sourcesContent":["import type {\n Column,\n ColumnPinningPosition,\n RowData,\n TableFeatures,\n} from '@tanstack/react-table';\nimport type React from 'react';\nimport { hasColumnFeature } from '../../../utils';\n\n/** Onde uma coluna está fixada, e a posição dela entre as fixadas do mesmo lado. */\nexport type DataTableColumnPinning = {\n /** O lado da fixação, ou `false` fora dela. */\n position: ColumnPinningPosition;\n /** O `column.getPinnedIndex()`: a posição no estado do pinning, que conta as escondidas. */\n index: number;\n};\n\n/**\n * A fixação de uma coluna. Sem `columnPinningFeature`, a coluna não está fixada.\n *\n * @example\n * ```ts\n * // Com `columnPinning: { start: ['select', 'name'], end: [] }`:\n * getDataTableColumnPinning(table.getColumn('name'));\n * // → { position: 'start', index: 1 }\n * ```\n */\nexport const getDataTableColumnPinning = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n TValue,\n>(\n column: Column<TFeatures, TData, TValue>,\n): DataTableColumnPinning =>\n hasColumnFeature(column, 'columnPinningFeature')\n ? { position: column.getIsPinned(), index: column.getPinnedIndex() }\n : { position: false, index: 0 };\n\n/**\n * O nome da variável com o deslocamento de uma coluna fixada: o `DataTable.Root` escreve, e a\n * célula e o header da coluna leem. Os dois lados usam o mesmo índice, o da fixação, e batem\n * mesmo com uma coluna fixada escondida.\n *\n * @example\n * ```ts\n * getDataTablePinnedOffsetVariable('start', 1);\n * // → '--data-table-pin-start-1'\n * ```\n */\nexport const getDataTablePinnedOffsetVariable = (\n position: 'start' | 'end',\n index: number,\n) => `--data-table-pin-${position}-${index}`;\n\n/**\n * O estilo de uma célula fixada: o deslocamento do lado dela, pela variável que o\n * `DataTable.Root` escreve. Fora da fixação, nenhum.\n *\n * @example\n * ```ts\n * getDataTablePinnedStyle({ position: 'start', index: 1 });\n * // → { insetInlineStart: 'var(--data-table-pin-start-1)' }\n * ```\n */\nexport const getDataTablePinnedStyle = (\n pinning: DataTableColumnPinning,\n): React.CSSProperties | undefined =>\n pinning.position === 'start'\n ? {\n insetInlineStart: `var(${getDataTablePinnedOffsetVariable('start', pinning.index)})`,\n }\n : pinning.position === 'end'\n ? {\n insetInlineEnd: `var(${getDataTablePinnedOffsetVariable('end', pinning.index)})`,\n }\n : undefined;\n"],"mappings":";;;;;;;;;;;;AA2BA,MAAa,6BAKX,WAEA,iBAAiB,QAAQ,sBAAsB,IAC3C;CAAE,UAAU,OAAO,YAAY;CAAG,OAAO,OAAO,eAAe;AAAE,IACjE;CAAE,UAAU;CAAO,OAAO;AAAE;;;;;;;;;;;;AAalC,MAAa,oCACX,UACA,UACG,oBAAoB,SAAS,GAAG;;;;;;;;;;;AAYrC,MAAa,2BACX,YAEA,QAAQ,aAAa,UACjB,EACE,kBAAkB,OAAO,iCAAiC,SAAS,QAAQ,KAAK,EAAE,GACpF,IACA,QAAQ,aAAa,QACnB,EACE,gBAAgB,OAAO,iCAAiC,OAAO,QAAQ,KAAK,EAAE,GAChF,IACA,KAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/components/data-table/root/get-data-table-scroll-parent.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* O ancestral que rola a tabela. A `DataTable.ScrollArea` põe nele o `scroll-padding-top` com a
|
|
4
|
+
* altura do cabeçalho.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* getDataTableScrollParent(bodyElement)?.scrollTo({ top: 0 });
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare const getDataTableScrollParent: (element: Element) => HTMLElement | undefined;
|
|
12
|
+
//#endregion
|
|
13
|
+
//# sourceMappingURL=get-data-table-scroll-parent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-data-table-scroll-parent.d.ts","names":[],"sources":["../../../../src/components/data-table/root/get-data-table-scroll-parent.ts"],"mappings":";;;;;;;;;;qBASa,2BAA4B,SAAS,YAAO"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/components/data-table/root/get-data-table-scroll-parent.ts
|
|
2
|
+
/**
|
|
3
|
+
* O ancestral que rola a tabela. A `DataTable.ScrollArea` põe nele o `scroll-padding-top` com a
|
|
4
|
+
* altura do cabeçalho.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* getDataTableScrollParent(bodyElement)?.scrollTo({ top: 0 });
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
const getDataTableScrollParent = (element) => {
|
|
12
|
+
for (let parent = element.parentElement; parent; parent = parent.parentElement) {
|
|
13
|
+
const { overflowY } = getComputedStyle(parent);
|
|
14
|
+
if (overflowY === "auto" || overflowY === "scroll") return parent;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
export { getDataTableScrollParent };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=get-data-table-scroll-parent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-data-table-scroll-parent.js","names":[],"sources":["../../../../src/components/data-table/root/get-data-table-scroll-parent.ts"],"sourcesContent":["/**\n * O ancestral que rola a tabela. A `DataTable.ScrollArea` põe nele o `scroll-padding-top` com a\n * altura do cabeçalho.\n *\n * @example\n * ```ts\n * getDataTableScrollParent(bodyElement)?.scrollTo({ top: 0 });\n * ```\n */\nexport const getDataTableScrollParent = (element: Element) => {\n for (\n let parent = element.parentElement;\n parent;\n parent = parent.parentElement\n ) {\n const { overflowY } = getComputedStyle(parent);\n\n if (overflowY === 'auto' || overflowY === 'scroll') {\n return parent;\n }\n }\n\n return undefined;\n};\n"],"mappings":";;;;;;;;;;AASA,MAAa,4BAA4B,YAAqB;CAC5D,KACE,IAAI,SAAS,QAAQ,eACrB,QACA,SAAS,OAAO,eAChB;EACA,MAAM,EAAE,cAAc,iBAAiB,MAAM;EAE7C,IAAI,cAAc,UAAU,cAAc,UACxC,OAAO;CAEX;AAGF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { TableWith } from "../../../types/table-with.js";
|
|
2
|
+
import "../../../types/index.js";
|
|
3
|
+
import { RowData, TableFeatures } from "@tanstack/react-table";
|
|
4
|
+
//#region src/components/data-table/root/use-data-table-column-layout.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Sincroniza o layout das colunas com o elemento do grid, nas variáveis que as partes leem:
|
|
7
|
+
*
|
|
8
|
+
* - `--data-table-template`: a largura de cada coluna visível, em px, na ordem das células;
|
|
9
|
+
* - `--data-table-width`: a soma delas;
|
|
10
|
+
* - `--data-table-pin-<lado>-<n>`: o deslocamento de cada coluna fixada, que a célula dela lê.
|
|
11
|
+
*
|
|
12
|
+
* Escreve também o `scroll-padding` lateral do contêiner que rola, com a largura das fixadas de
|
|
13
|
+
* cada lado: o foco que vai para um elemento coberto por uma fixada (o Tab no cabeçalho, um
|
|
14
|
+
* controle numa célula) rola até ele.
|
|
15
|
+
*
|
|
16
|
+
* Assina o store da tabela, fora do React: quando tamanho, visibilidade, ordem ou pinning das
|
|
17
|
+
* colunas mudam, só as variáveis mudam, sem render. A cada render do `Root` também sincroniza,
|
|
18
|
+
* para `columns` novos, que não passam pelo store. Nos dois casos, só toca no estilo se o layout
|
|
19
|
+
* mudou, e tira a variável de uma coluna que deixou de ser fixada.
|
|
20
|
+
*
|
|
21
|
+
* Devolve o callback ref do elemento do grid.
|
|
22
|
+
*/
|
|
23
|
+
export declare const useDataTableColumnLayout: <TFeatures extends TableFeatures, TData extends RowData>(table: TableWith<TFeatures, TData, "columnSizingFeature">) => (element: HTMLDivElement | null) => void;
|
|
24
|
+
//#endregion
|
|
25
|
+
//# sourceMappingURL=use-data-table-column-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-data-table-column-layout.d.ts","names":[],"sources":["../../../../src/components/data-table/root/use-data-table-column-layout.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;qBAwBa,2BACX,kBAAkB,eAClB,cAAc,SAEd,OAAO,UAAU,WAAW,mCAA6B,SA8E7C"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { getDataTableScrollParent } from "./get-data-table-scroll-parent.js";
|
|
2
|
+
import { getDataTableColumnLayout } from "./get-data-table-column-layout.js";
|
|
3
|
+
import { useCallback, useLayoutEffect, useRef } from "react";
|
|
4
|
+
//#region src/components/data-table/root/use-data-table-column-layout.ts
|
|
5
|
+
/**
|
|
6
|
+
* Sincroniza o layout das colunas com o elemento do grid, nas variáveis que as partes leem:
|
|
7
|
+
*
|
|
8
|
+
* - `--data-table-template`: a largura de cada coluna visível, em px, na ordem das células;
|
|
9
|
+
* - `--data-table-width`: a soma delas;
|
|
10
|
+
* - `--data-table-pin-<lado>-<n>`: o deslocamento de cada coluna fixada, que a célula dela lê.
|
|
11
|
+
*
|
|
12
|
+
* Escreve também o `scroll-padding` lateral do contêiner que rola, com a largura das fixadas de
|
|
13
|
+
* cada lado: o foco que vai para um elemento coberto por uma fixada (o Tab no cabeçalho, um
|
|
14
|
+
* controle numa célula) rola até ele.
|
|
15
|
+
*
|
|
16
|
+
* Assina o store da tabela, fora do React: quando tamanho, visibilidade, ordem ou pinning das
|
|
17
|
+
* colunas mudam, só as variáveis mudam, sem render. A cada render do `Root` também sincroniza,
|
|
18
|
+
* para `columns` novos, que não passam pelo store. Nos dois casos, só toca no estilo se o layout
|
|
19
|
+
* mudou, e tira a variável de uma coluna que deixou de ser fixada.
|
|
20
|
+
*
|
|
21
|
+
* Devolve o callback ref do elemento do grid.
|
|
22
|
+
*/
|
|
23
|
+
const useDataTableColumnLayout = (table) => {
|
|
24
|
+
/**
|
|
25
|
+
* O elemento do grid, ligado pelo callback ref devolvido no fim.
|
|
26
|
+
*/
|
|
27
|
+
const elementRef = useRef(null);
|
|
28
|
+
/**
|
|
29
|
+
* As variáveis aplicadas no elemento atual, pelo nome. O `syncColumnLayout` compara com elas e
|
|
30
|
+
* só toca no estilo do que mudou: a maioria das mudanças do store (seleção, página) não mexe
|
|
31
|
+
* nas colunas.
|
|
32
|
+
*/
|
|
33
|
+
const lastVariablesRef = useRef({});
|
|
34
|
+
/**
|
|
35
|
+
* O contêiner que rola, procurado uma vez ao ligar o elemento: a busca lê o estilo computado dos
|
|
36
|
+
* ancestrais, e a cada tick do arrasto de uma coluna forçaria um recálculo de estilo.
|
|
37
|
+
*/
|
|
38
|
+
const scrollParentRef = useRef(void 0);
|
|
39
|
+
/** O `scroll-padding` lateral aplicado no contêiner, para só tocar no estilo se mudou. */
|
|
40
|
+
const lastScrollPaddingRef = useRef("");
|
|
41
|
+
/**
|
|
42
|
+
* A tabela do último render. O objeto `table` é novo a cada render; lido por ref, ele não entra
|
|
43
|
+
* nas dependências da assinatura, que senão seria desfeita e refeita em todo render.
|
|
44
|
+
*/
|
|
45
|
+
const tableRef = useRef(table);
|
|
46
|
+
/**
|
|
47
|
+
* Calcula o layout e o aplica no elemento, se mudou. Chamado de três lugares: ao ligar um
|
|
48
|
+
* elemento, depois de cada commit e a cada mudança do store. Lê tudo por ref, então a
|
|
49
|
+
* identidade é estável e não refaz o callback ref nem a assinatura.
|
|
50
|
+
*/
|
|
51
|
+
const syncColumnLayout = useCallback(() => {
|
|
52
|
+
const element = elementRef.current;
|
|
53
|
+
if (!element) return;
|
|
54
|
+
const layout = getDataTableColumnLayout(tableRef.current);
|
|
55
|
+
const variables = {
|
|
56
|
+
"--data-table-template": layout.template,
|
|
57
|
+
"--data-table-width": layout.width,
|
|
58
|
+
...layout.offsets
|
|
59
|
+
};
|
|
60
|
+
const lastVariables = lastVariablesRef.current;
|
|
61
|
+
for (const name of Object.keys(lastVariables)) if (!(name in variables)) element.style.removeProperty(name);
|
|
62
|
+
for (const [name, value] of Object.entries(variables)) if (lastVariables[name] !== value) element.style.setProperty(name, value);
|
|
63
|
+
lastVariablesRef.current = variables;
|
|
64
|
+
const scrollParent = scrollParentRef.current;
|
|
65
|
+
const scrollPadding = `${layout.scrollPadding.start} ${layout.scrollPadding.end}`;
|
|
66
|
+
if (scrollParent && lastScrollPaddingRef.current !== scrollPadding) {
|
|
67
|
+
scrollParent.style.scrollPaddingInline = scrollPadding;
|
|
68
|
+
lastScrollPaddingRef.current = scrollPadding;
|
|
69
|
+
}
|
|
70
|
+
}, []);
|
|
71
|
+
/**
|
|
72
|
+
* Um elemento novo (outro `render`, ou um remount só do elemento) nasce sem as variáveis. O que
|
|
73
|
+
* está em `lastVariablesRef` era do anterior: sem descartar, o sync acharia que nada mudou e não
|
|
74
|
+
* aplicaria no novo.
|
|
75
|
+
*/
|
|
76
|
+
const ref = useCallback((element) => {
|
|
77
|
+
elementRef.current = element;
|
|
78
|
+
lastVariablesRef.current = {};
|
|
79
|
+
scrollParentRef.current = element ? getDataTableScrollParent(element) : void 0;
|
|
80
|
+
lastScrollPaddingRef.current = "";
|
|
81
|
+
syncColumnLayout();
|
|
82
|
+
}, [syncColumnLayout]);
|
|
83
|
+
/**
|
|
84
|
+
* Sem dependências: roda depois de todo commit do `Root`. Cobre o que muda as colunas sem passar
|
|
85
|
+
* pelo store, como `columns` novos. Layout effect, e não effect, para o grid nunca pintar com o
|
|
86
|
+
* template antigo.
|
|
87
|
+
*/
|
|
88
|
+
useLayoutEffect(() => {
|
|
89
|
+
tableRef.current = table;
|
|
90
|
+
syncColumnLayout();
|
|
91
|
+
});
|
|
92
|
+
/**
|
|
93
|
+
* Tamanho, visibilidade, ordem e pinning mudam pelo store, inclusive a cada tick do arrasto de
|
|
94
|
+
* uma coluna: sincronizar daqui mantém tudo isso fora do React, sem render. O store é estável,
|
|
95
|
+
* então a assinatura vive enquanto o `Root` estiver montado.
|
|
96
|
+
*/
|
|
97
|
+
useLayoutEffect(() => {
|
|
98
|
+
const subscription = table.store.subscribe(syncColumnLayout);
|
|
99
|
+
return () => subscription.unsubscribe();
|
|
100
|
+
}, [table.store, syncColumnLayout]);
|
|
101
|
+
return ref;
|
|
102
|
+
};
|
|
103
|
+
//#endregion
|
|
104
|
+
export { useDataTableColumnLayout };
|
|
105
|
+
|
|
106
|
+
//# sourceMappingURL=use-data-table-column-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-data-table-column-layout.js","names":[],"sources":["../../../../src/components/data-table/root/use-data-table-column-layout.ts"],"sourcesContent":["import type { RowData, TableFeatures } from '@tanstack/react-table';\nimport { useCallback, useLayoutEffect, useRef } from 'react';\nimport type { TableWith } from '../../../types';\nimport { getDataTableColumnLayout } from './get-data-table-column-layout';\nimport { getDataTableScrollParent } from './get-data-table-scroll-parent';\n\n/**\n * Sincroniza o layout das colunas com o elemento do grid, nas variáveis que as partes leem:\n *\n * - `--data-table-template`: a largura de cada coluna visível, em px, na ordem das células;\n * - `--data-table-width`: a soma delas;\n * - `--data-table-pin-<lado>-<n>`: o deslocamento de cada coluna fixada, que a célula dela lê.\n *\n * Escreve também o `scroll-padding` lateral do contêiner que rola, com a largura das fixadas de\n * cada lado: o foco que vai para um elemento coberto por uma fixada (o Tab no cabeçalho, um\n * controle numa célula) rola até ele.\n *\n * Assina o store da tabela, fora do React: quando tamanho, visibilidade, ordem ou pinning das\n * colunas mudam, só as variáveis mudam, sem render. A cada render do `Root` também sincroniza,\n * para `columns` novos, que não passam pelo store. Nos dois casos, só toca no estilo se o layout\n * mudou, e tira a variável de uma coluna que deixou de ser fixada.\n *\n * Devolve o callback ref do elemento do grid.\n */\nexport const useDataTableColumnLayout = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: TableWith<TFeatures, TData, 'columnSizingFeature'>,\n) => {\n /**\n * O elemento do grid, ligado pelo callback ref devolvido no fim.\n */\n const elementRef = useRef<HTMLDivElement | null>(null);\n\n /**\n * As variáveis aplicadas no elemento atual, pelo nome. O `syncColumnLayout` compara com elas e\n * só toca no estilo do que mudou: a maioria das mudanças do store (seleção, página) não mexe\n * nas colunas.\n */\n const lastVariablesRef = useRef<Record<string, string>>({});\n\n /**\n * O contêiner que rola, procurado uma vez ao ligar o elemento: a busca lê o estilo computado dos\n * ancestrais, e a cada tick do arrasto de uma coluna forçaria um recálculo de estilo.\n */\n const scrollParentRef = useRef<HTMLElement | undefined>(undefined);\n\n /** O `scroll-padding` lateral aplicado no contêiner, para só tocar no estilo se mudou. */\n const lastScrollPaddingRef = useRef('');\n\n /**\n * A tabela do último render. O objeto `table` é novo a cada render; lido por ref, ele não entra\n * nas dependências da assinatura, que senão seria desfeita e refeita em todo render.\n */\n const tableRef = useRef(table);\n\n /**\n * Calcula o layout e o aplica no elemento, se mudou. Chamado de três lugares: ao ligar um\n * elemento, depois de cada commit e a cada mudança do store. Lê tudo por ref, então a\n * identidade é estável e não refaz o callback ref nem a assinatura.\n */\n const syncColumnLayout = useCallback(() => {\n const element = elementRef.current;\n\n if (!element) {\n return;\n }\n\n const layout = getDataTableColumnLayout(tableRef.current);\n const variables: Record<string, string> = {\n '--data-table-template': layout.template,\n '--data-table-width': layout.width,\n ...layout.offsets,\n };\n const lastVariables = lastVariablesRef.current;\n\n for (const name of Object.keys(lastVariables)) {\n if (!(name in variables)) {\n element.style.removeProperty(name);\n }\n }\n\n for (const [name, value] of Object.entries(variables)) {\n if (lastVariables[name] !== value) {\n element.style.setProperty(name, value);\n }\n }\n\n lastVariablesRef.current = variables;\n\n const scrollParent = scrollParentRef.current;\n const scrollPadding = `${layout.scrollPadding.start} ${layout.scrollPadding.end}`;\n\n if (scrollParent && lastScrollPaddingRef.current !== scrollPadding) {\n scrollParent.style.scrollPaddingInline = scrollPadding;\n lastScrollPaddingRef.current = scrollPadding;\n }\n }, []);\n\n /**\n * Um elemento novo (outro `render`, ou um remount só do elemento) nasce sem as variáveis. O que\n * está em `lastVariablesRef` era do anterior: sem descartar, o sync acharia que nada mudou e não\n * aplicaria no novo.\n */\n const ref = useCallback(\n (element: HTMLDivElement | null) => {\n elementRef.current = element;\n lastVariablesRef.current = {};\n scrollParentRef.current = element\n ? getDataTableScrollParent(element)\n : undefined;\n lastScrollPaddingRef.current = '';\n\n syncColumnLayout();\n },\n [syncColumnLayout],\n );\n\n /**\n * Sem dependências: roda depois de todo commit do `Root`. Cobre o que muda as colunas sem passar\n * pelo store, como `columns` novos. Layout effect, e não effect, para o grid nunca pintar com o\n * template antigo.\n */\n useLayoutEffect(() => {\n tableRef.current = table;\n\n syncColumnLayout();\n });\n\n /**\n * Tamanho, visibilidade, ordem e pinning mudam pelo store, inclusive a cada tick do arrasto de\n * uma coluna: sincronizar daqui mantém tudo isso fora do React, sem render. O store é estável,\n * então a assinatura vive enquanto o `Root` estiver montado.\n */\n useLayoutEffect(() => {\n const subscription = table.store.subscribe(syncColumnLayout);\n\n return () => subscription.unsubscribe();\n }, [table.store, syncColumnLayout]);\n\n return ref;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,4BAIX,UACG;;;;CAIH,MAAM,aAAa,OAA8B,IAAI;;;;;;CAOrD,MAAM,mBAAmB,OAA+B,CAAC,CAAC;;;;;CAM1D,MAAM,kBAAkB,OAAgC,KAAA,CAAS;;CAGjE,MAAM,uBAAuB,OAAO,EAAE;;;;;CAMtC,MAAM,WAAW,OAAO,KAAK;;;;;;CAO7B,MAAM,mBAAmB,kBAAkB;EACzC,MAAM,UAAU,WAAW;EAE3B,IAAI,CAAC,SACH;EAGF,MAAM,SAAS,yBAAyB,SAAS,OAAO;EACxD,MAAM,YAAoC;GACxC,yBAAyB,OAAO;GAChC,sBAAsB,OAAO;GAC7B,GAAG,OAAO;EACZ;EACA,MAAM,gBAAgB,iBAAiB;EAEvC,KAAK,MAAM,QAAQ,OAAO,KAAK,aAAa,GAC1C,IAAI,EAAE,QAAQ,YACZ,QAAQ,MAAM,eAAe,IAAI;EAIrC,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,SAAS,GAClD,IAAI,cAAc,UAAU,OAC1B,QAAQ,MAAM,YAAY,MAAM,KAAK;EAIzC,iBAAiB,UAAU;EAE3B,MAAM,eAAe,gBAAgB;EACrC,MAAM,gBAAgB,GAAG,OAAO,cAAc,MAAM,GAAG,OAAO,cAAc;EAE5E,IAAI,gBAAgB,qBAAqB,YAAY,eAAe;GAClE,aAAa,MAAM,sBAAsB;GACzC,qBAAqB,UAAU;EACjC;CACF,GAAG,CAAC,CAAC;;;;;;CAOL,MAAM,MAAM,aACT,YAAmC;EAClC,WAAW,UAAU;EACrB,iBAAiB,UAAU,CAAC;EAC5B,gBAAgB,UAAU,UACtB,yBAAyB,OAAO,IAChC,KAAA;EACJ,qBAAqB,UAAU;EAE/B,iBAAiB;CACnB,GACA,CAAC,gBAAgB,CACnB;;;;;;CAOA,sBAAsB;EACpB,SAAS,UAAU;EAEnB,iBAAiB;CACnB,CAAC;;;;;;CAOD,sBAAsB;EACpB,MAAM,eAAe,MAAM,MAAM,UAAU,gBAAgB;EAE3D,aAAa,aAAa,YAAY;CACxC,GAAG,CAAC,MAAM,OAAO,gBAAgB,CAAC;CAElC,OAAO;AACT"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/components/data-table/root/use-data-table-header-offset.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Mede a altura do `DataTable.Header` dentro do contêiner e a escreve em
|
|
4
|
+
* `--data-table-header-offset`, no próprio contêiner. A barra de rolagem vertical lê a variável
|
|
5
|
+
* para começar abaixo do cabeçalho, que é sticky e cobriria o começo dela.
|
|
6
|
+
*
|
|
7
|
+
* Mede pelo `ResizeObserver`, fora do React: a altura muda com a densidade e com os níveis de um
|
|
8
|
+
* cabeçalho agrupado, sem render do contêiner. O cabeçalho é procurado quando o contêiner monta;
|
|
9
|
+
* um que monte depois não é medido, e a barra começa no topo.
|
|
10
|
+
*
|
|
11
|
+
* Devolve o callback ref do contêiner.
|
|
12
|
+
*/
|
|
13
|
+
export declare const useDataTableHeaderOffset: () => (element: HTMLElement | null) => void;
|
|
14
|
+
//#endregion
|
|
15
|
+
//# sourceMappingURL=use-data-table-header-offset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-data-table-header-offset.d.ts","names":[],"sources":["../../../../src/components/data-table/root/use-data-table-header-offset.ts"],"mappings":";;;;;;;;;;;;qBAgBa,iCAAwB,SAIN"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useCallback, useRef } from "react";
|
|
2
|
+
//#region src/components/data-table/root/use-data-table-header-offset.ts
|
|
3
|
+
/** O cabeçalho da tabela, pelo `data-component` que o `DataTable.Header` põe. */
|
|
4
|
+
const HEADER_SELECTOR = "[data-component=\"DataTable.Header\"]";
|
|
5
|
+
/**
|
|
6
|
+
* Mede a altura do `DataTable.Header` dentro do contêiner e a escreve em
|
|
7
|
+
* `--data-table-header-offset`, no próprio contêiner. A barra de rolagem vertical lê a variável
|
|
8
|
+
* para começar abaixo do cabeçalho, que é sticky e cobriria o começo dela.
|
|
9
|
+
*
|
|
10
|
+
* Mede pelo `ResizeObserver`, fora do React: a altura muda com a densidade e com os níveis de um
|
|
11
|
+
* cabeçalho agrupado, sem render do contêiner. O cabeçalho é procurado quando o contêiner monta;
|
|
12
|
+
* um que monte depois não é medido, e a barra começa no topo.
|
|
13
|
+
*
|
|
14
|
+
* Devolve o callback ref do contêiner.
|
|
15
|
+
*/
|
|
16
|
+
const useDataTableHeaderOffset = () => {
|
|
17
|
+
/** O observer do contêiner atual, desligado quando o elemento sai ou é trocado. */
|
|
18
|
+
const observerRef = useRef(null);
|
|
19
|
+
return useCallback((element) => {
|
|
20
|
+
observerRef.current?.disconnect();
|
|
21
|
+
observerRef.current = null;
|
|
22
|
+
const header = element?.querySelector(HEADER_SELECTOR);
|
|
23
|
+
if (!(element && header)) return;
|
|
24
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
25
|
+
const height = entry?.borderBoxSize[0]?.blockSize ?? 0;
|
|
26
|
+
element.style.setProperty("--data-table-header-offset", `${height}px`);
|
|
27
|
+
});
|
|
28
|
+
observer.observe(header);
|
|
29
|
+
observerRef.current = observer;
|
|
30
|
+
}, []);
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { useDataTableHeaderOffset };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=use-data-table-header-offset.js.map
|