@lucasbernardosn/react-table 0.2.0 → 0.3.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/README.md +1 -1
- package/dist/components/column-menu/column-menu-check.js +2 -2
- package/dist/components/column-menu/column-menu-hide-item.d.ts +1 -1
- package/dist/components/column-menu/column-menu-hide-item.js +3 -3
- package/dist/components/column-menu/column-menu-hide-item.js.map +1 -1
- package/dist/components/column-menu/column-menu-pin-items.d.ts +1 -1
- package/dist/components/column-menu/column-menu-pin-items.js +3 -3
- package/dist/components/column-menu/column-menu-pin-items.js.map +1 -1
- package/dist/components/column-menu/column-menu-popup.d.ts +1 -1
- package/dist/components/column-menu/column-menu-popup.js +3 -3
- package/dist/components/column-menu/column-menu-popup.js.map +1 -1
- package/dist/components/column-menu/column-menu-root.js.map +1 -1
- package/dist/components/column-menu/column-menu-sort-items.d.ts +2 -2
- package/dist/components/column-menu/column-menu-sort-items.js +3 -3
- package/dist/components/column-menu/column-menu-sort-items.js.map +1 -1
- package/dist/components/column-menu/column-menu-trigger.d.ts +1 -1
- package/dist/components/column-menu/column-menu-trigger.js +3 -3
- package/dist/components/column-menu/column-menu-trigger.js.map +1 -1
- package/dist/components/columns-panel/columns-panel-item.d.ts +1 -1
- package/dist/components/columns-panel/columns-panel-item.js +5 -5
- package/dist/components/columns-panel/columns-panel-item.js.map +1 -1
- package/dist/components/columns-panel/columns-panel-root.d.ts +1 -1
- package/dist/components/columns-panel/columns-panel-root.js +4 -4
- package/dist/components/columns-panel/columns-panel-root.js.map +1 -1
- package/dist/components/data-table/body/data-table-body.d.ts +1 -1
- package/dist/components/data-table/body/data-table-body.js +5 -5
- package/dist/components/data-table/body/data-table-body.js.map +1 -1
- package/dist/components/data-table/body/data-table-cell.d.ts +1 -1
- package/dist/components/data-table/body/data-table-cell.js +1 -1
- package/dist/components/data-table/body/data-table-cell.js.map +1 -1
- package/dist/components/data-table/body/data-table-empty.d.ts +1 -1
- package/dist/components/data-table/body/data-table-empty.js +3 -3
- package/dist/components/data-table/body/data-table-empty.js.map +1 -1
- package/dist/components/data-table/body/data-table-row.d.ts +1 -1
- package/dist/components/data-table/body/data-table-row.js +4 -4
- package/dist/components/data-table/body/data-table-row.js.map +1 -1
- package/dist/components/data-table/header/data-table-header-cell.d.ts +1 -1
- package/dist/components/data-table/header/data-table-header-cell.js +2 -2
- package/dist/components/data-table/header/data-table-header-cell.js.map +1 -1
- package/dist/components/data-table/header/data-table-header-content.d.ts +1 -1
- package/dist/components/data-table/header/data-table-header-content.js +1 -1
- package/dist/components/data-table/header/data-table-header-content.js.map +1 -1
- package/dist/components/data-table/header/data-table-header.d.ts +1 -1
- package/dist/components/data-table/header/data-table-header.js +4 -4
- package/dist/components/data-table/header/data-table-header.js.map +1 -1
- package/dist/components/data-table/index.parts.js +1 -1
- package/dist/components/data-table/pagination/data-table-page-button.d.ts +1 -1
- package/dist/components/data-table/pagination/data-table-page-button.js +2 -2
- package/dist/components/data-table/pagination/data-table-page-button.js.map +1 -1
- package/dist/components/data-table/pagination/data-table-page-size-select.d.ts +1 -1
- package/dist/components/data-table/pagination/data-table-page-size-select.js +2 -2
- package/dist/components/data-table/pagination/data-table-page-size-select.js.map +1 -1
- package/dist/components/data-table/pagination/data-table-page-status.d.ts +1 -1
- package/dist/components/data-table/pagination/data-table-page-status.js +1 -1
- package/dist/components/data-table/pagination/data-table-page-status.js.map +1 -1
- package/dist/components/data-table/pagination/data-table-pagination.d.ts +1 -1
- package/dist/components/data-table/pagination/data-table-pagination.js +1 -1
- package/dist/components/data-table/pagination/data-table-pagination.js.map +1 -1
- package/dist/components/data-table/pagination/data-table-row-range.d.ts +1 -1
- package/dist/components/data-table/pagination/data-table-row-range.js +1 -1
- package/dist/components/data-table/pagination/data-table-row-range.js.map +1 -1
- package/dist/components/data-table/pagination/data-table-selected-count.d.ts +1 -1
- package/dist/components/data-table/pagination/data-table-selected-count.js +1 -1
- package/dist/components/data-table/pagination/data-table-selected-count.js.map +1 -1
- package/dist/components/data-table/resize/data-table-resize-handle.d.ts +1 -1
- package/dist/components/data-table/resize/data-table-resize-handle.js +3 -3
- package/dist/components/data-table/resize/data-table-resize-handle.js.map +1 -1
- package/dist/components/data-table/root/data-table-root.d.ts +1 -1
- package/dist/components/data-table/root/data-table-root.js +1 -1
- package/dist/components/data-table/root/data-table-root.js.map +1 -1
- package/dist/components/data-table/root/data-table-scroll-area.js +1 -1
- package/dist/components/data-table/selection/data-table-row-checkbox.d.ts +1 -1
- package/dist/components/data-table/selection/data-table-row-checkbox.js +1 -1
- package/dist/components/data-table/selection/data-table-row-checkbox.js.map +1 -1
- package/dist/components/data-table/selection/data-table-select-all-checkbox.d.ts +1 -1
- package/dist/components/data-table/selection/data-table-select-all-checkbox.js +1 -1
- package/dist/components/data-table/selection/data-table-select-all-checkbox.js.map +1 -1
- package/dist/components/data-table/selection/data-table-selection-bar.d.ts +1 -1
- package/dist/components/data-table/selection/data-table-selection-bar.js +1 -1
- package/dist/components/data-table/selection/data-table-selection-bar.js.map +1 -1
- package/dist/components/data-table/sorting/data-table-sort-indicator.d.ts +1 -1
- package/dist/components/data-table/sorting/data-table-sort-indicator.js +4 -4
- package/dist/components/data-table/sorting/data-table-sort-indicator.js.map +1 -1
- package/dist/components/data-table/sorting/data-table-sort-trigger.d.ts +1 -1
- package/dist/components/data-table/sorting/data-table-sort-trigger.js +2 -2
- package/dist/components/data-table/sorting/data-table-sort-trigger.js.map +1 -1
- package/dist/components/data-table/toolbar/data-table-density-select.d.ts +1 -1
- package/dist/components/data-table/toolbar/data-table-density-select.js +1 -1
- package/dist/components/data-table/toolbar/data-table-density-select.js.map +1 -1
- package/dist/components/data-table/toolbar/data-table-sort-column-select.d.ts +1 -1
- package/dist/components/data-table/toolbar/data-table-sort-column-select.js +1 -1
- package/dist/components/data-table/toolbar/data-table-sort-column-select.js.map +1 -1
- package/dist/components/data-table/toolbar/data-table-sort-direction-select.d.ts +1 -1
- package/dist/components/data-table/toolbar/data-table-sort-direction-select.js +1 -1
- package/dist/components/data-table/toolbar/data-table-sort-direction-select.js.map +1 -1
- package/package.json +12 -10
- package/dist/components/column-menu/column-menu-check.d.ts.map +0 -1
- package/dist/components/column-menu/column-menu-hide-item.d.ts.map +0 -1
- package/dist/components/column-menu/column-menu-labels.d.ts.map +0 -1
- package/dist/components/column-menu/column-menu-pin-items.d.ts.map +0 -1
- package/dist/components/column-menu/column-menu-popup.d.ts.map +0 -1
- package/dist/components/column-menu/column-menu-root.d.ts.map +0 -1
- package/dist/components/column-menu/column-menu-sort-items.d.ts.map +0 -1
- package/dist/components/column-menu/column-menu-trigger.d.ts.map +0 -1
- package/dist/components/column-menu/index.parts.d.ts.map +0 -1
- package/dist/components/columns-panel/columns-panel-item.d.ts.map +0 -1
- package/dist/components/columns-panel/columns-panel-root.d.ts.map +0 -1
- package/dist/components/columns-panel/get-columns-panel-column-order.d.ts.map +0 -1
- package/dist/components/columns-panel/index.parts.d.ts.map +0 -1
- package/dist/components/data-table/body/data-table-body.d.ts.map +0 -1
- package/dist/components/data-table/body/data-table-cell.d.ts.map +0 -1
- package/dist/components/data-table/body/data-table-empty.d.ts.map +0 -1
- package/dist/components/data-table/body/data-table-row-focus.d.ts.map +0 -1
- package/dist/components/data-table/body/data-table-row.d.ts.map +0 -1
- package/dist/components/data-table/body/use-data-table-row-focus-recovery.d.ts.map +0 -1
- package/dist/components/data-table/header/data-table-header-button.d.ts.map +0 -1
- package/dist/components/data-table/header/data-table-header-cell.d.ts.map +0 -1
- package/dist/components/data-table/header/data-table-header-content.d.ts.map +0 -1
- package/dist/components/data-table/header/data-table-header-row.d.ts.map +0 -1
- package/dist/components/data-table/header/data-table-header.d.ts.map +0 -1
- package/dist/components/data-table/index.parts.d.ts.map +0 -1
- package/dist/components/data-table/loading/get-data-table-loading-without-rows.d.ts.map +0 -1
- package/dist/components/data-table/loading/use-data-table-loading-inert.d.ts.map +0 -1
- package/dist/components/data-table/loading/use-data-table-loading.d.ts.map +0 -1
- package/dist/components/data-table/pagination/data-table-page-button.d.ts.map +0 -1
- package/dist/components/data-table/pagination/data-table-page-size-select.d.ts.map +0 -1
- package/dist/components/data-table/pagination/data-table-page-status.d.ts.map +0 -1
- package/dist/components/data-table/pagination/data-table-pagination.d.ts.map +0 -1
- package/dist/components/data-table/pagination/data-table-row-range.d.ts.map +0 -1
- package/dist/components/data-table/pagination/data-table-selected-count.d.ts.map +0 -1
- package/dist/components/data-table/pagination/use-data-table-page-scroll-reset.d.ts.map +0 -1
- package/dist/components/data-table/resize/data-table-resize-handle.d.ts.map +0 -1
- package/dist/components/data-table/resize/use-data-table-resize-scroll.d.ts.map +0 -1
- package/dist/components/data-table/root/data-table-grid-class-names.d.ts.map +0 -1
- package/dist/components/data-table/root/data-table-root.d.ts.map +0 -1
- package/dist/components/data-table/root/data-table-scroll-area.d.ts.map +0 -1
- package/dist/components/data-table/root/get-data-table-column-layout.d.ts.map +0 -1
- package/dist/components/data-table/root/get-data-table-column-pinning.d.ts.map +0 -1
- package/dist/components/data-table/root/get-data-table-scroll-parent.d.ts.map +0 -1
- package/dist/components/data-table/root/use-data-table-column-layout.d.ts.map +0 -1
- package/dist/components/data-table/root/use-data-table-header-offset.d.ts.map +0 -1
- package/dist/components/data-table/selection/data-table-row-checkbox.d.ts.map +0 -1
- package/dist/components/data-table/selection/data-table-select-all-checkbox.d.ts.map +0 -1
- package/dist/components/data-table/selection/data-table-selection-bar.d.ts.map +0 -1
- package/dist/components/data-table/selection/selection-column-def.d.ts.map +0 -1
- package/dist/components/data-table/sorting/data-table-sort-indicator.d.ts.map +0 -1
- package/dist/components/data-table/sorting/data-table-sort-trigger.d.ts.map +0 -1
- package/dist/components/data-table/toolbar/data-table-density-select.d.ts.map +0 -1
- package/dist/components/data-table/toolbar/data-table-sort-column-select.d.ts.map +0 -1
- package/dist/components/data-table/toolbar/data-table-sort-direction-select.d.ts.map +0 -1
- package/dist/features/active-row/active-row-feature.d.ts.map +0 -1
- package/dist/features/active-row/active-row-feature.types.d.ts.map +0 -1
- package/dist/features/column-alignment/column-alignment-feature.d.ts.map +0 -1
- package/dist/features/column-alignment/column-alignment-feature.types.d.ts.map +0 -1
- package/dist/features/loading/loading-feature.d.ts.map +0 -1
- package/dist/features/loading/loading-feature.types.d.ts.map +0 -1
- package/dist/features/row-density/row-density-feature.d.ts.map +0 -1
- package/dist/features/row-density/row-density-feature.types.d.ts.map +0 -1
- package/dist/types/table-with.d.ts.map +0 -1
- package/dist/utils/get-default-column-label.d.ts.map +0 -1
- package/dist/utils/has-feature.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-cell.js","names":[],"sources":["../../../../src/components/data-table/body/data-table-cell.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport {\n type Cell,\n FlexRender,\n type RowData,\n type TableFeatures,\n} from '@tanstack/react-table';\nimport { hasColumnFeature, hasTableFeature } from '../../../utils';\nimport {\n getDataTableColumnPinning,\n getDataTablePinnedStyle,\n} from '../root/get-data-table-column-pinning';\n\nexport type DataTableCellProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** A célula da linha. */\n cell: Cell<TFeatures, TData>;\n }\n>;\n\n/**\n * Uma célula do corpo (`role=\"cell\"`). Sem `children`, mostra o `cell` da definição da coluna;\n * com eles, mostra os `children`.\n *\n * Trunca o texto com reticências. Para arrumar o conteúdo em linha, como texto com ícone, passe\n * `className=\"flex items-center gap-2\"` e trunque o texto por conta própria.\n *\n * Com `columnAlignmentFeature`, alinha o conteúdo pelo `align` da coluna e o marca em\n * `data-align`. Com `columnPinningFeature`, numa coluna fixada, gruda na borda do lado dela,\n * marcada com `data-pinned`, e repete o fundo da `DataTable.Row` para cobrir o que rola por\n * baixo.\n */\nexport const DataTableCell = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableCellProps<TFeatures, TData>,\n) => {\n const { cell, render, className, children, ...rest } = props;\n\n /**\n * Sem assinatura: o alinhamento vem da definição da coluna, que não muda em runtime. Uma troca\n * das colunas muda as células, e a `DataTable.Row` re-renderiza, com a célula junto.\n */\n const align = hasColumnFeature(cell.column, 'columnAlignmentFeature')\n ? cell.column.getAlign()\n : undefined;\n\n /**\n * Sem assinatura: o pinning muda as células da linha, e a `DataTable.Row` re-renderiza, com a\n * célula junto. O deslocamento muda no resize, mas fica na variável que o `DataTable.Root`\n * escreve.\n */\n const pinning = getDataTableColumnPinning(cell.column);\n\n const baseProps = {\n 'data-component': 'DataTable.Cell',\n 'data-align': align,\n 'data-pinned': pinning.position || undefined,\n // Dentro do `grid` do `DataTable.Root`, que a navegação por teclado liga, a célula é `gridcell`.\n role: hasTableFeature(cell.table, 'activeRowFeature') ? 'gridcell' : 'cell',\n style: getDataTablePinnedStyle(pinning),\n className: mergeTwClassNames(\n [\n // Bloco, e não flex: só num bloco o texto ganha reticências. O `content-center` centraliza\n // na vertical.\n 'block',\n 'content-center',\n // Item de grid tem `min-width: auto`: sem isto, um conteúdo longo alarga o track, e a\n // coluna deixa de bater com o template.\n 'min-w-0',\n 'truncate',\n\n // Pelo `text-align`: a célula é bloco, e o conteúdo em linha, como o checkbox, segue.\n 'data-[align=center]:text-center',\n 'data-[align=end]:text-end',\n\n // Do `DataTable.Root`, pela densidade.\n 'h-(--data-table-row-height)',\n\n 'px-(--data-table-cell-padding)',\n\n // Fixada: gruda por cima das células do centro, e o fundo da linha a deixa opaca.\n 'data-pinned:sticky',\n 'data-pinned:z-1',\n 'data-pinned:bg-(--data-table-row-background)',\n // Sombra na borda da fixada, do lado em que o centro passa por baixo: na última do início e\n // na primeira do fim. Mais forte no escuro, onde a do claro sumiria no fundo.\n 'data-[pinned=start]:has-[+:not([data-pinned=start])]:shadow-[6px_0_8px_-6px_rgb(0_0_0/0.12)]',\n 'dark:data-[pinned=start]:has-[+:not([data-pinned=start])]:shadow-[6px_0_8px_-6px_rgb(0_0_0/0.8)]',\n 'data-[pinned=end]:not-[[data-pinned=end]+*]:shadow-[-6px_0_8px_-6px_rgb(0_0_0/0.12)]',\n 'dark:data-[pinned=end]:not-[[data-pinned=end]+*]:shadow-[-6px_0_8px_-6px_rgb(0_0_0/0.8)]',\n\n // A cor do texto vem da `DataTable.Row`, para a cor que o app puser na linha chegar aqui.\n 'text-sm',\n\n // Carregamento (`data-loading` no `DataTable.Root`): o conteúdo some\n // sem a célula mudar de tamanho, e um bloco com as classes do `Skeleton` do `ui` ocupa o\n // lugar, alinhado como o conteúdo. Por CSS, para as células não re-renderizarem a cada\n // carga. O texto vai a 0px, e não a transparente: senão empurraria o bloco no `center`.\n 'in-data-loading:text-[0px]',\n 'in-data-loading:*:hidden',\n \"in-data-loading:before:content-['']\",\n 'in-data-loading:before:inline-block',\n 'in-data-loading:before:align-middle',\n 'in-data-loading:before:h-3',\n 'in-data-loading:before:w-3/4',\n 'in-data-loading:before:rounded-md',\n 'in-data-loading:before:corner-squircle',\n 'in-data-loading:before:bg-gray-6',\n 'in-data-loading:before:not-motion-reduced:animate-skeleton-pulse',\n ],\n className,\n ),\n children: children === undefined ? <FlexRender cell={cell} /> : children,\n };\n\n return useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableCell.displayName = 'DataTable.Cell';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsCA,MAAa,iBAIX,UACG;CACH,MAAM,EAAE,MAAM,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;CAMvD,MAAM,QAAQ,iBAAiB,KAAK,QAAQ,wBAAwB,IAChE,KAAK,OAAO,SAAS,IACrB,KAAA;;;;;;CAOJ,MAAM,UAAU,0BAA0B,KAAK,MAAM;CAErD,MAAM,YAAY;EAChB,kBAAkB;EAClB,cAAc;EACd,eAAe,QAAQ,YAAY,KAAA;EAEnC,MAAM,gBAAgB,KAAK,OAAO,kBAAkB,IAAI,aAAa;EACrE,OAAO,wBAAwB,OAAO;EACtC,WAAW,kBACT;GAGE;GACA;GAGA;GACA;GAGA;GACA;GAGA;GAEA;GAGA;GACA;GACA;GAGA;GACA;GACA;GACA;GAGA;GAMA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,GACA,SACF;EACA,UAAU,aAAa,KAAA,IAAY,oBAAC,YAAD,EAAkB,KAAO,CAAA,IAAI;CAClE;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,cAAc,cAAc"}
|
|
1
|
+
{"version":3,"file":"data-table-cell.js","names":[],"sources":["../../../../src/components/data-table/body/data-table-cell.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport {\n type Cell,\n FlexRender,\n type RowData,\n type TableFeatures,\n} from '@tanstack/react-table';\nimport { hasColumnFeature, hasTableFeature } from '../../../utils';\nimport {\n getDataTableColumnPinning,\n getDataTablePinnedStyle,\n} from '../root/get-data-table-column-pinning';\n\nexport type DataTableCellProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** A célula da linha. */\n cell: Cell<TFeatures, TData>;\n }\n>;\n\n/**\n * Uma célula do corpo (`role=\"cell\"`). Sem `children`, mostra o `cell` da definição da coluna;\n * com eles, mostra os `children`.\n *\n * Trunca o texto com reticências. Para arrumar o conteúdo em linha, como texto com ícone, passe\n * `className=\"flex items-center gap-2\"` e trunque o texto por conta própria.\n *\n * Com `columnAlignmentFeature`, alinha o conteúdo pelo `align` da coluna e o marca em\n * `data-align`. Com `columnPinningFeature`, numa coluna fixada, gruda na borda do lado dela,\n * marcada com `data-pinned`, e repete o fundo da `DataTable.Row` para cobrir o que rola por\n * baixo.\n */\nexport const DataTableCell = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableCellProps<TFeatures, TData>,\n) => {\n const { cell, render, className, children, ...rest } = props;\n\n /**\n * Sem assinatura: o alinhamento vem da definição da coluna, que não muda em runtime. Uma troca\n * das colunas muda as células, e a `DataTable.Row` re-renderiza, com a célula junto.\n */\n const align = hasColumnFeature(cell.column, 'columnAlignmentFeature')\n ? cell.column.getAlign()\n : undefined;\n\n /**\n * Sem assinatura: o pinning muda as células da linha, e a `DataTable.Row` re-renderiza, com a\n * célula junto. O deslocamento muda no resize, mas fica na variável que o `DataTable.Root`\n * escreve.\n */\n const pinning = getDataTableColumnPinning(cell.column);\n\n const baseProps = {\n 'data-component': 'DataTable.Cell',\n 'data-align': align,\n 'data-pinned': pinning.position || undefined,\n // Dentro do `grid` do `DataTable.Root`, que a navegação por teclado liga, a célula é `gridcell`.\n role: hasTableFeature(cell.table, 'activeRowFeature') ? 'gridcell' : 'cell',\n style: getDataTablePinnedStyle(pinning),\n className: mergeTwClassNames(\n [\n // Bloco, e não flex: só num bloco o texto ganha reticências. O `content-center` centraliza\n // na vertical.\n 'block',\n 'content-center',\n // Item de grid tem `min-width: auto`: sem isto, um conteúdo longo alarga o track, e a\n // coluna deixa de bater com o template.\n 'min-w-0',\n 'truncate',\n\n // Pelo `text-align`: a célula é bloco, e o conteúdo em linha, como o checkbox, segue.\n 'data-[align=center]:text-center',\n 'data-[align=end]:text-end',\n\n // Do `DataTable.Root`, pela densidade.\n 'h-(--data-table-row-height)',\n\n 'px-(--data-table-cell-padding)',\n\n // Fixada: gruda por cima das células do centro, e o fundo da linha a deixa opaca.\n 'data-pinned:sticky',\n 'data-pinned:z-1',\n 'data-pinned:bg-(--data-table-row-background)',\n // Sombra na borda da fixada, do lado em que o centro passa por baixo: na última do início e\n // na primeira do fim. Mais forte no escuro, onde a do claro sumiria no fundo.\n 'data-[pinned=start]:has-[+:not([data-pinned=start])]:shadow-[6px_0_8px_-6px_rgb(0_0_0/0.12)]',\n 'dark:data-[pinned=start]:has-[+:not([data-pinned=start])]:shadow-[6px_0_8px_-6px_rgb(0_0_0/0.8)]',\n 'data-[pinned=end]:not-[[data-pinned=end]+*]:shadow-[-6px_0_8px_-6px_rgb(0_0_0/0.12)]',\n 'dark:data-[pinned=end]:not-[[data-pinned=end]+*]:shadow-[-6px_0_8px_-6px_rgb(0_0_0/0.8)]',\n\n // A cor do texto vem da `DataTable.Row`, para a cor que o app puser na linha chegar aqui.\n 'text-sm',\n\n // Carregamento (`data-loading` no `DataTable.Root`): o conteúdo some\n // sem a célula mudar de tamanho, e um bloco com as classes do `Skeleton` do `ui` ocupa o\n // lugar, alinhado como o conteúdo. Por CSS, para as células não re-renderizarem a cada\n // carga. O texto vai a 0px, e não a transparente: senão empurraria o bloco no `center`.\n 'in-data-loading:text-[0px]',\n 'in-data-loading:*:hidden',\n \"in-data-loading:before:content-['']\",\n 'in-data-loading:before:inline-block',\n 'in-data-loading:before:align-middle',\n 'in-data-loading:before:h-3',\n 'in-data-loading:before:w-3/4',\n 'in-data-loading:before:rounded-md',\n 'in-data-loading:before:corner-squircle',\n 'in-data-loading:before:bg-gray-6',\n 'in-data-loading:before:not-motion-reduced:animate-skeleton-pulse',\n ],\n className,\n ),\n children: children === undefined ? <FlexRender cell={cell} /> : children,\n };\n\n return useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableCell.displayName = 'DataTable.Cell';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsCA,MAAa,iBAIX,UACG;CACH,MAAM,EAAE,MAAM,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;CAMvD,MAAM,QAAQ,iBAAiB,KAAK,QAAQ,wBAAwB,IAChE,KAAK,OAAO,SAAS,IACrB,KAAA;;;;;;CAOJ,MAAM,UAAU,0BAA0B,KAAK,MAAM;CAErD,MAAM,YAAY;EAChB,kBAAkB;EAClB,cAAc;EACd,eAAe,QAAQ,YAAY,KAAA;EAEnC,MAAM,gBAAgB,KAAK,OAAO,kBAAkB,IAAI,aAAa;EACrE,OAAO,wBAAwB,OAAO;EACtC,WAAW,kBACT;GAGE;GACA;GAGA;GACA;GAGA;GACA;GAGA;GAEA;GAGA;GACA;GACA;GAGA;GACA;GACA;GACA;GAGA;GAMA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,GACA,SACF;EACA,UAAU,aAAa,KAAA,IAAY,oBAAC,YAAD,EAAkB,KAAO,CAAA,IAAI;CAClE;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,cAAc,cAAc"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RowData, Table, TableFeatures } from "@tanstack/react-table";
|
|
2
2
|
import { useRender } from "@base-ui/react";
|
|
3
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
3
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
4
4
|
//#region src/components/data-table/body/data-table-empty.d.ts
|
|
5
5
|
export type DataTableEmptyProps<TFeatures extends TableFeatures, TData extends RowData> = MergeOverride<useRender.ComponentProps<'div'>, {
|
|
6
6
|
/** A tabela do `useTable`. */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { hasTableFeature } from "../../../utils/has-feature.js";
|
|
2
|
-
import { TrayIcon } from "@phosphor-icons/react";
|
|
3
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
2
|
import { mergeProps, useRender } from "@base-ui/react";
|
|
5
|
-
import { useSelector } from "@tanstack/react-store";
|
|
6
3
|
import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
|
|
4
|
+
import { useSelector } from "@tanstack/react-store";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
6
|
import { EmptyState } from "@lucasbernardosn/react-ui/feedback/empty-state";
|
|
7
|
+
import { TrayIcon } from "@phosphor-icons/react";
|
|
8
8
|
//#region src/components/data-table/body/data-table-empty.tsx
|
|
9
9
|
/**
|
|
10
10
|
* O estado vazio da tabela, para depois do `DataTable.Body`, dentro do `DataTable.Root`. Aparece
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-empty.js","names":[],"sources":["../../../../src/components/data-table/body/data-table-empty.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { EmptyState } from '@lucasbernardosn/react-ui/feedback/empty-state';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport { TrayIcon } from '@phosphor-icons/react';\nimport { useSelector } from '@tanstack/react-store';\nimport type { RowData, Table, TableFeatures } from '@tanstack/react-table';\nimport { hasTableFeature } from '../../../utils';\n\nexport type DataTableEmptyProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** A tabela do `useTable`. */\n table: Table<TFeatures, TData>;\n }\n>;\n\n/**\n * O estado vazio da tabela, para depois do `DataTable.Body`, dentro do `DataTable.Root`. Aparece\n * quando o row model não tem linhas e a tabela não está carregando: com `loadingFeature`, a carga\n * sem linhas mostra as linhas-fantasma do corpo, e não o vazio.\n *\n * Sem `children`, mostra o `EmptyState` do `ui`, sem moldura, com \"Nenhum registro encontrado\"\n * e uma descrição que sugere ajustar os filtros. Com `children`, o conteúdo do app, como uma\n * mensagem do filtro e um botão para limpá-lo. Fica centralizado na largura da tabela.\n *\n * @example\n * ```tsx\n * <DataTable.Root table={table}>\n * <DataTable.Header table={table} />\n * <DataTable.Body table={table} />\n * <DataTable.Empty table={table}>\n * <EmptyState.Root variant=\"plain\">\n * <EmptyState.Content>\n * <EmptyState.Title>Nenhum cliente para este filtro</EmptyState.Title>\n * </EmptyState.Content>\n * </EmptyState.Root>\n * </DataTable.Empty>\n * </DataTable.Root>\n * ```\n */\nexport const DataTableEmpty = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableEmptyProps<TFeatures, TData>,\n) => {\n const { table, render, className, children, ...rest } = props;\n\n /**\n * Re-renderiza quando a tabela fica vazia ou deixa de ficar. O store: as linhas mudam com os\n * dados, e o carregamento, com a feature opcional.\n */\n const isEmpty = useSelector(\n table.store,\n () =>\n table.getRowModel().rows.length === 0 &&\n !(\n hasTableFeature(table, 'loadingFeature') && table.atoms.isLoading.get()\n ),\n );\n\n /** Dentro do `grid` do `DataTable.Root`, que a navegação por teclado liga, a célula é `gridcell`. */\n const cellRole = hasTableFeature(table, 'activeRowFeature')\n ? 'gridcell'\n : 'cell';\n\n const baseProps = {\n 'data-component': 'DataTable.Empty',\n // Uma linha com uma célula: dentro de `table` e `grid`, o ARIA só aceita linhas.\n role: 'row',\n className: mergeTwClassNames(['py-8'], className),\n children: (\n <div role={cellRole}>\n {children === undefined ? (\n <EmptyState.Root variant=\"plain\">\n <EmptyState.Indicator className=\"text-gray-11\">\n <TrayIcon />\n </EmptyState.Indicator>\n\n <EmptyState.Content>\n <EmptyState.Title className=\"text-gray-11\">\n Nenhum registro encontrado\n </EmptyState.Title>\n <EmptyState.Description>\n Não há registros para mostrar. Se houver filtros aplicados,\n tente ajustá-los.\n </EmptyState.Description>\n </EmptyState.Content>\n </EmptyState.Root>\n ) : (\n children\n )}\n </div>\n ),\n };\n\n const element = useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n\n return isEmpty ? element : null;\n};\n\nDataTableEmpty.displayName = 'DataTable.Empty';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,MAAa,kBAIX,UACG;CACH,MAAM,EAAE,OAAO,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;CAMxD,MAAM,UAAU,YACd,MAAM,aAEJ,MAAM,YAAY,CAAC,CAAC,KAAK,WAAW,KACpC,EACE,gBAAgB,OAAO,gBAAgB,KAAK,MAAM,MAAM,UAAU,IAAI,EAE5E;;CAGA,MAAM,WAAW,gBAAgB,OAAO,kBAAkB,IACtD,aACA;CAEJ,MAAM,YAAY;EAChB,kBAAkB;EAElB,MAAM;EACN,WAAW,kBAAkB,CAAC,MAAM,GAAG,SAAS;EAChD,UACE,oBAAC,OAAD;GAAK,MAAM;GACR,UAAA,aAAa,KAAA,IACZ,qBAAC,WAAW,MAAZ;IAAiB,SAAQ;IAAzB,UAAA,CACE,oBAAC,WAAW,WAAZ;KAAsB,WAAU;KAC9B,UAAA,oBAAC,UAAD,CAAW,CAAA;IACS,CAAA,GAEtB,qBAAC,WAAW,SAAZ,EAAA,UAAA,CACE,oBAAC,WAAW,OAAZ;KAAkB,WAAU;KAAe,UAAA;IAEzB,CAAA,GAClB,oBAAC,WAAW,aAAZ,EAAA,UAAwB,gFAGA,CAAA,CACN,EAAA,CAAA,CACL;GAEjB,CAAA,IAAA;EAEC,CAAA;CAET;CAEA,MAAM,UAAU,UAAU;EACxB;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;CAED,OAAO,UAAU,UAAU;AAC7B;AAEA,eAAe,cAAc"}
|
|
1
|
+
{"version":3,"file":"data-table-empty.js","names":[],"sources":["../../../../src/components/data-table/body/data-table-empty.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { EmptyState } from '@lucasbernardosn/react-ui/feedback/empty-state';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport { TrayIcon } from '@phosphor-icons/react';\nimport { useSelector } from '@tanstack/react-store';\nimport type { RowData, Table, TableFeatures } from '@tanstack/react-table';\nimport { hasTableFeature } from '../../../utils';\n\nexport type DataTableEmptyProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** A tabela do `useTable`. */\n table: Table<TFeatures, TData>;\n }\n>;\n\n/**\n * O estado vazio da tabela, para depois do `DataTable.Body`, dentro do `DataTable.Root`. Aparece\n * quando o row model não tem linhas e a tabela não está carregando: com `loadingFeature`, a carga\n * sem linhas mostra as linhas-fantasma do corpo, e não o vazio.\n *\n * Sem `children`, mostra o `EmptyState` do `ui`, sem moldura, com \"Nenhum registro encontrado\"\n * e uma descrição que sugere ajustar os filtros. Com `children`, o conteúdo do app, como uma\n * mensagem do filtro e um botão para limpá-lo. Fica centralizado na largura da tabela.\n *\n * @example\n * ```tsx\n * <DataTable.Root table={table}>\n * <DataTable.Header table={table} />\n * <DataTable.Body table={table} />\n * <DataTable.Empty table={table}>\n * <EmptyState.Root variant=\"plain\">\n * <EmptyState.Content>\n * <EmptyState.Title>Nenhum cliente para este filtro</EmptyState.Title>\n * </EmptyState.Content>\n * </EmptyState.Root>\n * </DataTable.Empty>\n * </DataTable.Root>\n * ```\n */\nexport const DataTableEmpty = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableEmptyProps<TFeatures, TData>,\n) => {\n const { table, render, className, children, ...rest } = props;\n\n /**\n * Re-renderiza quando a tabela fica vazia ou deixa de ficar. O store: as linhas mudam com os\n * dados, e o carregamento, com a feature opcional.\n */\n const isEmpty = useSelector(\n table.store,\n () =>\n table.getRowModel().rows.length === 0 &&\n !(\n hasTableFeature(table, 'loadingFeature') && table.atoms.isLoading.get()\n ),\n );\n\n /** Dentro do `grid` do `DataTable.Root`, que a navegação por teclado liga, a célula é `gridcell`. */\n const cellRole = hasTableFeature(table, 'activeRowFeature')\n ? 'gridcell'\n : 'cell';\n\n const baseProps = {\n 'data-component': 'DataTable.Empty',\n // Uma linha com uma célula: dentro de `table` e `grid`, o ARIA só aceita linhas.\n role: 'row',\n className: mergeTwClassNames(['py-8'], className),\n children: (\n <div role={cellRole}>\n {children === undefined ? (\n <EmptyState.Root variant=\"plain\">\n <EmptyState.Indicator className=\"text-gray-11\">\n <TrayIcon />\n </EmptyState.Indicator>\n\n <EmptyState.Content>\n <EmptyState.Title className=\"text-gray-11\">\n Nenhum registro encontrado\n </EmptyState.Title>\n <EmptyState.Description>\n Não há registros para mostrar. Se houver filtros aplicados,\n tente ajustá-los.\n </EmptyState.Description>\n </EmptyState.Content>\n </EmptyState.Root>\n ) : (\n children\n )}\n </div>\n ),\n };\n\n const element = useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n\n return isEmpty ? element : null;\n};\n\nDataTableEmpty.displayName = 'DataTable.Empty';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,MAAa,kBAIX,UACG;CACH,MAAM,EAAE,OAAO,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;CAMxD,MAAM,UAAU,YACd,MAAM,aAEJ,MAAM,YAAY,CAAC,CAAC,KAAK,WAAW,KACpC,EACE,gBAAgB,OAAO,gBAAgB,KAAK,MAAM,MAAM,UAAU,IAAI,EAE5E;;CAGA,MAAM,WAAW,gBAAgB,OAAO,kBAAkB,IACtD,aACA;CAEJ,MAAM,YAAY;EAChB,kBAAkB;EAElB,MAAM;EACN,WAAW,kBAAkB,CAAC,MAAM,GAAG,SAAS;EAChD,UACE,oBAAC,OAAD;GAAK,MAAM;GACR,UAAA,aAAa,KAAA,IACZ,qBAAC,WAAW,MAAZ;IAAiB,SAAQ;IAAzB,UAAA,CACE,oBAAC,WAAW,WAAZ;KAAsB,WAAU;KAC9B,UAAA,oBAAC,UAAD,CAAW,CAAA;IACS,CAAA,GAEtB,qBAAC,WAAW,SAAZ,EAAA,UAAA,CACE,oBAAC,WAAW,OAAZ;KAAkB,WAAU;KAAe,UAAA;IAEzB,CAAA,GAClB,oBAAC,WAAW,aAAZ,EAAA,UAAwB,gFAGA,CAAA,CACN,EAAA,CAAA,CACL;GAEjB,CAAA,IAAA;EAEC,CAAA;CAET;CAEA,MAAM,UAAU,UAAU;EACxB;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;CAED,OAAO,UAAU,UAAU;AAC7B;AAEA,eAAe,cAAc"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Cell, Row, RowData, TableFeatures } from "@tanstack/react-table";
|
|
2
2
|
import { useRender } from "@base-ui/react";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
4
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
5
5
|
//#region src/components/data-table/body/data-table-row.d.ts
|
|
6
6
|
export type DataTableRowProps<TFeatures extends TableFeatures, TData extends RowData> = MergeOverride<useRender.ComponentProps<'div'>, {
|
|
7
7
|
/** A linha do row model. */
|
|
@@ -2,11 +2,11 @@ import { hasRowFeature } from "../../../utils/has-feature.js";
|
|
|
2
2
|
import { focusDataTableRow, getDataTableRowKeyTarget } from "./data-table-row-focus.js";
|
|
3
3
|
import { dataTableGridClassNames } from "../root/data-table-grid-class-names.js";
|
|
4
4
|
import { DataTableCell } from "./data-table-cell.js";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
6
5
|
import { mergeProps, useRender } from "@base-ui/react";
|
|
7
|
-
import { shallow, useSelector } from "@tanstack/react-store";
|
|
8
6
|
import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
|
|
9
|
-
import {
|
|
7
|
+
import { shallow, useSelector } from "@tanstack/react-store";
|
|
8
|
+
import { Fragment } from "react";
|
|
9
|
+
import { jsx } from "react/jsx-runtime";
|
|
10
10
|
//#region src/components/data-table/body/data-table-row.tsx
|
|
11
11
|
/**
|
|
12
12
|
* Uma linha do corpo (`role="row"`). É um grid com as colunas do `--data-table-template`, que o
|
|
@@ -105,7 +105,7 @@ const DataTableRow = (props) => {
|
|
|
105
105
|
};
|
|
106
106
|
const isNavigable = hasRowFeature(row, "activeRowFeature");
|
|
107
107
|
/** Com render-prop ou sem `children`, o laço é daqui; com nós comuns, de quem usa. */
|
|
108
|
-
const content = typeof children === "function" || children === void 0 ? cells.map((cell) => /* @__PURE__ */ jsx(Fragment
|
|
108
|
+
const content = typeof children === "function" || children === void 0 ? cells.map((cell) => /* @__PURE__ */ jsx(Fragment, { children: children === void 0 ? /* @__PURE__ */ jsx(DataTableCell, { cell }) : children(cell) }, cell.id)) : children;
|
|
109
109
|
const baseProps = {
|
|
110
110
|
"data-component": "DataTable.Row",
|
|
111
111
|
"data-selected": isSelected ? "" : void 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-row.js","names":["Fragment"],"sources":["../../../../src/components/data-table/body/data-table-row.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport { shallow, useSelector } from '@tanstack/react-store';\nimport type { Cell, Row, RowData, TableFeatures } from '@tanstack/react-table';\nimport type React from 'react';\nimport { Fragment } from 'react';\nimport { hasRowFeature } from '../../../utils';\nimport { dataTableGridClassNames } from '../root/data-table-grid-class-names';\nimport { DataTableCell } from './data-table-cell';\nimport {\n focusDataTableRow,\n getDataTableRowKeyTarget,\n} from './data-table-row-focus';\n\nexport type DataTableRowProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** A linha do row model. */\n row: Row<TFeatures, TData>;\n /**\n * Uma função que recebe cada célula visível e devolve o elemento dela. Com nós comuns, quem\n * usa faz o laço.\n * @default (cell) => <DataTable.Cell cell={cell} />\n */\n children?:\n | React.ReactNode\n | ((cell: Cell<TFeatures, TData>) => React.ReactNode);\n }\n>;\n\n/**\n * Uma linha do corpo (`role=\"row\"`). É um grid com as colunas do `--data-table-template`, que o\n * `DataTable.Root` escreve.\n *\n * Com render-prop ou sem `children`, faz o laço das células sozinha: assina as próprias células e\n * re-renderiza quando a ordem, a visibilidade ou o pinning das colunas mudam, que não mudam o row\n * model e não passam pelo `DataTable.Body`. Com `columnVisibilityFeature`, são as células\n * visíveis; sem ela, todas. Com `columnPinningFeature`, vêm na ordem das regiões: as fixadas no\n * início, as do centro e as fixadas no fim.\n *\n * Com `rowSelectionFeature`, a linha selecionada ganha `data-selected` e o fundo destacado, e com\n * `activeRowFeature`, também o `aria-selected`. O clique na linha não seleciona: o `onClick` fica\n * livre, e a seleção é do `DataTable.RowCheckbox` e do Espaço.\n *\n * Com `activeRowFeature`, entra na navegação por teclado. A linha ativa tem o ponto de Tab (sem\n * ela no row model, a primeira), e receber o foco, pelo teclado ou pelo clique, torna esta a\n * ativa, marcada com `data-active`. ↑↓, Home, End, PageUp e PageDown movem o foco entre as\n * linhas, e o Espaço alterna a seleção, com Shift para o intervalo. Os atalhos são do app, no\n * `onKeyDown`, que roda antes: um `preventDefault()` cancela o da linha. Num campo de texto de\n * dentro, as setas ficam com o campo.\n *\n * O fundo fica na variável `--data-table-row-background`, que as células fixadas repetem: o\n * hover a troca para `gray-2`, a selecionada para `gray-3`, e as duas juntas, para `gray-4`. Para\n * colorir uma linha, troque a variável, e não use `bg-*`, que deixaria as fixadas com a cor\n * antiga. A cor do texto fica na linha, e as células herdam.\n *\n * @example\n * ```tsx\n * <DataTable.Row\n * row={row}\n * onClick={() => openCustomer(row.original)}\n * onKeyDown={(event) => {\n * if (event.key === 'Enter') {\n * openCustomer(row.original);\n * }\n * }}\n * className={\n * row.original.overdue\n * ? '[--data-table-row-background:var(--color-gray-2)] text-gray-11'\n * : undefined\n * }\n * >\n * {(cell) => <DataTable.Cell cell={cell} />}\n * </DataTable.Row>\n * ```\n */\nexport const DataTableRow = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableRowProps<TFeatures, TData>,\n) => {\n const { row, render, className, children, ...rest } = props;\n\n /**\n * As listas que o TanStack memoiza, numa tupla: o `shallow` compara item a item, e só\n * re-renderiza quando uma delas muda com as colunas. Todas seguem a ordem dos headers folha, que\n * é a do template, e as células caem nos tracks certos. Com pinning, as três regiões, que\n * ordenam as fixadas mesmo sem `columnVisibilityFeature`.\n */\n const cellGroups = useSelector(\n row.table.store,\n () =>\n hasRowFeature(row, 'columnPinningFeature')\n ? [\n row.getStartVisibleCells(),\n row.getCenterVisibleCells(),\n row.getEndVisibleCells(),\n ]\n : hasRowFeature(row, 'columnVisibilityFeature')\n ? [row.getVisibleCells()]\n : [row.getAllCells()],\n { compare: shallow },\n );\n\n const cells = cellGroups.flat();\n\n /**\n * Só re-renderiza quando esta linha é marcada ou desmarcada. A seleção é opcional, então assina\n * o store; sem `rowSelectionFeature`, nenhuma linha fica selecionada.\n */\n const isSelected = useSelector(\n row.table.store,\n () => hasRowFeature(row, 'rowSelectionFeature') && row.getIsSelected(),\n );\n\n /**\n * O ponto de Tab da tabela: a linha ativa ou, sem ela no row model, a primeira. Re-renderiza\n * quando o ponto de Tab entra ou sai daqui. A navegação é opcional, então assina o store; sem\n * `activeRowFeature`, nenhuma linha entra no Tab.\n */\n const isTabStop = useSelector(row.table.store, () => {\n if (!hasRowFeature(row, 'activeRowFeature')) {\n return false;\n }\n\n const activeRow = row.table.getActiveRow();\n\n return activeRow\n ? activeRow.id === row.id\n : row.table.getRowModel().rows[0]?.id === row.id;\n });\n\n /** Só re-renderiza quando esta linha vira ou deixa de ser a ativa. */\n const isActive = useSelector(\n row.table.store,\n () => hasRowFeature(row, 'activeRowFeature') && row.getIsActive(),\n );\n\n /** Receber o foco, nela ou num controle de dentro, torna esta a linha ativa. */\n const handleFocus = () => {\n if (hasRowFeature(row, 'activeRowFeature') && !row.getIsActive()) {\n row.table.setActiveRowId(row.id);\n }\n };\n\n /** As teclas da navegação. O `onKeyDown` do app roda antes e cancela com `preventDefault()`. */\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (!hasRowFeature(row, 'activeRowFeature') || event.defaultPrevented) {\n return;\n }\n\n /** Na própria linha: num controle de dentro, como o checkbox, o Espaço é dele. */\n if (event.key === ' ' && event.target === event.currentTarget) {\n if (hasRowFeature(row, 'rowSelectionFeature') && row.getCanSelect()) {\n event.preventDefault();\n\n /** O handler do checkbox: lê o Shift do evento, para o intervalo, e move a âncora. */\n row.getToggleSelectedHandler()({\n target: { checked: !row.getIsSelected() },\n nativeEvent: event.nativeEvent,\n });\n }\n\n return;\n }\n\n const targetRow = getDataTableRowKeyTarget(event.currentTarget, event);\n\n if (targetRow) {\n event.preventDefault();\n focusDataTableRow(targetRow);\n }\n };\n\n const isNavigable = hasRowFeature(row, 'activeRowFeature');\n\n /** Com render-prop ou sem `children`, o laço é daqui; com nós comuns, de quem usa. */\n const content =\n typeof children === 'function' || children === undefined\n ? cells.map((cell) => (\n <Fragment key={cell.id}>\n {children === undefined ? (\n <DataTableCell cell={cell} />\n ) : (\n children(cell)\n )}\n </Fragment>\n ))\n : children;\n\n const baseProps = {\n 'data-component': 'DataTable.Row',\n 'data-selected': isSelected ? '' : undefined,\n 'data-active': isActive ? '' : undefined,\n role: 'row',\n // Só no `grid`: o ARIA não define o atributo na linha de uma `table`, e o leitor o ignora.\n 'aria-selected':\n isNavigable && hasRowFeature(row, 'rowSelectionFeature')\n ? isSelected\n : undefined,\n tabIndex: isNavigable ? (isTabStop ? 0 : -1) : undefined,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n className: mergeTwClassNames(\n [\n // O anel de foco se posiciona por aqui.\n 'relative',\n\n dataTableGridClassNames,\n // Sem a linha horizontal na última: embaixo dela já vem a borda da área de rolagem, e as\n // duas somariam 2px.\n 'last:border-b-0',\n\n // O fundo numa variável, que as células fixadas repetem para ficarem opacas. A base é\n // branca no claro e quase preta no escuro, numa variável à parte: a variante `dark` e o\n // `hover` disputariam a mesma propriedade, e a ordem delas no CSS decidiria. O hover sobe\n // um passo, a selecionada outro, e a selecionada com hover mais um: sem isso, passar o\n // mouse por ela não mudaria nada. Escala curta, para o fundo dos botões `ghost` das\n // células (`gray-3`) aparecer sobre a linha em hover.\n '[--data-table-row-base:var(--color-white)]',\n 'dark:[--data-table-row-base:#0b0b0b]',\n '[--data-table-row-background:var(--data-table-row-base)]',\n 'hover:[--data-table-row-background:var(--color-gray-2)]',\n 'data-selected:[--data-table-row-background:var(--color-gray-3)]',\n 'data-selected:hover:[--data-table-row-background:var(--color-gray-4)]',\n // Com um menu aberto num controle da linha, ela fica como em hover, com o ponteiro onde\n // estiver: o backdrop do menu cobre o resto da linha e deixa um recorte só sobre o\n // gatilho, e o `:hover` acenderia e apagaria a linha conforme o ponteiro passa por ele.\n 'has-[[data-popup-open]]:[--data-table-row-background:var(--color-gray-2)]',\n 'data-selected:has-[[data-popup-open]]:[--data-table-row-background:var(--color-gray-4)]',\n 'bg-(--data-table-row-background)',\n\n 'text-gray-12',\n\n // O anel de foco, com o foco na linha ou num controle de dentro, pelo teclado ou pelo\n // clique: com `focus-visible`, o clique tornaria a linha ativa sem mostrar qual é. Num\n // `::after` por cima das células fixadas (`z-1`), que cobririam o `outline` e o\n // `box-shadow` da própria linha. Por dentro: a linha seguinte cobriria o que sai por baixo.\n 'outline-none',\n 'after:pointer-events-none',\n 'after:absolute',\n 'after:inset-0',\n 'after:z-2',\n 'after:content-[\"\"]',\n 'focus-within:after:outline-2',\n 'focus-within:after:-outline-offset-2',\n 'focus-within:after:outline-gray-12',\n ],\n className,\n ),\n children: content,\n };\n\n return useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableRow.displayName = 'DataTable.Row';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,MAAa,gBAIX,UACG;CACH,MAAM,EAAE,KAAK,QAAQ,WAAW,UAAU,GAAG,SAAS;CAuBtD,MAAM,QAfa,YACjB,IAAI,MAAM,aAER,cAAc,KAAK,sBAAsB,IACrC;EACE,IAAI,qBAAqB;EACzB,IAAI,sBAAsB;EAC1B,IAAI,mBAAmB;CACzB,IACA,cAAc,KAAK,yBAAyB,IAC1C,CAAC,IAAI,gBAAgB,CAAC,IACtB,CAAC,IAAI,YAAY,CAAC,GAC1B,EAAE,SAAS,QAAQ,CAGE,CAAC,CAAC,KAAK;;;;;CAM9B,MAAM,aAAa,YACjB,IAAI,MAAM,aACJ,cAAc,KAAK,qBAAqB,KAAK,IAAI,cAAc,CACvE;;;;;;CAOA,MAAM,YAAY,YAAY,IAAI,MAAM,aAAa;EACnD,IAAI,CAAC,cAAc,KAAK,kBAAkB,GACxC,OAAO;EAGT,MAAM,YAAY,IAAI,MAAM,aAAa;EAEzC,OAAO,YACH,UAAU,OAAO,IAAI,KACrB,IAAI,MAAM,YAAY,CAAC,CAAC,KAAK,EAAE,EAAE,OAAO,IAAI;CAClD,CAAC;;CAGD,MAAM,WAAW,YACf,IAAI,MAAM,aACJ,cAAc,KAAK,kBAAkB,KAAK,IAAI,YAAY,CAClE;;CAGA,MAAM,oBAAoB;EACxB,IAAI,cAAc,KAAK,kBAAkB,KAAK,CAAC,IAAI,YAAY,GAC7D,IAAI,MAAM,eAAe,IAAI,EAAE;CAEnC;;CAGA,MAAM,iBAAiB,UAA+C;EACpE,IAAI,CAAC,cAAc,KAAK,kBAAkB,KAAK,MAAM,kBACnD;;EAIF,IAAI,MAAM,QAAQ,OAAO,MAAM,WAAW,MAAM,eAAe;GAC7D,IAAI,cAAc,KAAK,qBAAqB,KAAK,IAAI,aAAa,GAAG;IACnE,MAAM,eAAe;;IAGrB,IAAI,yBAAyB,CAAC,CAAC;KAC7B,QAAQ,EAAE,SAAS,CAAC,IAAI,cAAc,EAAE;KACxC,aAAa,MAAM;IACrB,CAAC;GACH;GAEA;EACF;EAEA,MAAM,YAAY,yBAAyB,MAAM,eAAe,KAAK;EAErE,IAAI,WAAW;GACb,MAAM,eAAe;GACrB,kBAAkB,SAAS;EAC7B;CACF;CAEA,MAAM,cAAc,cAAc,KAAK,kBAAkB;;CAGzD,MAAM,UACJ,OAAO,aAAa,cAAc,aAAa,KAAA,IAC3C,MAAM,KAAK,SACT,oBAACA,YAAD,EAAA,UACG,aAAa,KAAA,IACZ,oBAAC,eAAD,EAAqB,KAAO,CAAA,IAE5B,SAAS,IAAI,EAEP,GANK,KAAK,EAMV,CACX,IACD;CAEN,MAAM,YAAY;EAChB,kBAAkB;EAClB,iBAAiB,aAAa,KAAK,KAAA;EACnC,eAAe,WAAW,KAAK,KAAA;EAC/B,MAAM;EAEN,iBACE,eAAe,cAAc,KAAK,qBAAqB,IACnD,aACA,KAAA;EACN,UAAU,cAAe,YAAY,IAAI,KAAM,KAAA;EAC/C,SAAS;EACT,WAAW;EACX,WAAW,kBACT;GAEE;GAEA;GAGA;GAQA;GACA;GACA;GACA;GACA;GACA;GAIA;GACA;GACA;GAEA;GAMA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,GACA,SACF;EACA,UAAU;CACZ;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,aAAa,cAAc"}
|
|
1
|
+
{"version":3,"file":"data-table-row.js","names":[],"sources":["../../../../src/components/data-table/body/data-table-row.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport { shallow, useSelector } from '@tanstack/react-store';\nimport type { Cell, Row, RowData, TableFeatures } from '@tanstack/react-table';\nimport type React from 'react';\nimport { Fragment } from 'react';\nimport { hasRowFeature } from '../../../utils';\nimport { dataTableGridClassNames } from '../root/data-table-grid-class-names';\nimport { DataTableCell } from './data-table-cell';\nimport {\n focusDataTableRow,\n getDataTableRowKeyTarget,\n} from './data-table-row-focus';\n\nexport type DataTableRowProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** A linha do row model. */\n row: Row<TFeatures, TData>;\n /**\n * Uma função que recebe cada célula visível e devolve o elemento dela. Com nós comuns, quem\n * usa faz o laço.\n * @default (cell) => <DataTable.Cell cell={cell} />\n */\n children?:\n | React.ReactNode\n | ((cell: Cell<TFeatures, TData>) => React.ReactNode);\n }\n>;\n\n/**\n * Uma linha do corpo (`role=\"row\"`). É um grid com as colunas do `--data-table-template`, que o\n * `DataTable.Root` escreve.\n *\n * Com render-prop ou sem `children`, faz o laço das células sozinha: assina as próprias células e\n * re-renderiza quando a ordem, a visibilidade ou o pinning das colunas mudam, que não mudam o row\n * model e não passam pelo `DataTable.Body`. Com `columnVisibilityFeature`, são as células\n * visíveis; sem ela, todas. Com `columnPinningFeature`, vêm na ordem das regiões: as fixadas no\n * início, as do centro e as fixadas no fim.\n *\n * Com `rowSelectionFeature`, a linha selecionada ganha `data-selected` e o fundo destacado, e com\n * `activeRowFeature`, também o `aria-selected`. O clique na linha não seleciona: o `onClick` fica\n * livre, e a seleção é do `DataTable.RowCheckbox` e do Espaço.\n *\n * Com `activeRowFeature`, entra na navegação por teclado. A linha ativa tem o ponto de Tab (sem\n * ela no row model, a primeira), e receber o foco, pelo teclado ou pelo clique, torna esta a\n * ativa, marcada com `data-active`. ↑↓, Home, End, PageUp e PageDown movem o foco entre as\n * linhas, e o Espaço alterna a seleção, com Shift para o intervalo. Os atalhos são do app, no\n * `onKeyDown`, que roda antes: um `preventDefault()` cancela o da linha. Num campo de texto de\n * dentro, as setas ficam com o campo.\n *\n * O fundo fica na variável `--data-table-row-background`, que as células fixadas repetem: o\n * hover a troca para `gray-2`, a selecionada para `gray-3`, e as duas juntas, para `gray-4`. Para\n * colorir uma linha, troque a variável, e não use `bg-*`, que deixaria as fixadas com a cor\n * antiga. A cor do texto fica na linha, e as células herdam.\n *\n * @example\n * ```tsx\n * <DataTable.Row\n * row={row}\n * onClick={() => openCustomer(row.original)}\n * onKeyDown={(event) => {\n * if (event.key === 'Enter') {\n * openCustomer(row.original);\n * }\n * }}\n * className={\n * row.original.overdue\n * ? '[--data-table-row-background:var(--color-gray-2)] text-gray-11'\n * : undefined\n * }\n * >\n * {(cell) => <DataTable.Cell cell={cell} />}\n * </DataTable.Row>\n * ```\n */\nexport const DataTableRow = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableRowProps<TFeatures, TData>,\n) => {\n const { row, render, className, children, ...rest } = props;\n\n /**\n * As listas que o TanStack memoiza, numa tupla: o `shallow` compara item a item, e só\n * re-renderiza quando uma delas muda com as colunas. Todas seguem a ordem dos headers folha, que\n * é a do template, e as células caem nos tracks certos. Com pinning, as três regiões, que\n * ordenam as fixadas mesmo sem `columnVisibilityFeature`.\n */\n const cellGroups = useSelector(\n row.table.store,\n () =>\n hasRowFeature(row, 'columnPinningFeature')\n ? [\n row.getStartVisibleCells(),\n row.getCenterVisibleCells(),\n row.getEndVisibleCells(),\n ]\n : hasRowFeature(row, 'columnVisibilityFeature')\n ? [row.getVisibleCells()]\n : [row.getAllCells()],\n { compare: shallow },\n );\n\n const cells = cellGroups.flat();\n\n /**\n * Só re-renderiza quando esta linha é marcada ou desmarcada. A seleção é opcional, então assina\n * o store; sem `rowSelectionFeature`, nenhuma linha fica selecionada.\n */\n const isSelected = useSelector(\n row.table.store,\n () => hasRowFeature(row, 'rowSelectionFeature') && row.getIsSelected(),\n );\n\n /**\n * O ponto de Tab da tabela: a linha ativa ou, sem ela no row model, a primeira. Re-renderiza\n * quando o ponto de Tab entra ou sai daqui. A navegação é opcional, então assina o store; sem\n * `activeRowFeature`, nenhuma linha entra no Tab.\n */\n const isTabStop = useSelector(row.table.store, () => {\n if (!hasRowFeature(row, 'activeRowFeature')) {\n return false;\n }\n\n const activeRow = row.table.getActiveRow();\n\n return activeRow\n ? activeRow.id === row.id\n : row.table.getRowModel().rows[0]?.id === row.id;\n });\n\n /** Só re-renderiza quando esta linha vira ou deixa de ser a ativa. */\n const isActive = useSelector(\n row.table.store,\n () => hasRowFeature(row, 'activeRowFeature') && row.getIsActive(),\n );\n\n /** Receber o foco, nela ou num controle de dentro, torna esta a linha ativa. */\n const handleFocus = () => {\n if (hasRowFeature(row, 'activeRowFeature') && !row.getIsActive()) {\n row.table.setActiveRowId(row.id);\n }\n };\n\n /** As teclas da navegação. O `onKeyDown` do app roda antes e cancela com `preventDefault()`. */\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (!hasRowFeature(row, 'activeRowFeature') || event.defaultPrevented) {\n return;\n }\n\n /** Na própria linha: num controle de dentro, como o checkbox, o Espaço é dele. */\n if (event.key === ' ' && event.target === event.currentTarget) {\n if (hasRowFeature(row, 'rowSelectionFeature') && row.getCanSelect()) {\n event.preventDefault();\n\n /** O handler do checkbox: lê o Shift do evento, para o intervalo, e move a âncora. */\n row.getToggleSelectedHandler()({\n target: { checked: !row.getIsSelected() },\n nativeEvent: event.nativeEvent,\n });\n }\n\n return;\n }\n\n const targetRow = getDataTableRowKeyTarget(event.currentTarget, event);\n\n if (targetRow) {\n event.preventDefault();\n focusDataTableRow(targetRow);\n }\n };\n\n const isNavigable = hasRowFeature(row, 'activeRowFeature');\n\n /** Com render-prop ou sem `children`, o laço é daqui; com nós comuns, de quem usa. */\n const content =\n typeof children === 'function' || children === undefined\n ? cells.map((cell) => (\n <Fragment key={cell.id}>\n {children === undefined ? (\n <DataTableCell cell={cell} />\n ) : (\n children(cell)\n )}\n </Fragment>\n ))\n : children;\n\n const baseProps = {\n 'data-component': 'DataTable.Row',\n 'data-selected': isSelected ? '' : undefined,\n 'data-active': isActive ? '' : undefined,\n role: 'row',\n // Só no `grid`: o ARIA não define o atributo na linha de uma `table`, e o leitor o ignora.\n 'aria-selected':\n isNavigable && hasRowFeature(row, 'rowSelectionFeature')\n ? isSelected\n : undefined,\n tabIndex: isNavigable ? (isTabStop ? 0 : -1) : undefined,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n className: mergeTwClassNames(\n [\n // O anel de foco se posiciona por aqui.\n 'relative',\n\n dataTableGridClassNames,\n // Sem a linha horizontal na última: embaixo dela já vem a borda da área de rolagem, e as\n // duas somariam 2px.\n 'last:border-b-0',\n\n // O fundo numa variável, que as células fixadas repetem para ficarem opacas. A base é\n // branca no claro e quase preta no escuro, numa variável à parte: a variante `dark` e o\n // `hover` disputariam a mesma propriedade, e a ordem delas no CSS decidiria. O hover sobe\n // um passo, a selecionada outro, e a selecionada com hover mais um: sem isso, passar o\n // mouse por ela não mudaria nada. Escala curta, para o fundo dos botões `ghost` das\n // células (`gray-3`) aparecer sobre a linha em hover.\n '[--data-table-row-base:var(--color-white)]',\n 'dark:[--data-table-row-base:#0b0b0b]',\n '[--data-table-row-background:var(--data-table-row-base)]',\n 'hover:[--data-table-row-background:var(--color-gray-2)]',\n 'data-selected:[--data-table-row-background:var(--color-gray-3)]',\n 'data-selected:hover:[--data-table-row-background:var(--color-gray-4)]',\n // Com um menu aberto num controle da linha, ela fica como em hover, com o ponteiro onde\n // estiver: o backdrop do menu cobre o resto da linha e deixa um recorte só sobre o\n // gatilho, e o `:hover` acenderia e apagaria a linha conforme o ponteiro passa por ele.\n 'has-[[data-popup-open]]:[--data-table-row-background:var(--color-gray-2)]',\n 'data-selected:has-[[data-popup-open]]:[--data-table-row-background:var(--color-gray-4)]',\n 'bg-(--data-table-row-background)',\n\n 'text-gray-12',\n\n // O anel de foco, com o foco na linha ou num controle de dentro, pelo teclado ou pelo\n // clique: com `focus-visible`, o clique tornaria a linha ativa sem mostrar qual é. Num\n // `::after` por cima das células fixadas (`z-1`), que cobririam o `outline` e o\n // `box-shadow` da própria linha. Por dentro: a linha seguinte cobriria o que sai por baixo.\n 'outline-none',\n 'after:pointer-events-none',\n 'after:absolute',\n 'after:inset-0',\n 'after:z-2',\n 'after:content-[\"\"]',\n 'focus-within:after:outline-2',\n 'focus-within:after:-outline-offset-2',\n 'focus-within:after:outline-gray-12',\n ],\n className,\n ),\n children: content,\n };\n\n return useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableRow.displayName = 'DataTable.Row';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,MAAa,gBAIX,UACG;CACH,MAAM,EAAE,KAAK,QAAQ,WAAW,UAAU,GAAG,SAAS;CAuBtD,MAAM,QAfa,YACjB,IAAI,MAAM,aAER,cAAc,KAAK,sBAAsB,IACrC;EACE,IAAI,qBAAqB;EACzB,IAAI,sBAAsB;EAC1B,IAAI,mBAAmB;CACzB,IACA,cAAc,KAAK,yBAAyB,IAC1C,CAAC,IAAI,gBAAgB,CAAC,IACtB,CAAC,IAAI,YAAY,CAAC,GAC1B,EAAE,SAAS,QAAQ,CAGE,CAAC,CAAC,KAAK;;;;;CAM9B,MAAM,aAAa,YACjB,IAAI,MAAM,aACJ,cAAc,KAAK,qBAAqB,KAAK,IAAI,cAAc,CACvE;;;;;;CAOA,MAAM,YAAY,YAAY,IAAI,MAAM,aAAa;EACnD,IAAI,CAAC,cAAc,KAAK,kBAAkB,GACxC,OAAO;EAGT,MAAM,YAAY,IAAI,MAAM,aAAa;EAEzC,OAAO,YACH,UAAU,OAAO,IAAI,KACrB,IAAI,MAAM,YAAY,CAAC,CAAC,KAAK,EAAE,EAAE,OAAO,IAAI;CAClD,CAAC;;CAGD,MAAM,WAAW,YACf,IAAI,MAAM,aACJ,cAAc,KAAK,kBAAkB,KAAK,IAAI,YAAY,CAClE;;CAGA,MAAM,oBAAoB;EACxB,IAAI,cAAc,KAAK,kBAAkB,KAAK,CAAC,IAAI,YAAY,GAC7D,IAAI,MAAM,eAAe,IAAI,EAAE;CAEnC;;CAGA,MAAM,iBAAiB,UAA+C;EACpE,IAAI,CAAC,cAAc,KAAK,kBAAkB,KAAK,MAAM,kBACnD;;EAIF,IAAI,MAAM,QAAQ,OAAO,MAAM,WAAW,MAAM,eAAe;GAC7D,IAAI,cAAc,KAAK,qBAAqB,KAAK,IAAI,aAAa,GAAG;IACnE,MAAM,eAAe;;IAGrB,IAAI,yBAAyB,CAAC,CAAC;KAC7B,QAAQ,EAAE,SAAS,CAAC,IAAI,cAAc,EAAE;KACxC,aAAa,MAAM;IACrB,CAAC;GACH;GAEA;EACF;EAEA,MAAM,YAAY,yBAAyB,MAAM,eAAe,KAAK;EAErE,IAAI,WAAW;GACb,MAAM,eAAe;GACrB,kBAAkB,SAAS;EAC7B;CACF;CAEA,MAAM,cAAc,cAAc,KAAK,kBAAkB;;CAGzD,MAAM,UACJ,OAAO,aAAa,cAAc,aAAa,KAAA,IAC3C,MAAM,KAAK,SACT,oBAAC,UAAD,EAAA,UACG,aAAa,KAAA,IACZ,oBAAC,eAAD,EAAqB,KAAO,CAAA,IAE5B,SAAS,IAAI,EAEP,GANK,KAAK,EAMV,CACX,IACD;CAEN,MAAM,YAAY;EAChB,kBAAkB;EAClB,iBAAiB,aAAa,KAAK,KAAA;EACnC,eAAe,WAAW,KAAK,KAAA;EAC/B,MAAM;EAEN,iBACE,eAAe,cAAc,KAAK,qBAAqB,IACnD,aACA,KAAA;EACN,UAAU,cAAe,YAAY,IAAI,KAAM,KAAA;EAC/C,SAAS;EACT,WAAW;EACX,WAAW,kBACT;GAEE;GAEA;GAGA;GAQA;GACA;GACA;GACA;GACA;GACA;GAIA;GACA;GACA;GAEA;GAMA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,GACA,SACF;EACA,UAAU;CACZ;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,aAAa,cAAc"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Header, RowData, TableFeatures } from "@tanstack/react-table";
|
|
2
2
|
import { useRender } from "@base-ui/react";
|
|
3
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
3
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
4
4
|
//#region src/components/data-table/header/data-table-header-cell.d.ts
|
|
5
5
|
export type DataTableHeaderCellProps<TFeatures extends TableFeatures, TData extends RowData> = MergeOverride<useRender.ComponentProps<'div'>, {
|
|
6
6
|
/** O header da coluna. */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { hasColumnFeature, hasHeaderFeature } from "../../../utils/has-feature.js";
|
|
2
2
|
import { getDataTableColumnPinning, getDataTablePinnedStyle } from "../root/get-data-table-column-pinning.js";
|
|
3
3
|
import { DataTableHeaderContent } from "./data-table-header-content.js";
|
|
4
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
4
|
import { mergeProps, useRender } from "@base-ui/react";
|
|
6
|
-
import { useSelector } from "@tanstack/react-store";
|
|
7
5
|
import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
|
|
6
|
+
import { useSelector } from "@tanstack/react-store";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
8
|
//#region src/components/data-table/header/data-table-header-cell.tsx
|
|
9
9
|
/**
|
|
10
10
|
* A célula de um header (`role="columnheader"`). Num header de grupo, ocupa as colunas que o
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-header-cell.js","names":[],"sources":["../../../../src/components/data-table/header/data-table-header-cell.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport { useSelector } from '@tanstack/react-store';\nimport type { Header, RowData, TableFeatures } from '@tanstack/react-table';\nimport { hasColumnFeature, hasHeaderFeature } from '../../../utils';\nimport {\n getDataTableColumnPinning,\n getDataTablePinnedStyle,\n} from '../root/get-data-table-column-pinning';\nimport { DataTableHeaderContent } from './data-table-header-content';\n\nexport type DataTableHeaderCellProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** O header da coluna. */\n header: Header<TFeatures, TData>;\n }\n>;\n\n/**\n * A célula de um header (`role=\"columnheader\"`). Num header de grupo, ocupa as colunas que o\n * grupo abrange; num placeholder, fica vazia e marcada com `data-placeholder`.\n *\n * Com `rowSortingFeature`, marca a direção da ordenação em `aria-sort` e `data-sorted`. Com\n * `columnAlignmentFeature`, alinha o conteúdo pelo `align` da coluna e o marca em `data-align`.\n * Com `columnPinningFeature`, num header fixado, gruda na borda do lado dele, marcado com\n * `data-pinned`.\n *\n * Sem `children`, mostra o `DataTable.HeaderContent`. Com eles, monte o conteúdo, o\n * `DataTable.HeaderContent` incluso, e o `DataTable.ResizeHandle`, que se ancora na borda daqui.\n *\n * @example\n * ```tsx\n * <DataTable.HeaderCell header={header}>\n * <DataTable.HeaderContent header={header} />\n * <DataTable.ResizeHandle header={header} />\n * </DataTable.HeaderCell>\n * ```\n */\nexport const DataTableHeaderCell = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableHeaderCellProps<TFeatures, TData>,\n) => {\n const { header, render, className, children, ...rest } = props;\n\n /**\n * Só re-renderiza quando a ordenação desta coluna muda. A ordenação é opcional, então assina o\n * store, e o guard estreita o header; sem `rowSortingFeature`, fica `false`.\n */\n const sorted = useSelector(header.column.table.store, () =>\n hasHeaderFeature(header, 'rowSortingFeature')\n ? header.column.getIsSorted()\n : false,\n );\n\n /**\n * Sem assinatura: o alinhamento vem da definição da coluna, que não muda em runtime. Num grupo,\n * é o da definição do grupo.\n */\n const align = hasColumnFeature(header.column, 'columnAlignmentFeature')\n ? header.column.getAlign()\n : undefined;\n\n /**\n * A fixação vem da coluna folha da ponta: a primeira, no início, e a última, no fim, com o\n * deslocamento dela. Num grupo, o `getIsPinned()` diz fixado se qualquer folha for, e só a folha\n * da ponta sabe o lado e o lugar. Sem assinatura: o pinning muda os grupos, e o\n * `DataTable.Header` re-renderiza, com o header junto.\n */\n const leafHeaders = header\n .getLeafHeaders()\n .filter((leafHeader) => leafHeader.subHeaders.length === 0);\n const startPinning = getDataTableColumnPinning(\n (leafHeaders.at(0) ?? header).column,\n );\n const pinning =\n startPinning.position === 'start'\n ? startPinning\n : getDataTableColumnPinning((leafHeaders.at(-1) ?? header).column);\n\n const isGroup = header.colSpan > 1;\n\n const baseProps = {\n 'data-component': 'DataTable.HeaderCell',\n 'data-placeholder': header.isPlaceholder ? '' : undefined,\n 'data-sorted': sorted || undefined,\n 'data-align': align,\n 'data-pinned': pinning.position || undefined,\n role: 'columnheader',\n 'aria-sort':\n sorted === 'asc'\n ? 'ascending'\n : sorted === 'desc'\n ? 'descending'\n : undefined,\n 'aria-colspan': isGroup ? header.colSpan : undefined,\n style: {\n // Os tracks do grid são os das colunas folha: o grupo abrange os das colunas dele.\n gridColumn: isGroup ? `span ${header.colSpan}` : undefined,\n ...getDataTablePinnedStyle(pinning),\n },\n className: mergeTwClassNames(\n [\n // O `DataTable.ResizeHandle` se posiciona por aqui.\n 'relative',\n\n 'flex',\n 'items-center',\n 'gap-1',\n // Vale para o conteúdo solto. O `DataTable.HeaderButton` ocupa a célula e segue o\n // `data-align` daqui por conta própria.\n 'data-[align=center]:justify-center',\n 'data-[align=end]:justify-end',\n\n // Item de grid tem `min-width: auto`: sem isto, um conteúdo longo alarga o track, e a\n // coluna deixa de bater com o template. Sem `overflow-hidden`: quem trunca é o\n // `DataTable.HeaderContent`, e o recorte aqui cortaria a área de agarre do handle.\n 'min-w-0',\n\n // Do `DataTable.Root`, pela densidade.\n 'h-(--data-table-header-height)',\n\n 'px-(--data-table-cell-padding)',\n\n // Fixado: gruda acima dos handles de resize das colunas do centro (`z-10`), que passam por\n // baixo dele.\n 'data-pinned:sticky',\n 'data-pinned:z-20',\n // A sombra na borda da fixada, como na `DataTable.Cell`.\n 'data-[pinned=start]:has-[+:not([data-pinned=start])]:shadow-[6px_0_8px_-6px_rgb(0_0_0/0.12)]',\n 'dark:data-[pinned=start]:has-[+:not([data-pinned=start])]:shadow-[6px_0_8px_-6px_rgb(0_0_0/0.8)]',\n 'data-[pinned=end]:not-[[data-pinned=end]+*]:shadow-[-6px_0_8px_-6px_rgb(0_0_0/0.12)]',\n 'dark:data-[pinned=end]:not-[[data-pinned=end]+*]:shadow-[-6px_0_8px_-6px_rgb(0_0_0/0.8)]',\n\n // Opaco: o cabeçalho gruda, e as linhas passam por baixo; fixado, o centro também.\n 'bg-gray-2',\n\n 'text-xs',\n 'font-medium',\n 'text-gray-11',\n ],\n className,\n ),\n children:\n children === undefined ? (\n <DataTableHeaderContent header={header} />\n ) : (\n children\n ),\n };\n\n return useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableHeaderCell.displayName = 'DataTable.HeaderCell';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAa,uBAIX,UACG;CACH,MAAM,EAAE,QAAQ,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;CAMzD,MAAM,SAAS,YAAY,OAAO,OAAO,MAAM,aAC7C,iBAAiB,QAAQ,mBAAmB,IACxC,OAAO,OAAO,YAAY,IAC1B,KACN;;;;;CAMA,MAAM,QAAQ,iBAAiB,OAAO,QAAQ,wBAAwB,IAClE,OAAO,OAAO,SAAS,IACvB,KAAA;;;;;;;CAQJ,MAAM,cAAc,OACjB,eAAe,CAAC,CAChB,QAAQ,eAAe,WAAW,WAAW,WAAW,CAAC;CAC5D,MAAM,eAAe,2BAClB,YAAY,GAAG,CAAC,KAAK,OAAA,CAAQ,MAChC;CACA,MAAM,UACJ,aAAa,aAAa,UACtB,eACA,2BAA2B,YAAY,GAAG,EAAE,KAAK,OAAA,CAAQ,MAAM;CAErE,MAAM,UAAU,OAAO,UAAU;CAEjC,MAAM,YAAY;EAChB,kBAAkB;EAClB,oBAAoB,OAAO,gBAAgB,KAAK,KAAA;EAChD,eAAe,UAAU,KAAA;EACzB,cAAc;EACd,eAAe,QAAQ,YAAY,KAAA;EACnC,MAAM;EACN,aACE,WAAW,QACP,cACA,WAAW,SACT,eACA,KAAA;EACR,gBAAgB,UAAU,OAAO,UAAU,KAAA;EAC3C,OAAO;GAEL,YAAY,UAAU,QAAQ,OAAO,YAAY,KAAA;GACjD,GAAG,wBAAwB,OAAO;EACpC;EACA,WAAW,kBACT;GAEE;GAEA;GACA;GACA;GAGA;GACA;GAKA;GAGA;GAEA;GAIA;GACA;GAEA;GACA;GACA;GACA;GAGA;GAEA;GACA;GACA;EACF,GACA,SACF;EACA,UACE,aAAa,KAAA,IACX,oBAAC,wBAAD,EAAgC,OAAS,CAAA,IAEzC;CAEN;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,oBAAoB,cAAc"}
|
|
1
|
+
{"version":3,"file":"data-table-header-cell.js","names":[],"sources":["../../../../src/components/data-table/header/data-table-header-cell.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport { useSelector } from '@tanstack/react-store';\nimport type { Header, RowData, TableFeatures } from '@tanstack/react-table';\nimport { hasColumnFeature, hasHeaderFeature } from '../../../utils';\nimport {\n getDataTableColumnPinning,\n getDataTablePinnedStyle,\n} from '../root/get-data-table-column-pinning';\nimport { DataTableHeaderContent } from './data-table-header-content';\n\nexport type DataTableHeaderCellProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** O header da coluna. */\n header: Header<TFeatures, TData>;\n }\n>;\n\n/**\n * A célula de um header (`role=\"columnheader\"`). Num header de grupo, ocupa as colunas que o\n * grupo abrange; num placeholder, fica vazia e marcada com `data-placeholder`.\n *\n * Com `rowSortingFeature`, marca a direção da ordenação em `aria-sort` e `data-sorted`. Com\n * `columnAlignmentFeature`, alinha o conteúdo pelo `align` da coluna e o marca em `data-align`.\n * Com `columnPinningFeature`, num header fixado, gruda na borda do lado dele, marcado com\n * `data-pinned`.\n *\n * Sem `children`, mostra o `DataTable.HeaderContent`. Com eles, monte o conteúdo, o\n * `DataTable.HeaderContent` incluso, e o `DataTable.ResizeHandle`, que se ancora na borda daqui.\n *\n * @example\n * ```tsx\n * <DataTable.HeaderCell header={header}>\n * <DataTable.HeaderContent header={header} />\n * <DataTable.ResizeHandle header={header} />\n * </DataTable.HeaderCell>\n * ```\n */\nexport const DataTableHeaderCell = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableHeaderCellProps<TFeatures, TData>,\n) => {\n const { header, render, className, children, ...rest } = props;\n\n /**\n * Só re-renderiza quando a ordenação desta coluna muda. A ordenação é opcional, então assina o\n * store, e o guard estreita o header; sem `rowSortingFeature`, fica `false`.\n */\n const sorted = useSelector(header.column.table.store, () =>\n hasHeaderFeature(header, 'rowSortingFeature')\n ? header.column.getIsSorted()\n : false,\n );\n\n /**\n * Sem assinatura: o alinhamento vem da definição da coluna, que não muda em runtime. Num grupo,\n * é o da definição do grupo.\n */\n const align = hasColumnFeature(header.column, 'columnAlignmentFeature')\n ? header.column.getAlign()\n : undefined;\n\n /**\n * A fixação vem da coluna folha da ponta: a primeira, no início, e a última, no fim, com o\n * deslocamento dela. Num grupo, o `getIsPinned()` diz fixado se qualquer folha for, e só a folha\n * da ponta sabe o lado e o lugar. Sem assinatura: o pinning muda os grupos, e o\n * `DataTable.Header` re-renderiza, com o header junto.\n */\n const leafHeaders = header\n .getLeafHeaders()\n .filter((leafHeader) => leafHeader.subHeaders.length === 0);\n const startPinning = getDataTableColumnPinning(\n (leafHeaders.at(0) ?? header).column,\n );\n const pinning =\n startPinning.position === 'start'\n ? startPinning\n : getDataTableColumnPinning((leafHeaders.at(-1) ?? header).column);\n\n const isGroup = header.colSpan > 1;\n\n const baseProps = {\n 'data-component': 'DataTable.HeaderCell',\n 'data-placeholder': header.isPlaceholder ? '' : undefined,\n 'data-sorted': sorted || undefined,\n 'data-align': align,\n 'data-pinned': pinning.position || undefined,\n role: 'columnheader',\n 'aria-sort':\n sorted === 'asc'\n ? 'ascending'\n : sorted === 'desc'\n ? 'descending'\n : undefined,\n 'aria-colspan': isGroup ? header.colSpan : undefined,\n style: {\n // Os tracks do grid são os das colunas folha: o grupo abrange os das colunas dele.\n gridColumn: isGroup ? `span ${header.colSpan}` : undefined,\n ...getDataTablePinnedStyle(pinning),\n },\n className: mergeTwClassNames(\n [\n // O `DataTable.ResizeHandle` se posiciona por aqui.\n 'relative',\n\n 'flex',\n 'items-center',\n 'gap-1',\n // Vale para o conteúdo solto. O `DataTable.HeaderButton` ocupa a célula e segue o\n // `data-align` daqui por conta própria.\n 'data-[align=center]:justify-center',\n 'data-[align=end]:justify-end',\n\n // Item de grid tem `min-width: auto`: sem isto, um conteúdo longo alarga o track, e a\n // coluna deixa de bater com o template. Sem `overflow-hidden`: quem trunca é o\n // `DataTable.HeaderContent`, e o recorte aqui cortaria a área de agarre do handle.\n 'min-w-0',\n\n // Do `DataTable.Root`, pela densidade.\n 'h-(--data-table-header-height)',\n\n 'px-(--data-table-cell-padding)',\n\n // Fixado: gruda acima dos handles de resize das colunas do centro (`z-10`), que passam por\n // baixo dele.\n 'data-pinned:sticky',\n 'data-pinned:z-20',\n // A sombra na borda da fixada, como na `DataTable.Cell`.\n 'data-[pinned=start]:has-[+:not([data-pinned=start])]:shadow-[6px_0_8px_-6px_rgb(0_0_0/0.12)]',\n 'dark:data-[pinned=start]:has-[+:not([data-pinned=start])]:shadow-[6px_0_8px_-6px_rgb(0_0_0/0.8)]',\n 'data-[pinned=end]:not-[[data-pinned=end]+*]:shadow-[-6px_0_8px_-6px_rgb(0_0_0/0.12)]',\n 'dark:data-[pinned=end]:not-[[data-pinned=end]+*]:shadow-[-6px_0_8px_-6px_rgb(0_0_0/0.8)]',\n\n // Opaco: o cabeçalho gruda, e as linhas passam por baixo; fixado, o centro também.\n 'bg-gray-2',\n\n 'text-xs',\n 'font-medium',\n 'text-gray-11',\n ],\n className,\n ),\n children:\n children === undefined ? (\n <DataTableHeaderContent header={header} />\n ) : (\n children\n ),\n };\n\n return useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableHeaderCell.displayName = 'DataTable.HeaderCell';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAa,uBAIX,UACG;CACH,MAAM,EAAE,QAAQ,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;CAMzD,MAAM,SAAS,YAAY,OAAO,OAAO,MAAM,aAC7C,iBAAiB,QAAQ,mBAAmB,IACxC,OAAO,OAAO,YAAY,IAC1B,KACN;;;;;CAMA,MAAM,QAAQ,iBAAiB,OAAO,QAAQ,wBAAwB,IAClE,OAAO,OAAO,SAAS,IACvB,KAAA;;;;;;;CAQJ,MAAM,cAAc,OACjB,eAAe,CAAC,CAChB,QAAQ,eAAe,WAAW,WAAW,WAAW,CAAC;CAC5D,MAAM,eAAe,2BAClB,YAAY,GAAG,CAAC,KAAK,OAAA,CAAQ,MAChC;CACA,MAAM,UACJ,aAAa,aAAa,UACtB,eACA,2BAA2B,YAAY,GAAG,EAAE,KAAK,OAAA,CAAQ,MAAM;CAErE,MAAM,UAAU,OAAO,UAAU;CAEjC,MAAM,YAAY;EAChB,kBAAkB;EAClB,oBAAoB,OAAO,gBAAgB,KAAK,KAAA;EAChD,eAAe,UAAU,KAAA;EACzB,cAAc;EACd,eAAe,QAAQ,YAAY,KAAA;EACnC,MAAM;EACN,aACE,WAAW,QACP,cACA,WAAW,SACT,eACA,KAAA;EACR,gBAAgB,UAAU,OAAO,UAAU,KAAA;EAC3C,OAAO;GAEL,YAAY,UAAU,QAAQ,OAAO,YAAY,KAAA;GACjD,GAAG,wBAAwB,OAAO;EACpC;EACA,WAAW,kBACT;GAEE;GAEA;GACA;GACA;GAGA;GACA;GAKA;GAGA;GAEA;GAIA;GACA;GAEA;GACA;GACA;GACA;GAGA;GAEA;GACA;GACA;EACF,GACA,SACF;EACA,UACE,aAAa,KAAA,IACX,oBAAC,wBAAD,EAAgC,OAAS,CAAA,IAEzC;CAEN;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,oBAAoB,cAAc"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Header, RowData, TableFeatures } from "@tanstack/react-table";
|
|
2
2
|
import { useRender } from "@base-ui/react";
|
|
3
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
3
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
4
4
|
//#region src/components/data-table/header/data-table-header-content.d.ts
|
|
5
5
|
export type DataTableHeaderContentProps<TFeatures extends TableFeatures, TData extends RowData> = MergeOverride<useRender.ComponentProps<'span'>, {
|
|
6
6
|
/** O header da coluna. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FlexRender } from "@tanstack/react-table";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
3
2
|
import { mergeProps, useRender } from "@base-ui/react";
|
|
4
3
|
import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
//#region src/components/data-table/header/data-table-header-content.tsx
|
|
6
6
|
/**
|
|
7
7
|
* O conteúdo do header: o `header` da definição da coluna, truncado com reticências. Num header
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-header-content.js","names":[],"sources":["../../../../src/components/data-table/header/data-table-header-content.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport {\n FlexRender,\n type Header,\n type RowData,\n type TableFeatures,\n} from '@tanstack/react-table';\n\nexport type DataTableHeaderContentProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'span'>,\n {\n /** O header da coluna. */\n header: Header<TFeatures, TData>;\n }\n>;\n\n/**\n * O conteúdo do header: o `header` da definição da coluna, truncado com reticências. Num header\n * placeholder, fica vazio. Com `children`, eles substituem o da definição.\n *\n * Existe à parte porque o `DataTable.HeaderCell` não pode recortar: a área de agarre do\n * `DataTable.ResizeHandle` passa da borda dele, e conteúdo recortado não recebe clique.\n */\nexport const DataTableHeaderContent = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableHeaderContentProps<TFeatures, TData>,\n) => {\n const { header, render, className, children, ...rest } = props;\n\n const content = header.isPlaceholder ? null : <FlexRender header={header} />;\n\n const baseProps = {\n 'data-component': 'DataTable.HeaderContent',\n className: mergeTwClassNames(\n [\n // `span` em bloco: trunca como um bloco e ainda cabe num botão, que só aceita conteúdo\n // inline.\n 'block',\n 'min-w-0',\n 'truncate',\n\n // Afasta a borda do recorte 4px sem mover o conteúdo: cabe o anel de foco de um\n // controle aqui dentro, como o \"selecionar tudo\".\n '-m-1',\n 'p-1',\n ],\n className,\n ),\n children: children === undefined ? content : children,\n };\n\n return useRender({\n render,\n defaultTagName: 'span',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableHeaderContent.displayName = 'DataTable.HeaderContent';\n"],"mappings":";;;;;;;;;;;;AA4BA,MAAa,0BAIX,UACG;CACH,MAAM,EAAE,QAAQ,QAAQ,WAAW,UAAU,GAAG,SAAS;CAEzD,MAAM,UAAU,OAAO,gBAAgB,OAAO,oBAAC,YAAD,EAAoB,OAAS,CAAA;CAE3E,MAAM,YAAY;EAChB,kBAAkB;EAClB,WAAW,kBACT;GAGE;GACA;GACA;GAIA;GACA;EACF,GACA,SACF;EACA,UAAU,aAAa,KAAA,IAAY,UAAU;CAC/C;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,uBAAuB,cAAc"}
|
|
1
|
+
{"version":3,"file":"data-table-header-content.js","names":[],"sources":["../../../../src/components/data-table/header/data-table-header-content.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport {\n FlexRender,\n type Header,\n type RowData,\n type TableFeatures,\n} from '@tanstack/react-table';\n\nexport type DataTableHeaderContentProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'span'>,\n {\n /** O header da coluna. */\n header: Header<TFeatures, TData>;\n }\n>;\n\n/**\n * O conteúdo do header: o `header` da definição da coluna, truncado com reticências. Num header\n * placeholder, fica vazio. Com `children`, eles substituem o da definição.\n *\n * Existe à parte porque o `DataTable.HeaderCell` não pode recortar: a área de agarre do\n * `DataTable.ResizeHandle` passa da borda dele, e conteúdo recortado não recebe clique.\n */\nexport const DataTableHeaderContent = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableHeaderContentProps<TFeatures, TData>,\n) => {\n const { header, render, className, children, ...rest } = props;\n\n const content = header.isPlaceholder ? null : <FlexRender header={header} />;\n\n const baseProps = {\n 'data-component': 'DataTable.HeaderContent',\n className: mergeTwClassNames(\n [\n // `span` em bloco: trunca como um bloco e ainda cabe num botão, que só aceita conteúdo\n // inline.\n 'block',\n 'min-w-0',\n 'truncate',\n\n // Afasta a borda do recorte 4px sem mover o conteúdo: cabe o anel de foco de um\n // controle aqui dentro, como o \"selecionar tudo\".\n '-m-1',\n 'p-1',\n ],\n className,\n ),\n children: children === undefined ? content : children,\n };\n\n return useRender({\n render,\n defaultTagName: 'span',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableHeaderContent.displayName = 'DataTable.HeaderContent';\n"],"mappings":";;;;;;;;;;;;AA4BA,MAAa,0BAIX,UACG;CACH,MAAM,EAAE,QAAQ,QAAQ,WAAW,UAAU,GAAG,SAAS;CAEzD,MAAM,UAAU,OAAO,gBAAgB,OAAO,oBAAC,YAAD,EAAoB,OAAS,CAAA;CAE3E,MAAM,YAAY;EAChB,kBAAkB;EAClB,WAAW,kBACT;GAGE;GACA;GACA;GAIA;GACA;EACF,GACA,SACF;EACA,UAAU,aAAa,KAAA,IAAY,UAAU;CAC/C;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,uBAAuB,cAAc"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Header, RowData, Table, TableFeatures } from "@tanstack/react-table";
|
|
2
2
|
import { useRender } from "@base-ui/react";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
4
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
5
5
|
//#region src/components/data-table/header/data-table-header.d.ts
|
|
6
6
|
export type DataTableHeaderProps<TFeatures extends TableFeatures, TData extends RowData> = MergeOverride<useRender.ComponentProps<'div'>, {
|
|
7
7
|
/** A tabela do `useTable`. */
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { hasTableFeature } from "../../../utils/has-feature.js";
|
|
2
2
|
import { DataTableHeaderCell } from "./data-table-header-cell.js";
|
|
3
3
|
import { DataTableHeaderRow } from "./data-table-header-row.js";
|
|
4
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
4
|
import { mergeProps, useRender } from "@base-ui/react";
|
|
6
|
-
import { shallow, useSelector } from "@tanstack/react-store";
|
|
7
5
|
import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
|
|
8
|
-
import {
|
|
6
|
+
import { shallow, useSelector } from "@tanstack/react-store";
|
|
7
|
+
import { Fragment } from "react";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
9
|
//#region src/components/data-table/header/data-table-header.tsx
|
|
10
10
|
/**
|
|
11
11
|
* O cabeçalho da tabela (`role="rowgroup"`), grudado no topo da área de rolagem.
|
|
@@ -56,7 +56,7 @@ const DataTableHeader = (props) => {
|
|
|
56
56
|
* Com render-prop ou sem `children`, o laço é daqui, com uma `HeaderRow` por grupo; com nós
|
|
57
57
|
* comuns, de quem usa.
|
|
58
58
|
*/
|
|
59
|
-
const content = typeof children === "function" || children === void 0 ? headerRows.map((headerRow) => /* @__PURE__ */ jsx(DataTableHeaderRow, { children: headerRow.headers.map((header) => /* @__PURE__ */ jsx(Fragment
|
|
59
|
+
const content = typeof children === "function" || children === void 0 ? headerRows.map((headerRow) => /* @__PURE__ */ jsx(DataTableHeaderRow, { children: headerRow.headers.map((header) => /* @__PURE__ */ jsx(Fragment, { children: children === void 0 ? /* @__PURE__ */ jsx(DataTableHeaderCell, { header }) : children(header) }, header.id)) }, headerRow.depth)) : children;
|
|
60
60
|
const baseProps = {
|
|
61
61
|
"data-component": "DataTable.Header",
|
|
62
62
|
role: "rowgroup",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-header.js","names":[
|
|
1
|
+
{"version":3,"file":"data-table-header.js","names":[],"sources":["../../../../src/components/data-table/header/data-table-header.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport { shallow, useSelector } from '@tanstack/react-store';\nimport type {\n Header,\n RowData,\n Table,\n TableFeatures,\n} from '@tanstack/react-table';\nimport type React from 'react';\nimport { Fragment } from 'react';\nimport { hasTableFeature } from '../../../utils';\nimport { DataTableHeaderCell } from './data-table-header-cell';\nimport { DataTableHeaderRow } from './data-table-header-row';\n\nexport type DataTableHeaderProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** A tabela do `useTable`. */\n table: Table<TFeatures, TData>;\n /**\n * Uma função que recebe cada header e devolve a célula dele: o `Header` monta uma\n * `DataTable.HeaderRow` por grupo de headers e chama a função para cada header. Com nós\n * comuns, quem usa faz o laço.\n * @default (header) => <DataTable.HeaderCell header={header} />\n */\n children?:\n | React.ReactNode\n | ((header: Header<TFeatures, TData>) => React.ReactNode);\n }\n>;\n\n/**\n * O cabeçalho da tabela (`role=\"rowgroup\"`), grudado no topo da área de rolagem.\n *\n * Com render-prop ou sem `children`, faz o laço sozinho: assina os grupos de headers e só\n * re-renderiza quando a estrutura das colunas muda (`columns`, ordem, visibilidade, pinning),\n * sem o dono da tabela precisar re-renderizar. Com nós comuns, o laço é de quem usa, e o dono\n * precisa re-renderizar quando a estrutura muda.\n *\n * Com `columnPinningFeature`, monta as linhas com os grupos de cada região (as fixadas no início,\n * o centro e as fixadas no fim): um grupo cujas colunas atravessam a fronteira da fixação vira um\n * header em cada região, e a parte fixada gruda.\n *\n * @example\n * ```tsx\n * <DataTable.Header table={table}>\n * {(header) => (\n * <DataTable.HeaderCell header={header}>\n * <DataTable.HeaderContent header={header} />\n * <DataTable.ResizeHandle header={header} />\n * </DataTable.HeaderCell>\n * )}\n * </DataTable.Header>\n * ```\n */\nexport const DataTableHeader = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableHeaderProps<TFeatures, TData>,\n) => {\n const { table, render, className, children, ...rest } = props;\n\n /**\n * Os grupos que o TanStack memoiza, numa tupla: o `shallow` compara item a item, e só\n * re-renderiza quando a estrutura das colunas muda. Tamanho, ordenação e seleção mudam o store,\n * mas não os grupos. Com pinning, os grupos de cada região: o de uma região só tem as colunas\n * dela.\n */\n const regionHeaderGroups = useSelector(\n table.store,\n () =>\n hasTableFeature(table, 'columnPinningFeature')\n ? [\n table.getStartHeaderGroups(),\n table.getCenterHeaderGroups(),\n table.getEndHeaderGroups(),\n ]\n : [table.getHeaderGroups()],\n { compare: shallow },\n );\n\n /**\n * As linhas do cabeçalho, uma por profundidade, com os headers das regiões na ordem do\n * template. Toda região tem o mesmo número de grupos, o da coluna mais funda.\n */\n const headerRows = (regionHeaderGroups[0] ?? []).map((headerGroup) => ({\n depth: headerGroup.depth,\n headers: regionHeaderGroups.flatMap(\n (headerGroups) => headerGroups[headerGroup.depth]?.headers ?? [],\n ),\n }));\n\n /**\n * Com render-prop ou sem `children`, o laço é daqui, com uma `HeaderRow` por grupo; com nós\n * comuns, de quem usa.\n */\n const content =\n typeof children === 'function' || children === undefined\n ? headerRows.map((headerRow) => (\n <DataTableHeaderRow key={headerRow.depth}>\n {headerRow.headers.map((header) => (\n <Fragment key={header.id}>\n {children === undefined ? (\n <DataTableHeaderCell header={header} />\n ) : (\n children(header)\n )}\n </Fragment>\n ))}\n </DataTableHeaderRow>\n ))\n : children;\n\n const baseProps = {\n 'data-component': 'DataTable.Header',\n role: 'rowgroup',\n className: mergeTwClassNames(\n [\n // Gruda no ancestral que rola, como o viewport do `DataTable.ScrollArea`.\n 'sticky',\n 'top-0',\n 'z-10',\n ],\n className,\n ),\n children: content,\n };\n\n return useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableHeader.displayName = 'DataTable.Header';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,MAAa,mBAIX,UACG;CACH,MAAM,EAAE,OAAO,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;;;CAQxD,MAAM,qBAAqB,YACzB,MAAM,aAEJ,gBAAgB,OAAO,sBAAsB,IACzC;EACE,MAAM,qBAAqB;EAC3B,MAAM,sBAAsB;EAC5B,MAAM,mBAAmB;CAC3B,IACA,CAAC,MAAM,gBAAgB,CAAC,GAC9B,EAAE,SAAS,QAAQ,CACrB;;;;;CAMA,MAAM,cAAc,mBAAmB,MAAM,CAAC,EAAA,CAAG,KAAK,iBAAiB;EACrE,OAAO,YAAY;EACnB,SAAS,mBAAmB,SACzB,iBAAiB,aAAa,YAAY,MAAM,EAAE,WAAW,CAAC,CACjE;CACF,EAAE;;;;;CAMF,MAAM,UACJ,OAAO,aAAa,cAAc,aAAa,KAAA,IAC3C,WAAW,KAAK,cACd,oBAAC,oBAAD,EAAA,UACG,UAAU,QAAQ,KAAK,WACtB,oBAAC,UAAD,EAAA,UACG,aAAa,KAAA,IACZ,oBAAC,qBAAD,EAA6B,OAAS,CAAA,IAEtC,SAAS,MAAM,EAET,GANK,OAAO,EAMZ,CACX,EACiB,GAVK,UAAU,KAUf,CACrB,IACD;CAEN,MAAM,YAAY;EAChB,kBAAkB;EAClB,MAAM;EACN,WAAW,kBACT;GAEE;GACA;GACA;EACF,GACA,SACF;EACA,UAAU;CACZ;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,gBAAgB,cAAc"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { DataTableHeaderButton } from "./header/data-table-header-button.js";
|
|
3
2
|
import { DataTableCell } from "./body/data-table-cell.js";
|
|
4
3
|
import { DataTableRow } from "./body/data-table-row.js";
|
|
5
4
|
import { DataTableBody } from "./body/data-table-body.js";
|
|
@@ -8,6 +7,7 @@ import { DataTableHeaderContent } from "./header/data-table-header-content.js";
|
|
|
8
7
|
import { DataTableHeaderCell } from "./header/data-table-header-cell.js";
|
|
9
8
|
import { DataTableHeaderRow } from "./header/data-table-header-row.js";
|
|
10
9
|
import { DataTableHeader } from "./header/data-table-header.js";
|
|
10
|
+
import { DataTableHeaderButton } from "./header/data-table-header-button.js";
|
|
11
11
|
import { DataTablePageButton } from "./pagination/data-table-page-button.js";
|
|
12
12
|
import { DataTablePageSizeSelect } from "./pagination/data-table-page-size-select.js";
|
|
13
13
|
import { DataTablePageStatus } from "./pagination/data-table-page-status.js";
|
|
@@ -2,7 +2,7 @@ import { TableWith } from "../../../types/table-with.js";
|
|
|
2
2
|
import "../../../types/index.js";
|
|
3
3
|
import { RowData, TableFeatures } from "@tanstack/react-table";
|
|
4
4
|
import { IconButtonProps } from "@lucasbernardosn/react-ui/buttons/icon-button";
|
|
5
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
5
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
6
6
|
//#region src/components/data-table/pagination/data-table-page-button.d.ts
|
|
7
7
|
/** Para onde o botão leva. */
|
|
8
8
|
export type DataTablePageButtonPage = 'first' | 'previous' | 'next' | 'last';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { CaretDoubleLeftIcon, CaretDoubleRightIcon, CaretLeftIcon, CaretRightIcon } from "@phosphor-icons/react";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
3
1
|
import { useSelector } from "@tanstack/react-store";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { CaretDoubleLeftIcon, CaretDoubleRightIcon, CaretLeftIcon, CaretRightIcon } from "@phosphor-icons/react";
|
|
4
4
|
import { IconButton } from "@lucasbernardosn/react-ui/buttons/icon-button";
|
|
5
5
|
//#region src/components/data-table/pagination/data-table-page-button.tsx
|
|
6
6
|
const PAGE_LABELS = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-page-button.js","names":[],"sources":["../../../../src/components/data-table/pagination/data-table-page-button.tsx"],"sourcesContent":["import {\n IconButton,\n type IconButtonProps,\n} from '@lucasbernardosn/react-ui/buttons/icon-button';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport {\n CaretDoubleLeftIcon,\n CaretDoubleRightIcon,\n CaretLeftIcon,\n CaretRightIcon,\n} from '@phosphor-icons/react';\nimport { useSelector } from '@tanstack/react-store';\nimport type { RowData, TableFeatures } from '@tanstack/react-table';\nimport type { TableWith } from '../../../types';\n\n/** Para onde o botão leva. */\nexport type DataTablePageButtonPage = 'first' | 'previous' | 'next' | 'last';\n\nexport type DataTablePageButtonProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n Omit<IconButtonProps, 'icon' | 'aria-label'>,\n {\n /** A tabela. Exige `rowPaginationFeature`. */\n table: TableWith<TFeatures, TData, 'rowPaginationFeature'>;\n /** Para onde o botão leva: a primeira página, a anterior, a próxima ou a última. */\n page: DataTablePageButtonPage;\n /**\n * O ícone.\n * @default um caret por página: duplo nas pontas, simples na anterior e na próxima\n */\n icon?: IconButtonProps['icon'];\n /**\n * O que o botão faz.\n * @default 'Primeira página', 'Página anterior', 'Próxima página' ou 'Última página'\n */\n 'aria-label'?: string;\n }\n>;\n\nconst PAGE_LABELS: Record<DataTablePageButtonPage, string> = {\n first: 'Primeira página',\n previous: 'Página anterior',\n next: 'Próxima página',\n last: 'Última página',\n};\n\nconst PAGE_ICONS: Record<DataTablePageButtonPage, IconButtonProps['icon']> = {\n first: <CaretDoubleLeftIcon />,\n previous: <CaretLeftIcon />,\n next: <CaretRightIcon />,\n last: <CaretDoubleRightIcon />,\n};\n\n/**\n * O botão que leva a outra página: a primeira, a anterior, a próxima ou a última. Fica\n * desabilitado quando não há para onde ir. Sem o total de páginas (`pageCount: -1` na paginação\n * pela API), a próxima continua habilitada, e a última, não.\n *\n * As props do `IconButton` passam adiante, como `variant` e `size`.\n *\n * @example\n * ```tsx\n * <DataTable.PageButton\n * table={table}\n * page=\"next\"\n * />\n * ```\n */\nexport const DataTablePageButton = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTablePageButtonProps<TFeatures, TData>,\n) => {\n const { table, page, icon, onClick, ...rest } = props;\n\n /**\n * Re-renderiza quando o botão passa a ter ou deixa de ter para onde ir. O store, e não só o\n * atom da paginação: o total de páginas também muda com as linhas.\n */\n const isDisabled = useSelector(table.store, () => {\n if (page === 'first' || page === 'previous') {\n return !table.getCanPreviousPage();\n }\n\n return page === 'next' ? !table.getCanNextPage() : !table.getCanLastPage();\n });\n\n const goToPage = () => {\n if (page === 'first') {\n table.firstPage();\n } else if (page === 'previous') {\n table.previousPage();\n } else if (page === 'next') {\n table.nextPage();\n } else {\n table.lastPage();\n }\n };\n\n return (\n <IconButton\n data-component=\"DataTable.PageButton\"\n data-page={page}\n aria-label={PAGE_LABELS[page]}\n icon={icon ?? PAGE_ICONS[page]}\n variant=\"outline\"\n disabled={isDisabled}\n // O `onClick` do app roda antes, e um `preventDefault()` nele cancela a troca de página.\n onClick={(event) => {\n onClick?.(event);\n\n if (!event.defaultPrevented) {\n goToPage();\n }\n }}\n {...rest}\n />\n );\n};\n\nDataTablePageButton.displayName = 'DataTable.PageButton';\n"],"mappings":";;;;;AAyCA,MAAM,cAAuD;CAC3D,OAAO;CACP,UAAU;CACV,MAAM;CACN,MAAM;AACR;AAEA,MAAM,aAAuE;CAC3E,OAAO,oBAAC,qBAAD,CAAsB,CAAA;CAC7B,UAAU,oBAAC,eAAD,CAAgB,CAAA;CAC1B,MAAM,oBAAC,gBAAD,CAAiB,CAAA;CACvB,MAAM,oBAAC,sBAAD,CAAuB,CAAA;AAC/B;;;;;;;;;;;;;;;;AAiBA,MAAa,uBAIX,UACG;CACH,MAAM,EAAE,OAAO,MAAM,MAAM,SAAS,GAAG,SAAS;;;;;CAMhD,MAAM,aAAa,YAAY,MAAM,aAAa;EAChD,IAAI,SAAS,WAAW,SAAS,YAC/B,OAAO,CAAC,MAAM,mBAAmB;EAGnC,OAAO,SAAS,SAAS,CAAC,MAAM,eAAe,IAAI,CAAC,MAAM,eAAe;CAC3E,CAAC;CAED,MAAM,iBAAiB;EACrB,IAAI,SAAS,SACX,MAAM,UAAU;OACX,IAAI,SAAS,YAClB,MAAM,aAAa;OACd,IAAI,SAAS,QAClB,MAAM,SAAS;OAEf,MAAM,SAAS;CAEnB;CAEA,OACE,oBAAC,YAAD;EACE,kBAAe;EACf,aAAW;EACX,cAAY,YAAY;EACxB,MAAM,QAAQ,WAAW;EACzB,SAAQ;EACR,UAAU;EAEV,UAAU,UAAU;GAClB,UAAU,KAAK;GAEf,IAAI,CAAC,MAAM,kBACT,SAAS;EAEb;EACA,GAAI;CACL,CAAA;AAEL;AAEA,oBAAoB,cAAc"}
|
|
1
|
+
{"version":3,"file":"data-table-page-button.js","names":[],"sources":["../../../../src/components/data-table/pagination/data-table-page-button.tsx"],"sourcesContent":["import {\n IconButton,\n type IconButtonProps,\n} from '@lucasbernardosn/react-ui/buttons/icon-button';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport {\n CaretDoubleLeftIcon,\n CaretDoubleRightIcon,\n CaretLeftIcon,\n CaretRightIcon,\n} from '@phosphor-icons/react';\nimport { useSelector } from '@tanstack/react-store';\nimport type { RowData, TableFeatures } from '@tanstack/react-table';\nimport type { TableWith } from '../../../types';\n\n/** Para onde o botão leva. */\nexport type DataTablePageButtonPage = 'first' | 'previous' | 'next' | 'last';\n\nexport type DataTablePageButtonProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n Omit<IconButtonProps, 'icon' | 'aria-label'>,\n {\n /** A tabela. Exige `rowPaginationFeature`. */\n table: TableWith<TFeatures, TData, 'rowPaginationFeature'>;\n /** Para onde o botão leva: a primeira página, a anterior, a próxima ou a última. */\n page: DataTablePageButtonPage;\n /**\n * O ícone.\n * @default um caret por página: duplo nas pontas, simples na anterior e na próxima\n */\n icon?: IconButtonProps['icon'];\n /**\n * O que o botão faz.\n * @default 'Primeira página', 'Página anterior', 'Próxima página' ou 'Última página'\n */\n 'aria-label'?: string;\n }\n>;\n\nconst PAGE_LABELS: Record<DataTablePageButtonPage, string> = {\n first: 'Primeira página',\n previous: 'Página anterior',\n next: 'Próxima página',\n last: 'Última página',\n};\n\nconst PAGE_ICONS: Record<DataTablePageButtonPage, IconButtonProps['icon']> = {\n first: <CaretDoubleLeftIcon />,\n previous: <CaretLeftIcon />,\n next: <CaretRightIcon />,\n last: <CaretDoubleRightIcon />,\n};\n\n/**\n * O botão que leva a outra página: a primeira, a anterior, a próxima ou a última. Fica\n * desabilitado quando não há para onde ir. Sem o total de páginas (`pageCount: -1` na paginação\n * pela API), a próxima continua habilitada, e a última, não.\n *\n * As props do `IconButton` passam adiante, como `variant` e `size`.\n *\n * @example\n * ```tsx\n * <DataTable.PageButton\n * table={table}\n * page=\"next\"\n * />\n * ```\n */\nexport const DataTablePageButton = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTablePageButtonProps<TFeatures, TData>,\n) => {\n const { table, page, icon, onClick, ...rest } = props;\n\n /**\n * Re-renderiza quando o botão passa a ter ou deixa de ter para onde ir. O store, e não só o\n * atom da paginação: o total de páginas também muda com as linhas.\n */\n const isDisabled = useSelector(table.store, () => {\n if (page === 'first' || page === 'previous') {\n return !table.getCanPreviousPage();\n }\n\n return page === 'next' ? !table.getCanNextPage() : !table.getCanLastPage();\n });\n\n const goToPage = () => {\n if (page === 'first') {\n table.firstPage();\n } else if (page === 'previous') {\n table.previousPage();\n } else if (page === 'next') {\n table.nextPage();\n } else {\n table.lastPage();\n }\n };\n\n return (\n <IconButton\n data-component=\"DataTable.PageButton\"\n data-page={page}\n aria-label={PAGE_LABELS[page]}\n icon={icon ?? PAGE_ICONS[page]}\n variant=\"outline\"\n disabled={isDisabled}\n // O `onClick` do app roda antes, e um `preventDefault()` nele cancela a troca de página.\n onClick={(event) => {\n onClick?.(event);\n\n if (!event.defaultPrevented) {\n goToPage();\n }\n }}\n {...rest}\n />\n );\n};\n\nDataTablePageButton.displayName = 'DataTable.PageButton';\n"],"mappings":";;;;;AAyCA,MAAM,cAAuD;CAC3D,OAAO;CACP,UAAU;CACV,MAAM;CACN,MAAM;AACR;AAEA,MAAM,aAAuE;CAC3E,OAAO,oBAAC,qBAAD,CAAsB,CAAA;CAC7B,UAAU,oBAAC,eAAD,CAAgB,CAAA;CAC1B,MAAM,oBAAC,gBAAD,CAAiB,CAAA;CACvB,MAAM,oBAAC,sBAAD,CAAuB,CAAA;AAC/B;;;;;;;;;;;;;;;;AAiBA,MAAa,uBAIX,UACG;CACH,MAAM,EAAE,OAAO,MAAM,MAAM,SAAS,GAAG,SAAS;;;;;CAMhD,MAAM,aAAa,YAAY,MAAM,aAAa;EAChD,IAAI,SAAS,WAAW,SAAS,YAC/B,OAAO,CAAC,MAAM,mBAAmB;EAGnC,OAAO,SAAS,SAAS,CAAC,MAAM,eAAe,IAAI,CAAC,MAAM,eAAe;CAC3E,CAAC;CAED,MAAM,iBAAiB;EACrB,IAAI,SAAS,SACX,MAAM,UAAU;OACX,IAAI,SAAS,YAClB,MAAM,aAAa;OACd,IAAI,SAAS,QAClB,MAAM,SAAS;OAEf,MAAM,SAAS;CAEnB;CAEA,OACE,oBAAC,YAAD;EACE,kBAAe;EACf,aAAW;EACX,cAAY,YAAY;EACxB,MAAM,QAAQ,WAAW;EACzB,SAAQ;EACR,UAAU;EAEV,UAAU,UAAU;GAClB,UAAU,KAAK;GAEf,IAAI,CAAC,MAAM,kBACT,SAAS;EAEb;EACA,GAAI;CACL,CAAA;AAEL;AAEA,oBAAoB,cAAc"}
|
|
@@ -3,7 +3,7 @@ import "../../../types/index.js";
|
|
|
3
3
|
import { RowData, TableFeatures } from "@tanstack/react-table";
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { Select } from "@lucasbernardosn/react-ui/collections/select";
|
|
6
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
6
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
7
7
|
//#region src/components/data-table/pagination/data-table-page-size-select.d.ts
|
|
8
8
|
export type DataTablePageSizeSelectProps<TFeatures extends TableFeatures, TData extends RowData> = MergeOverride<React.ComponentProps<'div'>, {
|
|
9
9
|
/** A tabela. Exige `rowPaginationFeature`. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useSelector } from "@tanstack/react-store";
|
|
3
1
|
import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
|
|
2
|
+
import { useSelector } from "@tanstack/react-store";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { Select } from "@lucasbernardosn/react-ui/collections/select";
|
|
5
5
|
//#region src/components/data-table/pagination/data-table-page-size-select.tsx
|
|
6
6
|
const DEFAULT_PAGE_SIZE_OPTIONS = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-page-size-select.js","names":[],"sources":["../../../../src/components/data-table/pagination/data-table-page-size-select.tsx"],"sourcesContent":["import { Select } from '@lucasbernardosn/react-ui/collections/select';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport { useSelector } from '@tanstack/react-store';\nimport type { RowData, TableFeatures } from '@tanstack/react-table';\nimport type React from 'react';\nimport type { TableWith } from '../../../types';\n\nexport type DataTablePageSizeSelectProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n React.ComponentProps<'div'>,\n {\n /** A tabela. Exige `rowPaginationFeature`. */\n table: TableWith<TFeatures, TData, 'rowPaginationFeature'>;\n /**\n * Os tamanhos oferecidos. O tamanho atual entra na lista mesmo fora dela.\n * @default [10, 25, 50, 100]\n */\n options?: readonly number[];\n /**\n * O rótulo do select.\n * @default 'Linhas por página'\n */\n label?: React.ReactNode;\n /**\n * O tamanho do select.\n * @default 'sm'\n */\n size?: Select.RootProps<number>['size'];\n }\n>;\n\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\n\n/**\n * O select de quantas linhas cada página mostra, com o rótulo ao lado. Trocar o tamanho chama o\n * `table.setPageSize`, que mantém à vista a primeira linha da página atual.\n *\n * Renderiza o `Select` do `ui` por dentro; as props passam para o elemento em volta do rótulo e do\n * trigger.\n *\n * @example\n * ```tsx\n * <DataTable.PageSizeSelect\n * table={table}\n * options={[20, 50, 100]}\n * />\n * ```\n */\nexport const DataTablePageSizeSelect = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTablePageSizeSelectProps<TFeatures, TData>,\n) => {\n const {\n table,\n options = DEFAULT_PAGE_SIZE_OPTIONS,\n label = 'Linhas por página',\n size = 'sm',\n className,\n ...rest\n } = props;\n\n /** Re-renderiza quando o tamanho da página muda. */\n const pageSize = useSelector(\n table.atoms.pagination,\n (pagination) => pagination.pageSize,\n );\n\n /** O tamanho atual entra na lista: sem ele, o trigger ficaria vazio. */\n const items = (options.includes(pageSize) ? options : [...options, pageSize])\n .toSorted((a, b) => a - b)\n .map((option) => ({\n label: option.toLocaleString('pt-BR'),\n value: option,\n }));\n\n return (\n <Select.Root<number>\n size={size}\n value={pageSize}\n items={items}\n onValueChange={(value) => {\n if (value !== null) {\n table.setPageSize(value);\n }\n }}\n >\n <div\n data-component=\"DataTable.PageSizeSelect\"\n className={mergeTwClassNames(\n ['flex', 'items-center', 'gap-2'],\n className,\n )}\n {...rest}\n >\n <Select.Label className=\"whitespace-nowrap font-normal text-gray-11\">\n {label}\n </Select.Label>\n\n <Select.Trigger>\n <Select.Value />\n <Select.Icon />\n </Select.Trigger>\n </div>\n\n <Select.Portal>\n <Select.Positioner alignItemWithTrigger={false}>\n <Select.Popup>\n <Select.List>\n {items.map((item) => (\n <Select.Item\n key={item.value}\n value={item.value}\n >\n <Select.ItemIndicator />\n <Select.ItemText>{item.label}</Select.ItemText>\n </Select.Item>\n ))}\n </Select.List>\n </Select.Popup>\n </Select.Positioner>\n </Select.Portal>\n </Select.Root>\n );\n};\n\nDataTablePageSizeSelect.displayName = 'DataTable.PageSizeSelect';\n"],"mappings":";;;;;AAkCA,MAAM,4BAA4B;CAAC;CAAI;CAAI;CAAI;AAAG;;;;;;;;;;;;;;;;AAiBlD,MAAa,2BAIX,UACG;CACH,MAAM,EACJ,OACA,UAAU,2BACV,QAAQ,qBACR,OAAO,MACP,WACA,GAAG,SACD;;CAGJ,MAAM,WAAW,YACf,MAAM,MAAM,aACX,eAAe,WAAW,QAC7B;;CAGA,MAAM,SAAS,QAAQ,SAAS,QAAQ,IAAI,UAAU,CAAC,GAAG,SAAS,QAAQ,EAAA,CACxE,UAAU,GAAG,MAAM,IAAI,CAAC,CAAC,CACzB,KAAK,YAAY;EAChB,OAAO,OAAO,eAAe,OAAO;EACpC,OAAO;CACT,EAAE;CAEJ,OACE,qBAAC,OAAO,MAAR;EACQ;EACN,OAAO;EACA;EACP,gBAAgB,UAAU;GACxB,IAAI,UAAU,MACZ,MAAM,YAAY,KAAK;EAE3B;EARF,UAAA,CAUE,qBAAC,OAAD;GACE,kBAAe;GACf,WAAW,kBACT;IAAC;IAAQ;IAAgB;GAAO,GAChC,SACF;GACA,GAAI;GANN,UAAA,CAQE,oBAAC,OAAO,OAAR;IAAc,WAAU;IACrB,UAAA;GACW,CAAA,GAEd,qBAAC,OAAO,SAAR,EAAA,UAAA,CACE,oBAAC,OAAO,OAAR,CAAe,CAAA,GACf,oBAAC,OAAO,MAAR,CAAc,CAAA,CACA,EAAA,CAAA,CACb;EAEL,CAAA,GAAA,oBAAC,OAAO,QAAR,EAAA,UACE,oBAAC,OAAO,YAAR;GAAmB,sBAAsB;GACvC,UAAA,oBAAC,OAAO,OAAR,EAAA,UACE,oBAAC,OAAO,MAAR,EAAA,UACG,MAAM,KAAK,SACV,qBAAC,OAAO,MAAR;IAEE,OAAO,KAAK;IAFd,UAAA,CAIE,oBAAC,OAAO,eAAR,CAAuB,CAAA,GACvB,oBAAC,OAAO,UAAR,EAAA,UAAkB,KAAK,MAAuB,CAAA,CACnC;GALN,GAAA,KAAK,KAKC,CACd,EACU,CAAA,EACD,CAAA;EACG,CAAA,EACN,CAAA,CACJ;;AAEjB;AAEA,wBAAwB,cAAc"}
|
|
1
|
+
{"version":3,"file":"data-table-page-size-select.js","names":[],"sources":["../../../../src/components/data-table/pagination/data-table-page-size-select.tsx"],"sourcesContent":["import { Select } from '@lucasbernardosn/react-ui/collections/select';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport { useSelector } from '@tanstack/react-store';\nimport type { RowData, TableFeatures } from '@tanstack/react-table';\nimport type React from 'react';\nimport type { TableWith } from '../../../types';\n\nexport type DataTablePageSizeSelectProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n React.ComponentProps<'div'>,\n {\n /** A tabela. Exige `rowPaginationFeature`. */\n table: TableWith<TFeatures, TData, 'rowPaginationFeature'>;\n /**\n * Os tamanhos oferecidos. O tamanho atual entra na lista mesmo fora dela.\n * @default [10, 25, 50, 100]\n */\n options?: readonly number[];\n /**\n * O rótulo do select.\n * @default 'Linhas por página'\n */\n label?: React.ReactNode;\n /**\n * O tamanho do select.\n * @default 'sm'\n */\n size?: Select.RootProps<number>['size'];\n }\n>;\n\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\n\n/**\n * O select de quantas linhas cada página mostra, com o rótulo ao lado. Trocar o tamanho chama o\n * `table.setPageSize`, que mantém à vista a primeira linha da página atual.\n *\n * Renderiza o `Select` do `ui` por dentro; as props passam para o elemento em volta do rótulo e do\n * trigger.\n *\n * @example\n * ```tsx\n * <DataTable.PageSizeSelect\n * table={table}\n * options={[20, 50, 100]}\n * />\n * ```\n */\nexport const DataTablePageSizeSelect = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTablePageSizeSelectProps<TFeatures, TData>,\n) => {\n const {\n table,\n options = DEFAULT_PAGE_SIZE_OPTIONS,\n label = 'Linhas por página',\n size = 'sm',\n className,\n ...rest\n } = props;\n\n /** Re-renderiza quando o tamanho da página muda. */\n const pageSize = useSelector(\n table.atoms.pagination,\n (pagination) => pagination.pageSize,\n );\n\n /** O tamanho atual entra na lista: sem ele, o trigger ficaria vazio. */\n const items = (options.includes(pageSize) ? options : [...options, pageSize])\n .toSorted((a, b) => a - b)\n .map((option) => ({\n label: option.toLocaleString('pt-BR'),\n value: option,\n }));\n\n return (\n <Select.Root<number>\n size={size}\n value={pageSize}\n items={items}\n onValueChange={(value) => {\n if (value !== null) {\n table.setPageSize(value);\n }\n }}\n >\n <div\n data-component=\"DataTable.PageSizeSelect\"\n className={mergeTwClassNames(\n ['flex', 'items-center', 'gap-2'],\n className,\n )}\n {...rest}\n >\n <Select.Label className=\"whitespace-nowrap font-normal text-gray-11\">\n {label}\n </Select.Label>\n\n <Select.Trigger>\n <Select.Value />\n <Select.Icon />\n </Select.Trigger>\n </div>\n\n <Select.Portal>\n <Select.Positioner alignItemWithTrigger={false}>\n <Select.Popup>\n <Select.List>\n {items.map((item) => (\n <Select.Item\n key={item.value}\n value={item.value}\n >\n <Select.ItemIndicator />\n <Select.ItemText>{item.label}</Select.ItemText>\n </Select.Item>\n ))}\n </Select.List>\n </Select.Popup>\n </Select.Positioner>\n </Select.Portal>\n </Select.Root>\n );\n};\n\nDataTablePageSizeSelect.displayName = 'DataTable.PageSizeSelect';\n"],"mappings":";;;;;AAkCA,MAAM,4BAA4B;CAAC;CAAI;CAAI;CAAI;AAAG;;;;;;;;;;;;;;;;AAiBlD,MAAa,2BAIX,UACG;CACH,MAAM,EACJ,OACA,UAAU,2BACV,QAAQ,qBACR,OAAO,MACP,WACA,GAAG,SACD;;CAGJ,MAAM,WAAW,YACf,MAAM,MAAM,aACX,eAAe,WAAW,QAC7B;;CAGA,MAAM,SAAS,QAAQ,SAAS,QAAQ,IAAI,UAAU,CAAC,GAAG,SAAS,QAAQ,EAAA,CACxE,UAAU,GAAG,MAAM,IAAI,CAAC,CAAC,CACzB,KAAK,YAAY;EAChB,OAAO,OAAO,eAAe,OAAO;EACpC,OAAO;CACT,EAAE;CAEJ,OACE,qBAAC,OAAO,MAAR;EACQ;EACN,OAAO;EACA;EACP,gBAAgB,UAAU;GACxB,IAAI,UAAU,MACZ,MAAM,YAAY,KAAK;EAE3B;EARF,UAAA,CAUE,qBAAC,OAAD;GACE,kBAAe;GACf,WAAW,kBACT;IAAC;IAAQ;IAAgB;GAAO,GAChC,SACF;GACA,GAAI;GANN,UAAA,CAQE,oBAAC,OAAO,OAAR;IAAc,WAAU;IACrB,UAAA;GACW,CAAA,GAEd,qBAAC,OAAO,SAAR,EAAA,UAAA,CACE,oBAAC,OAAO,OAAR,CAAe,CAAA,GACf,oBAAC,OAAO,MAAR,CAAc,CAAA,CACA,EAAA,CAAA,CACb;EAEL,CAAA,GAAA,oBAAC,OAAO,QAAR,EAAA,UACE,oBAAC,OAAO,YAAR;GAAmB,sBAAsB;GACvC,UAAA,oBAAC,OAAO,OAAR,EAAA,UACE,oBAAC,OAAO,MAAR,EAAA,UACG,MAAM,KAAK,SACV,qBAAC,OAAO,MAAR;IAEE,OAAO,KAAK;IAFd,UAAA,CAIE,oBAAC,OAAO,eAAR,CAAuB,CAAA,GACvB,oBAAC,OAAO,UAAR,EAAA,UAAkB,KAAK,MAAuB,CAAA,CACnC;GALN,GAAA,KAAK,KAKC,CACd,EACU,CAAA,EACD,CAAA;EACG,CAAA,EACN,CAAA,CACJ;;AAEjB;AAEA,wBAAwB,cAAc"}
|
|
@@ -3,7 +3,7 @@ import "../../../types/index.js";
|
|
|
3
3
|
import { RowData, TableFeatures } from "@tanstack/react-table";
|
|
4
4
|
import { useRender } from "@base-ui/react";
|
|
5
5
|
import React from "react";
|
|
6
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
6
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
7
7
|
//#region src/components/data-table/pagination/data-table-page-status.d.ts
|
|
8
8
|
/** A página atual e o total, para o texto do `DataTable.PageStatus`. */
|
|
9
9
|
export type DataTablePageStatusValues = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getDataTableLoadingWithoutRows } from "../loading/get-data-table-loading-without-rows.js";
|
|
2
2
|
import { mergeProps, useRender } from "@base-ui/react";
|
|
3
|
-
import { shallow, useSelector } from "@tanstack/react-store";
|
|
4
3
|
import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
|
|
4
|
+
import { shallow, useSelector } from "@tanstack/react-store";
|
|
5
5
|
//#region src/components/data-table/pagination/data-table-page-status.tsx
|
|
6
6
|
/**
|
|
7
7
|
* Qual a página atual, e de quantas: "Página 2 de 10". Sem o total de páginas, só "Página 2",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-page-status.js","names":[],"sources":["../../../../src/components/data-table/pagination/data-table-page-status.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport { shallow, useSelector } from '@tanstack/react-store';\nimport type { RowData, TableFeatures } from '@tanstack/react-table';\nimport type React from 'react';\nimport type { TableWith } from '../../../types';\nimport { getDataTableLoadingWithoutRows } from '../loading/get-data-table-loading-without-rows';\n\n/** A página atual e o total, para o texto do `DataTable.PageStatus`. */\nexport type DataTablePageStatusValues = {\n /** O índice da página atual, a partir de 0. */\n pageIndex: number;\n /**\n * O total de páginas, ou `-1` sem ele: quando a API não informa (`pageCount: -1`) e, com\n * `loadingFeature`, na carga sem linhas, antes de o total chegar.\n */\n pageCount: number;\n};\n\nexport type DataTablePageStatusProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'span'>,\n {\n /** A tabela. Exige `rowPaginationFeature`. */\n table: TableWith<TFeatures, TData, 'rowPaginationFeature'>;\n /**\n * Uma função que recebe a página e o total e devolve o texto.\n * @default ({ pageIndex, pageCount }) => 'Página 2 de 10', ou 'Página 2' sem o total\n */\n children?: (values: DataTablePageStatusValues) => React.ReactNode;\n }\n>;\n\n/**\n * Qual a página atual, e de quantas: \"Página 2 de 10\". Sem o total de páginas, só \"Página 2\",\n * também na primeira carga, quando o total ainda não chegou.\n *\n * @example\n * ```tsx\n * <DataTable.PageStatus table={table}>\n * {({ pageIndex, pageCount }) => `${pageIndex + 1}/${pageCount}`}\n * </DataTable.PageStatus>\n * ```\n */\nexport const DataTablePageStatus = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTablePageStatusProps<TFeatures, TData>,\n) => {\n const { table, render, className, children, ...rest } = props;\n\n /**\n * Re-renderiza quando a página ou o total mudam. O store, e não só o atom da paginação: o total\n * também muda com as linhas.\n */\n const values = useSelector(\n table.store,\n (): DataTablePageStatusValues => ({\n pageIndex: table.atoms.pagination.get().pageIndex,\n pageCount: getDataTableLoadingWithoutRows(table)\n ? -1\n : table.getPageCount(),\n }),\n { compare: shallow },\n );\n\n const page = (values.pageIndex + 1).toLocaleString('pt-BR');\n\n const baseProps = {\n 'data-component': 'DataTable.PageStatus',\n className: mergeTwClassNames(\n ['text-gray-11', 'text-sm', 'tabular-nums', 'whitespace-nowrap'],\n className,\n ),\n children:\n children === undefined\n ? values.pageCount === -1\n ? `Página ${page}`\n : // Sem linhas, o total é 0, e a página 1 continua sendo a atual.\n `Página ${page} de ${Math.max(values.pageCount, 1).toLocaleString('pt-BR')}`\n : children(values),\n };\n\n return useRender({\n render,\n defaultTagName: 'span',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTablePageStatus.displayName = 'DataTable.PageStatus';\n"],"mappings":";;;;;;;;;;;;;;;;AA+CA,MAAa,uBAIX,UACG;CACH,MAAM,EAAE,OAAO,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;CAMxD,MAAM,SAAS,YACb,MAAM,cAC4B;EAChC,WAAW,MAAM,MAAM,WAAW,IAAI,CAAC,CAAC;EACxC,WAAW,+BAA+B,KAAK,IAC3C,KACA,MAAM,aAAa;CACzB,IACA,EAAE,SAAS,QAAQ,CACrB;CAEA,MAAM,QAAQ,OAAO,YAAY,EAAA,CAAG,eAAe,OAAO;CAE1D,MAAM,YAAY;EAChB,kBAAkB;EAClB,WAAW,kBACT;GAAC;GAAgB;GAAW;GAAgB;EAAmB,GAC/D,SACF;EACA,UACE,aAAa,KAAA,IACT,OAAO,cAAc,KACnB,UAAU,SAEV,UAAU,KAAK,MAAM,KAAK,IAAI,OAAO,WAAW,CAAC,CAAC,CAAC,eAAe,OAAO,MAC3E,SAAS,MAAM;CACvB;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,oBAAoB,cAAc"}
|
|
1
|
+
{"version":3,"file":"data-table-page-status.js","names":[],"sources":["../../../../src/components/data-table/pagination/data-table-page-status.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport { shallow, useSelector } from '@tanstack/react-store';\nimport type { RowData, TableFeatures } from '@tanstack/react-table';\nimport type React from 'react';\nimport type { TableWith } from '../../../types';\nimport { getDataTableLoadingWithoutRows } from '../loading/get-data-table-loading-without-rows';\n\n/** A página atual e o total, para o texto do `DataTable.PageStatus`. */\nexport type DataTablePageStatusValues = {\n /** O índice da página atual, a partir de 0. */\n pageIndex: number;\n /**\n * O total de páginas, ou `-1` sem ele: quando a API não informa (`pageCount: -1`) e, com\n * `loadingFeature`, na carga sem linhas, antes de o total chegar.\n */\n pageCount: number;\n};\n\nexport type DataTablePageStatusProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'span'>,\n {\n /** A tabela. Exige `rowPaginationFeature`. */\n table: TableWith<TFeatures, TData, 'rowPaginationFeature'>;\n /**\n * Uma função que recebe a página e o total e devolve o texto.\n * @default ({ pageIndex, pageCount }) => 'Página 2 de 10', ou 'Página 2' sem o total\n */\n children?: (values: DataTablePageStatusValues) => React.ReactNode;\n }\n>;\n\n/**\n * Qual a página atual, e de quantas: \"Página 2 de 10\". Sem o total de páginas, só \"Página 2\",\n * também na primeira carga, quando o total ainda não chegou.\n *\n * @example\n * ```tsx\n * <DataTable.PageStatus table={table}>\n * {({ pageIndex, pageCount }) => `${pageIndex + 1}/${pageCount}`}\n * </DataTable.PageStatus>\n * ```\n */\nexport const DataTablePageStatus = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTablePageStatusProps<TFeatures, TData>,\n) => {\n const { table, render, className, children, ...rest } = props;\n\n /**\n * Re-renderiza quando a página ou o total mudam. O store, e não só o atom da paginação: o total\n * também muda com as linhas.\n */\n const values = useSelector(\n table.store,\n (): DataTablePageStatusValues => ({\n pageIndex: table.atoms.pagination.get().pageIndex,\n pageCount: getDataTableLoadingWithoutRows(table)\n ? -1\n : table.getPageCount(),\n }),\n { compare: shallow },\n );\n\n const page = (values.pageIndex + 1).toLocaleString('pt-BR');\n\n const baseProps = {\n 'data-component': 'DataTable.PageStatus',\n className: mergeTwClassNames(\n ['text-gray-11', 'text-sm', 'tabular-nums', 'whitespace-nowrap'],\n className,\n ),\n children:\n children === undefined\n ? values.pageCount === -1\n ? `Página ${page}`\n : // Sem linhas, o total é 0, e a página 1 continua sendo a atual.\n `Página ${page} de ${Math.max(values.pageCount, 1).toLocaleString('pt-BR')}`\n : children(values),\n };\n\n return useRender({\n render,\n defaultTagName: 'span',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTablePageStatus.displayName = 'DataTable.PageStatus';\n"],"mappings":";;;;;;;;;;;;;;;;AA+CA,MAAa,uBAIX,UACG;CACH,MAAM,EAAE,OAAO,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;CAMxD,MAAM,SAAS,YACb,MAAM,cAC4B;EAChC,WAAW,MAAM,MAAM,WAAW,IAAI,CAAC,CAAC;EACxC,WAAW,+BAA+B,KAAK,IAC3C,KACA,MAAM,aAAa;CACzB,IACA,EAAE,SAAS,QAAQ,CACrB;CAEA,MAAM,QAAQ,OAAO,YAAY,EAAA,CAAG,eAAe,OAAO;CAE1D,MAAM,YAAY;EAChB,kBAAkB;EAClB,WAAW,kBACT;GAAC;GAAgB;GAAW;GAAgB;EAAmB,GAC/D,SACF;EACA,UACE,aAAa,KAAA,IACT,OAAO,cAAc,KACnB,UAAU,SAEV,UAAU,KAAK,MAAM,KAAK,IAAI,OAAO,WAAW,CAAC,CAAC,CAAC,eAAe,OAAO,MAC3E,SAAS,MAAM;CACvB;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,oBAAoB,cAAc"}
|
|
@@ -2,7 +2,7 @@ import { TableWith } from "../../../types/table-with.js";
|
|
|
2
2
|
import "../../../types/index.js";
|
|
3
3
|
import { RowData, TableFeatures } from "@tanstack/react-table";
|
|
4
4
|
import { useRender } from "@base-ui/react";
|
|
5
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
5
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
6
6
|
//#region src/components/data-table/pagination/data-table-pagination.d.ts
|
|
7
7
|
export type DataTablePaginationProps<TFeatures extends TableFeatures, TData extends RowData> = MergeOverride<useRender.ComponentProps<'nav'>, {
|
|
8
8
|
/** A tabela. Exige `rowPaginationFeature`. */
|
|
@@ -4,9 +4,9 @@ import { DataTablePageSizeSelect } from "./data-table-page-size-select.js";
|
|
|
4
4
|
import { DataTablePageStatus } from "./data-table-page-status.js";
|
|
5
5
|
import { DataTableRowRange } from "./data-table-row-range.js";
|
|
6
6
|
import { DataTableSelectedCount } from "./data-table-selected-count.js";
|
|
7
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
7
|
import { mergeProps, useRender } from "@base-ui/react";
|
|
9
8
|
import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
|
|
9
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
//#region src/components/data-table/pagination/data-table-pagination.tsx
|
|
11
11
|
/**
|
|
12
12
|
* A barra da paginação, para baixo da tabela. Sem `children`, monta o padrão: à esquerda, a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table-pagination.js","names":[],"sources":["../../../../src/components/data-table/pagination/data-table-pagination.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport type { RowData, TableFeatures } from '@tanstack/react-table';\nimport type { TableWith } from '../../../types';\nimport { hasTableFeature } from '../../../utils';\nimport { DataTablePageButton } from './data-table-page-button';\nimport { DataTablePageSizeSelect } from './data-table-page-size-select';\nimport { DataTablePageStatus } from './data-table-page-status';\nimport { DataTableRowRange } from './data-table-row-range';\nimport { DataTableSelectedCount } from './data-table-selected-count';\n\nexport type DataTablePaginationProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'nav'>,\n {\n /** A tabela. Exige `rowPaginationFeature`. */\n table: TableWith<TFeatures, TData, 'rowPaginationFeature'>;\n }\n>;\n\n/**\n * A barra da paginação, para baixo da tabela. Sem `children`, monta o padrão: à esquerda, a\n * contagem de selecionadas (com `rowSelectionFeature`); à direita, o `DataTable.PageSizeSelect`,\n * o `DataTable.RowRange`, o `DataTable.PageStatus` e os quatro `DataTable.PageButton`. Com\n * `children`, o app compõe as partes, cada uma com a `table`. Em tela estreita, os grupos quebram\n * linha.\n *\n * Funciona com a paginação local (`createPaginatedRowModel`) e com a da API\n * (`manualPagination`, com o `rowCount` ou o `pageCount`).\n *\n * É um `nav` com o nome \"Paginação\", trocável pelo `aria-label`: um marco, que o leitor de tela\n * lista e para onde salta.\n *\n * @example\n * ```tsx\n * <DataTable.Pagination table={table}>\n * <DataTable.PageStatus table={table} />\n * <DataTable.PageButton table={table} page=\"previous\" />\n * <DataTable.PageButton table={table} page=\"next\" />\n * </DataTable.Pagination>\n * ```\n */\nexport const DataTablePagination = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTablePaginationProps<TFeatures, TData>,\n) => {\n const { table, render, className, children, ...rest } = props;\n\n const content =\n children === undefined ? (\n <>\n {hasTableFeature(table, 'rowSelectionFeature') && (\n <DataTableSelectedCount table={table} />\n )}\n\n {/* À direita mesmo sozinho, sem a contagem: o `justify-between` o levaria para a\n esquerda. */}\n <div className=\"ms-auto flex flex-wrap items-center gap-x-4 gap-y-2\">\n <DataTablePageSizeSelect table={table} />\n <DataTableRowRange table={table} />\n <DataTablePageStatus table={table} />\n\n <div className=\"flex items-center gap-1\">\n <DataTablePageButton\n table={table}\n page=\"first\"\n />\n <DataTablePageButton\n table={table}\n page=\"previous\"\n />\n <DataTablePageButton\n table={table}\n page=\"next\"\n />\n <DataTablePageButton\n table={table}\n page=\"last\"\n />\n </div>\n </div>\n </>\n ) : (\n children\n );\n\n const baseProps = {\n 'data-component': 'DataTable.Pagination',\n 'aria-label': 'Paginação',\n className: mergeTwClassNames(\n [\n 'flex',\n 'flex-wrap',\n 'items-center',\n 'justify-between',\n 'gap-x-6',\n 'gap-y-2',\n ],\n className,\n ),\n children: content,\n };\n\n return useRender({\n render,\n defaultTagName: 'nav',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTablePagination.displayName = 'DataTable.Pagination';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,MAAa,uBAIX,UACG;CACH,MAAM,EAAE,OAAO,QAAQ,WAAW,UAAU,GAAG,SAAS;CAExD,MAAM,UACJ,aAAa,KAAA,IACX,qBAAA,UAAA,EAAA,UAAA,CACG,gBAAgB,OAAO,qBAAqB,KAC3C,oBAAC,wBAAD,EAA+B,MAAQ,CAAA,GAKzC,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,yBAAD,EAAgC,MAAQ,CAAA;GACxC,oBAAC,mBAAD,EAA0B,MAAQ,CAAA;GAClC,oBAAC,qBAAD,EAA4B,MAAQ,CAAA;GAEpC,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,qBAAD;MACS;MACP,MAAK;KACN,CAAA;KACD,oBAAC,qBAAD;MACS;MACP,MAAK;KACN,CAAA;KACD,oBAAC,qBAAD;MACS;MACP,MAAK;KACN,CAAA;KACD,oBAAC,qBAAD;MACS;MACP,MAAK;KACN,CAAA;IACE;;EACF;CACL,CAAA,CAAA,EAAA,CAAA,IAEF;CAGJ,MAAM,YAAY;EAChB,kBAAkB;EAClB,cAAc;EACd,WAAW,kBACT;GACE;GACA;GACA;GACA;GACA;GACA;EACF,GACA,SACF;EACA,UAAU;CACZ;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,oBAAoB,cAAc"}
|
|
1
|
+
{"version":3,"file":"data-table-pagination.js","names":[],"sources":["../../../../src/components/data-table/pagination/data-table-pagination.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/ts-utils';\nimport type { RowData, TableFeatures } from '@tanstack/react-table';\nimport type { TableWith } from '../../../types';\nimport { hasTableFeature } from '../../../utils';\nimport { DataTablePageButton } from './data-table-page-button';\nimport { DataTablePageSizeSelect } from './data-table-page-size-select';\nimport { DataTablePageStatus } from './data-table-page-status';\nimport { DataTableRowRange } from './data-table-row-range';\nimport { DataTableSelectedCount } from './data-table-selected-count';\n\nexport type DataTablePaginationProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'nav'>,\n {\n /** A tabela. Exige `rowPaginationFeature`. */\n table: TableWith<TFeatures, TData, 'rowPaginationFeature'>;\n }\n>;\n\n/**\n * A barra da paginação, para baixo da tabela. Sem `children`, monta o padrão: à esquerda, a\n * contagem de selecionadas (com `rowSelectionFeature`); à direita, o `DataTable.PageSizeSelect`,\n * o `DataTable.RowRange`, o `DataTable.PageStatus` e os quatro `DataTable.PageButton`. Com\n * `children`, o app compõe as partes, cada uma com a `table`. Em tela estreita, os grupos quebram\n * linha.\n *\n * Funciona com a paginação local (`createPaginatedRowModel`) e com a da API\n * (`manualPagination`, com o `rowCount` ou o `pageCount`).\n *\n * É um `nav` com o nome \"Paginação\", trocável pelo `aria-label`: um marco, que o leitor de tela\n * lista e para onde salta.\n *\n * @example\n * ```tsx\n * <DataTable.Pagination table={table}>\n * <DataTable.PageStatus table={table} />\n * <DataTable.PageButton table={table} page=\"previous\" />\n * <DataTable.PageButton table={table} page=\"next\" />\n * </DataTable.Pagination>\n * ```\n */\nexport const DataTablePagination = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTablePaginationProps<TFeatures, TData>,\n) => {\n const { table, render, className, children, ...rest } = props;\n\n const content =\n children === undefined ? (\n <>\n {hasTableFeature(table, 'rowSelectionFeature') && (\n <DataTableSelectedCount table={table} />\n )}\n\n {/* À direita mesmo sozinho, sem a contagem: o `justify-between` o levaria para a\n esquerda. */}\n <div className=\"ms-auto flex flex-wrap items-center gap-x-4 gap-y-2\">\n <DataTablePageSizeSelect table={table} />\n <DataTableRowRange table={table} />\n <DataTablePageStatus table={table} />\n\n <div className=\"flex items-center gap-1\">\n <DataTablePageButton\n table={table}\n page=\"first\"\n />\n <DataTablePageButton\n table={table}\n page=\"previous\"\n />\n <DataTablePageButton\n table={table}\n page=\"next\"\n />\n <DataTablePageButton\n table={table}\n page=\"last\"\n />\n </div>\n </div>\n </>\n ) : (\n children\n );\n\n const baseProps = {\n 'data-component': 'DataTable.Pagination',\n 'aria-label': 'Paginação',\n className: mergeTwClassNames(\n [\n 'flex',\n 'flex-wrap',\n 'items-center',\n 'justify-between',\n 'gap-x-6',\n 'gap-y-2',\n ],\n className,\n ),\n children: content,\n };\n\n return useRender({\n render,\n defaultTagName: 'nav',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTablePagination.displayName = 'DataTable.Pagination';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,MAAa,uBAIX,UACG;CACH,MAAM,EAAE,OAAO,QAAQ,WAAW,UAAU,GAAG,SAAS;CAExD,MAAM,UACJ,aAAa,KAAA,IACX,qBAAA,UAAA,EAAA,UAAA,CACG,gBAAgB,OAAO,qBAAqB,KAC3C,oBAAC,wBAAD,EAA+B,MAAQ,CAAA,GAKzC,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,yBAAD,EAAgC,MAAQ,CAAA;GACxC,oBAAC,mBAAD,EAA0B,MAAQ,CAAA;GAClC,oBAAC,qBAAD,EAA4B,MAAQ,CAAA;GAEpC,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,qBAAD;MACS;MACP,MAAK;KACN,CAAA;KACD,oBAAC,qBAAD;MACS;MACP,MAAK;KACN,CAAA;KACD,oBAAC,qBAAD;MACS;MACP,MAAK;KACN,CAAA;KACD,oBAAC,qBAAD;MACS;MACP,MAAK;KACN,CAAA;IACE;;EACF;CACL,CAAA,CAAA,EAAA,CAAA,IAEF;CAGJ,MAAM,YAAY;EAChB,kBAAkB;EAClB,cAAc;EACd,WAAW,kBACT;GACE;GACA;GACA;GACA;GACA;GACA;EACF,GACA,SACF;EACA,UAAU;CACZ;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,oBAAoB,cAAc"}
|
|
@@ -3,7 +3,7 @@ import "../../../types/index.js";
|
|
|
3
3
|
import { RowData, TableFeatures } from "@tanstack/react-table";
|
|
4
4
|
import { useRender } from "@base-ui/react";
|
|
5
5
|
import React from "react";
|
|
6
|
-
import { MergeOverride } from "@lucasbernardosn/utils";
|
|
6
|
+
import { MergeOverride } from "@lucasbernardosn/ts-utils";
|
|
7
7
|
//#region src/components/data-table/pagination/data-table-row-range.d.ts
|
|
8
8
|
/** As linhas da página atual e o total, para o texto do `DataTable.RowRange`. */
|
|
9
9
|
export type DataTableRowRangeValues = {
|