diff --git a/examples/angular/basic-external-atoms/src/app/app.ts b/examples/angular/basic-external-atoms/src/app/app.ts index ba5cf40d2d..99abe83fb2 100644 --- a/examples/angular/basic-external-atoms/src/app/app.ts +++ b/examples/angular/basic-external-atoms/src/app/app.ts @@ -1,8 +1,8 @@ import { ChangeDetectionStrategy, Component, - effect, Injector, + effect, inject, signal, } from '@angular/core' diff --git a/examples/angular/row-selection-signal/src/app/app.component.ts b/examples/angular/row-selection-signal/src/app/app.component.ts index 0efb7be024..439bfebb49 100644 --- a/examples/angular/row-selection-signal/src/app/app.component.ts +++ b/examples/angular/row-selection-signal/src/app/app.component.ts @@ -1,8 +1,8 @@ import { ChangeDetectionStrategy, Component, - computed, Injector, + computed, inject, signal, viewChild, diff --git a/examples/angular/row-selection/src/app/app.ts b/examples/angular/row-selection/src/app/app.ts index 03560f13c9..9de3acfd3c 100644 --- a/examples/angular/row-selection/src/app/app.ts +++ b/examples/angular/row-selection/src/app/app.ts @@ -1,8 +1,8 @@ import { ChangeDetectionStrategy, Component, - computed, Injector, + computed, inject, signal, } from '@angular/core' diff --git a/examples/angular/with-tanstack-form/src/app/app.ts b/examples/angular/with-tanstack-form/src/app/app.ts index c36ef586db..1c731794c9 100644 --- a/examples/angular/with-tanstack-form/src/app/app.ts +++ b/examples/angular/with-tanstack-form/src/app/app.ts @@ -1,8 +1,8 @@ import { ChangeDetectionStrategy, Component, - effect, Injector, + effect, inject, signal, untracked, diff --git a/examples/react/kitchen-sink-chakra-ui/src/components/data-table/shared.tsx b/examples/react/kitchen-sink-chakra-ui/src/components/data-table/shared.tsx index 2bbdb59d5a..5795a7635a 100644 --- a/examples/react/kitchen-sink-chakra-ui/src/components/data-table/shared.tsx +++ b/examples/react/kitchen-sink-chakra-ui/src/components/data-table/shared.tsx @@ -232,7 +232,7 @@ export function CheckboxField({ checked={indeterminate ? 'indeterminate' : checked} onCheckedChange={(details) => onCheckedChange?.(details.checked === true)} > - + {label ? {label} : null} diff --git a/examples/react/kitchen-sink-hero-ui/src/components/data-table/data-table-filter-list.tsx b/examples/react/kitchen-sink-hero-ui/src/components/data-table/data-table-filter-list.tsx index 985dfc3ec6..fcfffc96b4 100644 --- a/examples/react/kitchen-sink-hero-ui/src/components/data-table/data-table-filter-list.tsx +++ b/examples/react/kitchen-sink-hero-ui/src/components/data-table/data-table-filter-list.tsx @@ -188,7 +188,7 @@ export function DataTableFilterList(): React.ReactNode { setColumnFilters( columnFilters.map((filter: ExtendedColumnFilter) => filter.filterId === filterId ? { ...filter, ...patch } : filter, - ) as any, + ), ) } @@ -240,7 +240,7 @@ export function DataTableFilterList(): React.ReactNode { columnFilters.map((item: ExtendedColumnFilter) => ({ ...item, joinOperator: joinOperator as 'and' | 'or', - })) as any, + })), ) } /> @@ -293,7 +293,7 @@ export function DataTableFilterList(): React.ReactNode { columnFilters.filter( (item: ExtendedColumnFilter) => item.filterId !== filter.filterId, - ) as any, + ), ) } > @@ -309,7 +309,7 @@ export function DataTableFilterList(): React.ReactNode { diff --git a/examples/react/kitchen-sink-hero-ui/src/main.tsx b/examples/react/kitchen-sink-hero-ui/src/main.tsx index 4676ffc00e..1a202206f0 100644 --- a/examples/react/kitchen-sink-hero-ui/src/main.tsx +++ b/examples/react/kitchen-sink-hero-ui/src/main.tsx @@ -6,10 +6,10 @@ import * as ReactDOM from 'react-dom/client' import { useDebouncedCallback } from '@tanstack/react-pacer/debouncer' import { Button, + Table as HeroTable, Input, Surface, Switch, - Table as HeroTable, Tooltip, cn, useTheme, diff --git a/examples/react/kitchen-sink-mantine/src/components/data-table/data-table-filter-list.tsx b/examples/react/kitchen-sink-mantine/src/components/data-table/data-table-filter-list.tsx index 2020e78f2e..efb3905fdc 100644 --- a/examples/react/kitchen-sink-mantine/src/components/data-table/data-table-filter-list.tsx +++ b/examples/react/kitchen-sink-mantine/src/components/data-table/data-table-filter-list.tsx @@ -18,12 +18,12 @@ import { IconFilter, IconTrash } from '@tabler/icons-react' import type { Column, RowData } from '@tanstack/react-table' import type { ExtendedColumnFilter } from '@/types' import type { features } from '@/hooks/features' - -type AppColumn = Column import { useTableContext } from '@/hooks/table' import { getFilterOperators } from '@/lib/data-table' import { toDateInputValue } from '@/components/data-table/shared' +type AppColumn = Column + function FilterValueInput({ column, filter, diff --git a/examples/react/kitchen-sink-mantine/src/components/data-table/data-table-view-options.tsx b/examples/react/kitchen-sink-mantine/src/components/data-table/data-table-view-options.tsx index 476401c250..6c7740fa3e 100644 --- a/examples/react/kitchen-sink-mantine/src/components/data-table/data-table-view-options.tsx +++ b/examples/react/kitchen-sink-mantine/src/components/data-table/data-table-view-options.tsx @@ -26,9 +26,9 @@ import type { DragEndEvent } from '@dnd-kit/core' import type { Column, RowData } from '@tanstack/react-table' import type { features } from '@/hooks/features' import { useTableContext } from '@/hooks/table' +import { SortableFrame } from '@/components/data-table/shared' type AppColumn = Column -import { SortableFrame } from '@/components/data-table/shared' export function DataTableViewOptions(): React.ReactNode { const table = useTableContext() diff --git a/examples/react/kitchen-sink-material-ui/src/main.tsx b/examples/react/kitchen-sink-material-ui/src/main.tsx index 9b7c5612e0..c48fde58a5 100644 --- a/examples/react/kitchen-sink-material-ui/src/main.tsx +++ b/examples/react/kitchen-sink-material-ui/src/main.tsx @@ -12,9 +12,9 @@ import { InputAdornment, Menu, MenuItem, + Table as MuiTable, Paper, Stack, - Table as MuiTable, TableBody, TableCell, TableContainer, diff --git a/examples/react/kitchen-sink-react-aria/src/components/data-table/data-table-filter-list.tsx b/examples/react/kitchen-sink-react-aria/src/components/data-table/data-table-filter-list.tsx index 49d67ab39c..9620ca8202 100644 --- a/examples/react/kitchen-sink-react-aria/src/components/data-table/data-table-filter-list.tsx +++ b/examples/react/kitchen-sink-react-aria/src/components/data-table/data-table-filter-list.tsx @@ -197,7 +197,7 @@ export function DataTableFilterList(): React.ReactNode { setColumnFilters( columnFilters.map((filter) => filter.filterId === filterId ? { ...filter, ...patch } : filter, - ) as any, + ), ) } @@ -212,8 +212,8 @@ export function DataTableFilterList(): React.ReactNode { value: '', operator: 'includesString', joinOperator: columnFilters[0]?.joinOperator ?? 'and', - } as ExtendedColumnFilter, - ] as any) + }, + ]) } return ( @@ -249,7 +249,7 @@ export function DataTableFilterList(): React.ReactNode { columnFilters.map((item) => ({ ...item, joinOperator: joinOperator as 'and' | 'or', - })) as any, + })), ) } /> @@ -299,7 +299,7 @@ export function DataTableFilterList(): React.ReactNode { setColumnFilters( columnFilters.filter( (item) => item.filterId !== filter.filterId, - ) as any, + ), ) } > diff --git a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-filter-list.tsx b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-filter-list.tsx index 1900ede680..ba06210b9c 100644 --- a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-filter-list.tsx +++ b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-filter-list.tsx @@ -9,11 +9,7 @@ import { ListFilter, Trash2, } from 'lucide-react' -import type { - ExtendedColumnFilter, - FilterOperator, - JoinOperator, -} from '@/types' +import type { ExtendedColumnFilter, FilterOperator } from '@/types' import type { Column, RowData } from '@tanstack/react-table' import type { features } from '@/hooks/features' @@ -670,7 +666,7 @@ export function DataTableFilterList(): React.ReactNode { if (columnFilters.length > 0) { const updatedFilters = columnFilters.map((f) => ({ ...f, - joinOperator: value as JoinOperator, + joinOperator: value, })) setColumnFilters(updatedFilters) } diff --git a/examples/react/material-react-table/src/main.tsx b/examples/react/material-react-table/src/main.tsx index 664105ac50..e4a0a2e2af 100644 --- a/examples/react/material-react-table/src/main.tsx +++ b/examples/react/material-react-table/src/main.tsx @@ -16,6 +16,7 @@ import { } from './material-react-table' import { makeData } from './makeData' import type { Person } from './makeData' +import type { MRT_ColumnDef } from './material-react-table' import './index.css' const columnHelper = createMRTColumnHelper() @@ -109,8 +110,8 @@ const theme = createTheme({ function App() { const [data, setData] = React.useState(() => makeData(50)) - const table = useMaterialReactTable({ - columns, + const table = useMaterialReactTable({ + columns: columns as Array>, data, enableColumnFilters: true, enableColumnOrdering: true, diff --git a/examples/react/material-react-table/src/material-react-table/components/MaterialReactTable.tsx b/examples/react/material-react-table/src/material-react-table/components/MaterialReactTable.tsx index 8192420e02..fe2661a43a 100644 --- a/examples/react/material-react-table/src/material-react-table/components/MaterialReactTable.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/MaterialReactTable.tsx @@ -32,5 +32,15 @@ export const MaterialReactTable = ( table = useMaterialReactTable(props) } - return + // `AppTable` (attached by `useAppTable`) provides the table via React context + // so MRT components can read it with `useTableContext()` instead of a prop. + const AppTable = (table as any).AppTable as React.FC<{ + children: React.ReactNode + }> + + return ( + + + + ) } diff --git a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBody.tsx b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBody.tsx index b738f2b2fa..85a0ddd0c7 100644 --- a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBody.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBody.tsx @@ -4,28 +4,21 @@ import Typography from '@mui/material/Typography' import { useMRT_RowVirtualizer } from '../../hooks/useMRT_RowVirtualizer' import { useMRT_Rows } from '../../hooks/useMRT_Rows' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableBodyRow, Memo_MRT_TableBodyRow } from './MRT_TableBodyRow' -import type { - MRT_ColumnVirtualizer, - MRT_Row, - MRT_RowData, - MRT_TableInstance, -} from '../../types' +import type { MRT_ColumnVirtualizer, MRT_Row, MRT_RowData } from '../../types' import type { TableBodyProps } from '@mui/material/TableBody' import type { VirtualItem } from '@tanstack/react-virtual' -export interface MRT_TableBodyProps< - TData extends MRT_RowData, -> extends TableBodyProps { +export interface MRT_TableBodyProps extends TableBodyProps { columnVirtualizer?: MRT_ColumnVirtualizer - table: MRT_TableInstance } -export const MRT_TableBody = ({ +export const MRT_TableBody = ({ columnVirtualizer, - table, ...rest -}: MRT_TableBodyProps) => { +}: MRT_TableBodyProps) => { + const table = useMRTContext() const { getBottomRows, getIsSomeRowsPinned, @@ -75,7 +68,6 @@ export const MRT_TableBody = ({ const commonRowProps = { columnVirtualizer, numRows: rows.length, - table, } return ( @@ -219,7 +211,4 @@ export const MRT_TableBody = ({ ) } -export const Memo_MRT_TableBody = memo( - MRT_TableBody, - (prev, next) => prev.table.options.data === next.table.options.data, -) as typeof MRT_TableBody +export const Memo_MRT_TableBody = memo(MRT_TableBody) as typeof MRT_TableBody diff --git a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyCell.tsx b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyCell.tsx index b2becd7347..f99cdb0920 100644 --- a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyCell.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyCell.tsx @@ -11,8 +11,9 @@ import { getCommonMRTCellStyles } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_CopyButton } from '../buttons/MRT_CopyButton' import { MRT_EditCellTextField } from '../inputs/MRT_EditCellTextField' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableBodyCellValue } from './MRT_TableBodyCellValue' -import type { MRT_Cell, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Cell, MRT_RowData } from '../../types' import type { TableCellProps } from '@mui/material/TableCell' import type { DragEvent, MouseEvent, RefObject } from 'react' @@ -24,7 +25,6 @@ export interface MRT_TableBodyCellProps< rowRef: RefObject staticColumnIndex?: number staticRowIndex: number - table: MRT_TableInstance } export const MRT_TableBodyCell = ({ @@ -33,9 +33,9 @@ export const MRT_TableBodyCell = ({ rowRef, staticColumnIndex, staticRowIndex, - table, ...rest }: MRT_TableBodyCellProps) => { + const table = useMRTContext() const theme = useTheme() const { state, @@ -185,7 +185,6 @@ export const MRT_TableBodyCell = ({ const cellValueProps = { cell, - table, staticColumnIndex, staticRowIndex, } @@ -316,9 +315,9 @@ export const MRT_TableBodyCell = ({ table, }) ) : isCreating || isEditing ? ( - + ) : showClickToCopyButton && columnDef.enableClickToCopy !== false ? ( - + ) : ( diff --git a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyCellValue.tsx b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyCellValue.tsx index 87e65c8a12..5ad2d32ccf 100644 --- a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyCellValue.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyCellValue.tsx @@ -1,7 +1,8 @@ import Box from '@mui/material/Box' import highlightWords from 'highlight-words' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { ReactNode, RefObject } from 'react' -import type { MRT_Cell, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Cell, MRT_RowData } from '../../types' const allowedTypes = ['string', 'number'] @@ -10,7 +11,6 @@ export interface MRT_TableBodyCellValueProps { rowRef?: RefObject staticColumnIndex?: number staticRowIndex?: number - table: MRT_TableInstance } export const MRT_TableBodyCellValue = ({ @@ -18,8 +18,8 @@ export const MRT_TableBodyCellValue = ({ rowRef, staticColumnIndex, staticRowIndex, - table, }: MRT_TableBodyCellValueProps) => { + const table = useMRTContext() const { state, options: { diff --git a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRow.tsx b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRow.tsx index 7ad62b49c7..303b5ce12a 100644 --- a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRow.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRow.tsx @@ -7,6 +7,7 @@ import { getCommonPinnedCellStyles, } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableDetailPanel } from './MRT_TableDetailPanel' import { MRT_TableBodyCell, Memo_MRT_TableBodyCell } from './MRT_TableBodyCell' import type { @@ -15,7 +16,6 @@ import type { MRT_Row, MRT_RowData, MRT_RowVirtualizer, - MRT_TableInstance, MRT_VirtualItem, } from '../../types' import type { Theme } from '@mui/material/styles' @@ -32,7 +32,6 @@ export interface MRT_TableBodyRowProps< row: MRT_Row rowVirtualizer?: MRT_RowVirtualizer staticRowIndex: number - table: MRT_TableInstance virtualRow?: VirtualItem } @@ -43,10 +42,10 @@ export const MRT_TableBodyRow = ({ row, rowVirtualizer, staticRowIndex, - table, virtualRow, ...rest }: MRT_TableBodyRowProps) => { + const table = useMRTContext() const theme = useTheme() const { @@ -244,7 +243,6 @@ export const MRT_TableBodyRow = ({ rowRef, staticColumnIndex, staticRowIndex, - table, } const key = `${cell.id}-${staticRowIndex}` return cell ? ( @@ -271,7 +269,6 @@ export const MRT_TableBodyRow = ({ row={row} rowVirtualizer={rowVirtualizer} staticRowIndex={staticRowIndex} - table={table} virtualRow={virtualRow} /> )} diff --git a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRowGrabHandle.tsx b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRowGrabHandle.tsx index 1dc8ee8c95..633d40fac5 100644 --- a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRowGrabHandle.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRowGrabHandle.tsx @@ -1,23 +1,23 @@ import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_GrabHandleButton } from '../buttons/MRT_GrabHandleButton' import type { DragEvent, RefObject } from 'react' import type { IconButtonProps } from '@mui/material/IconButton' -import type { MRT_Row, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Row, MRT_RowData } from '../../types' export interface MRT_TableBodyRowGrabHandleProps< TData extends MRT_RowData, > extends IconButtonProps { row: MRT_Row rowRef: RefObject - table: MRT_TableInstance } export const MRT_TableBodyRowGrabHandle = ({ row, rowRef, - table, ...rest }: MRT_TableBodyRowGrabHandleProps) => { + const table = useMRTContext() const { options: { muiRowDragHandleProps }, } = table @@ -52,7 +52,6 @@ export const MRT_TableBodyRowGrabHandle = ({ location="row" onDragEnd={handleDragEnd} onDragStart={handleDragStart} - table={table} /> ) } diff --git a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRowPinButton.tsx b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRowPinButton.tsx index e527bbb4f9..79a941717d 100644 --- a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRowPinButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableBodyRowPinButton.tsx @@ -1,21 +1,21 @@ import Box from '@mui/material/Box' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_RowPinButton } from '../buttons/MRT_RowPinButton' import type { IconButtonProps } from '@mui/material/IconButton' -import type { MRT_Row, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Row, MRT_RowData } from '../../types' export interface MRT_TableBodyRowPinButtonProps< TData extends MRT_RowData, > extends IconButtonProps { row: MRT_Row - table: MRT_TableInstance } export const MRT_TableBodyRowPinButton = ({ row, - table, ...rest }: MRT_TableBodyRowPinButtonProps) => { + const table = useMRTContext() const { state, options: { enableRowPinning, rowPinningDisplayMode }, @@ -28,7 +28,6 @@ export const MRT_TableBodyRowPinButton = ({ const rowPinButtonProps = { row, - table, ...rest, } diff --git a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableDetailPanel.tsx b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableDetailPanel.tsx index 30db86f035..d3180b7fe0 100644 --- a/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableDetailPanel.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/body/MRT_TableDetailPanel.tsx @@ -2,12 +2,12 @@ import Collapse from '@mui/material/Collapse' import TableCell from '@mui/material/TableCell' import TableRow from '@mui/material/TableRow' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { TableCellProps } from '@mui/material/TableCell' import type { MRT_Row, MRT_RowData, MRT_RowVirtualizer, - MRT_TableInstance, MRT_VirtualItem, } from '../../types' import type { RefObject } from 'react' @@ -19,7 +19,6 @@ export interface MRT_TableDetailPanelProps< row: MRT_Row rowVirtualizer?: MRT_RowVirtualizer staticRowIndex: number - table: MRT_TableInstance virtualRow?: MRT_VirtualItem } @@ -28,10 +27,10 @@ export const MRT_TableDetailPanel = ({ row, rowVirtualizer, staticRowIndex, - table, virtualRow, ...rest }: MRT_TableDetailPanelProps) => { + const table = useMRTContext() const { state, getVisibleLeafColumns, diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ColumnPinningButtons.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ColumnPinningButtons.tsx index 47d686937e..ada739c11e 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ColumnPinningButtons.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ColumnPinningButtons.tsx @@ -1,22 +1,22 @@ import Box from '@mui/material/Box' import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' +import { useMRTContext } from '../../hooks/mrtTableHook' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_Column, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Column, MRT_RowData } from '../../types' import type { BoxProps } from '@mui/material/Box' export interface MRT_ColumnPinningButtonsProps< TData extends MRT_RowData, > extends BoxProps { column: MRT_Column - table: MRT_TableInstance } export const MRT_ColumnPinningButtons = ({ column, - table, ...rest }: MRT_ColumnPinningButtonsProps) => { + const table = useMRTContext() const { options: { icons: { PushPinIcon }, diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_CopyButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_CopyButton.tsx index 65077a808e..344e152663 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_CopyButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_CopyButton.tsx @@ -2,8 +2,9 @@ import { useState } from 'react' import Button from '@mui/material/Button' import Tooltip from '@mui/material/Tooltip' import { getCommonTooltipProps } from '../../utils/style.utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_Cell, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Cell, MRT_RowData } from '../../types' import type { ButtonProps } from '@mui/material/Button' import type { MouseEvent } from 'react' @@ -11,14 +12,13 @@ export interface MRT_CopyButtonProps< TData extends MRT_RowData, > extends ButtonProps { cell: MRT_Cell - table: MRT_TableInstance } export const MRT_CopyButton = ({ cell, - table, ...rest }: MRT_CopyButtonProps) => { + const table = useMRTContext() const { options: { localization, muiCopyButtonProps }, } = table diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_EditActionButtons.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_EditActionButtons.tsx index 6319105cd6..130c27f164 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_EditActionButtons.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_EditActionButtons.tsx @@ -3,24 +3,24 @@ import Button from '@mui/material/Button' import CircularProgress from '@mui/material/CircularProgress' import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' +import { useMRTContext } from '../../hooks/mrtTableHook' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_Row, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Row, MRT_RowData } from '../../types' import type { BoxProps } from '@mui/material/Box' export interface MRT_EditActionButtonsProps< TData extends MRT_RowData, > extends BoxProps { row: MRT_Row - table: MRT_TableInstance variant?: 'icon' | 'text' } export const MRT_EditActionButtons = ({ row, - table, variant = 'icon', ...rest }: MRT_EditActionButtonsProps) => { + const table = useMRTContext() const { state, options: { @@ -48,7 +48,7 @@ export const MRT_EditActionButtons = ({ onEditingRowCancel?.({ row, table }) setEditingRow(null) } - row._valuesCache = {} as any // reset values cache + row._valuesCache = {} // reset values cache } const handleSubmitRow = () => { @@ -60,7 +60,6 @@ export const MRT_EditActionButtons = ({ input.value !== undefined && Object.hasOwn(row?._valuesCache, input.name) ) { - // @ts-expect-error row._valuesCache[input.name] = input.value } }) diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ExpandAllButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ExpandAllButton.tsx index 9e9f60cee2..6c311bc62b 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ExpandAllButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ExpandAllButton.tsx @@ -1,20 +1,14 @@ import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' import { getCommonTooltipProps } from '../../utils/style.utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_RowData, MRT_TableInstance } from '../../types' import type { IconButtonProps } from '@mui/material/IconButton' -export interface MRT_ExpandAllButtonProps< - TData extends MRT_RowData, -> extends IconButtonProps { - table: MRT_TableInstance -} +export interface MRT_ExpandAllButtonProps extends IconButtonProps {} -export const MRT_ExpandAllButton = ({ - table, - ...rest -}: MRT_ExpandAllButtonProps) => { +export const MRT_ExpandAllButton = ({ ...rest }: MRT_ExpandAllButtonProps) => { + const table = useMRTContext() const { getCanSomeRowsExpand, getIsAllRowsExpanded, diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ExpandButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ExpandButton.tsx index 2fc7e9e04c..ab2b213b13 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ExpandButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ExpandButton.tsx @@ -2,8 +2,9 @@ import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' import { useTheme } from '@mui/material/styles' import { getCommonTooltipProps } from '../../utils/style.utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_Row, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Row, MRT_RowData } from '../../types' import type { IconButtonProps } from '@mui/material/IconButton' import type { MouseEvent } from 'react' @@ -12,14 +13,13 @@ export interface MRT_ExpandButtonProps< > extends IconButtonProps { row: MRT_Row staticRowIndex?: number - table: MRT_TableInstance } export const MRT_ExpandButton = ({ row, staticRowIndex, - table, }: MRT_ExpandButtonProps) => { + const table = useMRTContext() const theme = useTheme() const { state, diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_GrabHandleButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_GrabHandleButton.tsx index c02268c498..134b327bae 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_GrabHandleButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_GrabHandleButton.tsx @@ -1,26 +1,23 @@ import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' import { getCommonTooltipProps } from '../../utils/style.utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_RowData, MRT_TableInstance } from '../../types' import type { IconButtonProps } from '@mui/material/IconButton' import type { DragEventHandler } from 'react' -export interface MRT_GrabHandleButtonProps< - TData extends MRT_RowData, -> extends IconButtonProps { +export interface MRT_GrabHandleButtonProps extends IconButtonProps { iconButtonProps?: IconButtonProps location?: 'column' | 'row' onDragEnd: DragEventHandler onDragStart: DragEventHandler - table: MRT_TableInstance } -export const MRT_GrabHandleButton = ({ +export const MRT_GrabHandleButton = ({ location, - table, ...rest -}: MRT_GrabHandleButtonProps) => { +}: MRT_GrabHandleButtonProps) => { + const table = useMRTContext() const { options: { icons: { DragHandleIcon }, diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_RowPinButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_RowPinButton.tsx index c91859abaf..87fd47c2c3 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_RowPinButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_RowPinButton.tsx @@ -2,26 +2,26 @@ import { useState } from 'react' import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' import { getCommonTooltipProps } from '../../utils/style.utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { parseFromValuesOrFunc } from '../../utils/utils' import type { MouseEvent } from 'react' import type { RowPinningPosition } from '@tanstack/react-table' import type { IconButtonProps } from '@mui/material/IconButton' -import type { MRT_Row, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Row, MRT_RowData } from '../../types' export interface MRT_RowPinButtonProps< TData extends MRT_RowData, > extends IconButtonProps { pinningPosition: RowPinningPosition row: MRT_Row - table: MRT_TableInstance } export const MRT_RowPinButton = ({ pinningPosition, row, - table, ...rest }: MRT_RowPinButtonProps) => { + const table = useMRTContext() const { options: { icons: { CloseIcon, PushPinIcon }, diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ShowHideColumnsButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ShowHideColumnsButton.tsx index fbc6fedc9b..46a765484e 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ShowHideColumnsButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ShowHideColumnsButton.tsx @@ -2,20 +2,16 @@ import { useState } from 'react' import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' import { MRT_ShowHideColumnsMenu } from '../menus/MRT_ShowHideColumnsMenu' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { MouseEvent } from 'react' import type { IconButtonProps } from '@mui/material/IconButton' -import type { MRT_RowData, MRT_TableInstance } from '../../types' -export interface MRT_ShowHideColumnsButtonProps< - TData extends MRT_RowData, -> extends IconButtonProps { - table: MRT_TableInstance -} +export interface MRT_ShowHideColumnsButtonProps extends IconButtonProps {} -export const MRT_ShowHideColumnsButton = ({ - table, +export const MRT_ShowHideColumnsButton = ({ ...rest -}: MRT_ShowHideColumnsButtonProps) => { +}: MRT_ShowHideColumnsButtonProps) => { + const table = useMRTContext() const { options: { icons: { ViewColumnIcon }, @@ -45,7 +41,6 @@ export const MRT_ShowHideColumnsButton = ({ )} diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleDensePaddingButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleDensePaddingButton.tsx index d1905a58c6..95dbe13f53 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleDensePaddingButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleDensePaddingButton.tsx @@ -1,18 +1,14 @@ import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { IconButtonProps } from '@mui/material/IconButton' -import type { MRT_RowData, MRT_TableInstance } from '../../types' -export interface MRT_ToggleDensePaddingButtonProps< - TData extends MRT_RowData, -> extends IconButtonProps { - table: MRT_TableInstance -} +export interface MRT_ToggleDensePaddingButtonProps extends IconButtonProps {} -export const MRT_ToggleDensePaddingButton = ({ - table, +export const MRT_ToggleDensePaddingButton = ({ ...rest -}: MRT_ToggleDensePaddingButtonProps) => { +}: MRT_ToggleDensePaddingButtonProps) => { + const table = useMRTContext() const { state, options: { diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleFiltersButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleFiltersButton.tsx index bbdd90cdca..2b9496203f 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleFiltersButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleFiltersButton.tsx @@ -1,18 +1,14 @@ import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { IconButtonProps } from '@mui/material/IconButton' -import type { MRT_RowData, MRT_TableInstance } from '../../types' -export interface MRT_ToggleFiltersButtonProps< - TData extends MRT_RowData, -> extends IconButtonProps { - table: MRT_TableInstance -} +export interface MRT_ToggleFiltersButtonProps extends IconButtonProps {} -export const MRT_ToggleFiltersButton = ({ - table, +export const MRT_ToggleFiltersButton = ({ ...rest -}: MRT_ToggleFiltersButtonProps) => { +}: MRT_ToggleFiltersButtonProps) => { + const table = useMRTContext() const { state, options: { diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleFullScreenButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleFullScreenButton.tsx index c999d0df19..7a67270cb6 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleFullScreenButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleFullScreenButton.tsx @@ -1,19 +1,15 @@ import { useState } from 'react' import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { IconButtonProps } from '@mui/material/IconButton' -import type { MRT_RowData, MRT_TableInstance } from '../../types' -export interface MRT_ToggleFullScreenButtonProps< - TData extends MRT_RowData, -> extends IconButtonProps { - table: MRT_TableInstance -} +export interface MRT_ToggleFullScreenButtonProps extends IconButtonProps {} -export const MRT_ToggleFullScreenButton = ({ - table, +export const MRT_ToggleFullScreenButton = ({ ...rest -}: MRT_ToggleFullScreenButtonProps) => { +}: MRT_ToggleFullScreenButtonProps) => { + const table = useMRTContext() const { state, options: { diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleGlobalFilterButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleGlobalFilterButton.tsx index f365ad2173..10d8513718 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleGlobalFilterButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleGlobalFilterButton.tsx @@ -1,18 +1,14 @@ import IconButton from '@mui/material/IconButton' import Tooltip from '@mui/material/Tooltip' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { IconButtonProps } from '@mui/material/IconButton' -import type { MRT_RowData, MRT_TableInstance } from '../../types' -export interface MRT_ToggleGlobalFilterButtonProps< - TData extends MRT_RowData, -> extends IconButtonProps { - table: MRT_TableInstance -} +export interface MRT_ToggleGlobalFilterButtonProps extends IconButtonProps {} -export const MRT_ToggleGlobalFilterButton = ({ - table, +export const MRT_ToggleGlobalFilterButton = ({ ...rest -}: MRT_ToggleGlobalFilterButtonProps) => { +}: MRT_ToggleGlobalFilterButtonProps) => { + const table = useMRTContext() const { state, options: { diff --git a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx index e6f4db2d37..f0440f8154 100644 --- a/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx @@ -4,13 +4,9 @@ import Tooltip from '@mui/material/Tooltip' import { getCommonTooltipProps } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_RowActionMenu } from '../menus/MRT_RowActionMenu' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_EditActionButtons } from './MRT_EditActionButtons' -import type { - MRT_Cell, - MRT_Row, - MRT_RowData, - MRT_TableInstance, -} from '../../types' +import type { MRT_Cell, MRT_Row, MRT_RowData } from '../../types' import type { IconButtonProps } from '@mui/material/IconButton' import type { MouseEvent } from 'react' @@ -31,16 +27,15 @@ export interface MRT_ToggleRowActionMenuButtonProps< cell: MRT_Cell row: MRT_Row staticRowIndex?: number - table: MRT_TableInstance } export const MRT_ToggleRowActionMenuButton = ({ cell, row, staticRowIndex, - table, ...rest }: MRT_ToggleRowActionMenuButtonProps) => { + const table = useMRTContext() const { state, options: { @@ -83,7 +78,7 @@ export const MRT_ToggleRowActionMenuButton = ({ {renderRowActions && !showEditActionButtons ? ( renderRowActions({ cell, row, staticRowIndex, table }) ) : showEditActionButtons ? ( - + ) : !renderRowActionMenuItems && parseFromValuesOrFunc(enableEditing, row) && ['modal', 'row'].includes(editDisplayMode!) ? ( @@ -120,7 +115,6 @@ export const MRT_ToggleRowActionMenuButton = ({ row={row} setAnchorEl={setAnchorEl} staticRowIndex={staticRowIndex} - table={table} /> ) : null} diff --git a/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooter.tsx b/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooter.tsx index 3a5480e511..6f850528b6 100644 --- a/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooter.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooter.tsx @@ -1,25 +1,19 @@ import TableFooter from '@mui/material/TableFooter' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableFooterRow } from './MRT_TableFooterRow' -import type { - MRT_ColumnVirtualizer, - MRT_RowData, - MRT_TableInstance, -} from '../../types' +import type { MRT_ColumnVirtualizer, MRT_RowData } from '../../types' import type { TableFooterProps } from '@mui/material/TableFooter' -export interface MRT_TableFooterProps< - TData extends MRT_RowData, -> extends TableFooterProps { +export interface MRT_TableFooterProps extends TableFooterProps { columnVirtualizer?: MRT_ColumnVirtualizer - table: MRT_TableInstance } export const MRT_TableFooter = ({ columnVirtualizer, - table, ...rest -}: MRT_TableFooterProps) => { +}: MRT_TableFooterProps) => { + const table = useMRTContext() const { state, options: { enableStickyFooter, layoutMode, muiTableFooterProps }, @@ -82,7 +76,6 @@ export const MRT_TableFooter = ({ columnVirtualizer={columnVirtualizer} footerGroup={footerGroup as any} key={footerGroup.id} - table={table} /> ))} diff --git a/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooterCell.tsx b/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooterCell.tsx index 1ea8f04af8..9a9e1b3558 100644 --- a/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooterCell.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooterCell.tsx @@ -3,7 +3,8 @@ import { useTheme } from '@mui/material/styles' import { getCommonMRTCellStyles } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' import { cellKeyboardShortcuts } from '../../utils/cell.utils' -import type { MRT_Header, MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' +import type { MRT_Header, MRT_RowData } from '../../types' import type { TableCellProps } from '@mui/material/TableCell' export interface MRT_TableFooterCellProps< @@ -11,15 +12,14 @@ export interface MRT_TableFooterCellProps< > extends TableCellProps { footer: MRT_Header staticColumnIndex?: number - table: MRT_TableInstance } export const MRT_TableFooterCell = ({ footer, staticColumnIndex, - table, ...rest }: MRT_TableFooterCellProps) => { + const table = useMRTContext() const theme = useTheme() const { state, diff --git a/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooterRow.tsx b/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooterRow.tsx index ee781d0bc0..22b8c0195e 100644 --- a/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooterRow.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/footer/MRT_TableFooterRow.tsx @@ -1,12 +1,12 @@ import TableRow from '@mui/material/TableRow' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableFooterCell } from './MRT_TableFooterCell' import type { MRT_ColumnVirtualizer, MRT_Header, MRT_HeaderGroup, MRT_RowData, - MRT_TableInstance, MRT_VirtualItem, } from '../../types' import type { TableRowProps } from '@mui/material/TableRow' @@ -16,15 +16,14 @@ export interface MRT_TableFooterRowProps< > extends TableRowProps { columnVirtualizer?: MRT_ColumnVirtualizer footerGroup: MRT_HeaderGroup - table: MRT_TableInstance } export const MRT_TableFooterRow = ({ columnVirtualizer, footerGroup, - table, ...rest }: MRT_TableFooterRowProps) => { + const table = useMRTContext() const { options: { layoutMode, @@ -83,7 +82,6 @@ export const MRT_TableFooterRow = ({ footer={footer} key={footer.id} staticColumnIndex={staticColumnIndex} - table={table} /> ) : null }, diff --git a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHead.tsx b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHead.tsx index cf406dd38a..712e05d74d 100644 --- a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHead.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHead.tsx @@ -1,26 +1,20 @@ import TableHead from '@mui/material/TableHead' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_ToolbarAlertBanner } from '../toolbar/MRT_ToolbarAlertBanner' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableHeadRow } from './MRT_TableHeadRow' -import type { - MRT_ColumnVirtualizer, - MRT_RowData, - MRT_TableInstance, -} from '../../types' +import type { MRT_ColumnVirtualizer, MRT_RowData } from '../../types' import type { TableHeadProps } from '@mui/material/TableHead' -export interface MRT_TableHeadProps< - TData extends MRT_RowData, -> extends TableHeadProps { +export interface MRT_TableHeadProps extends TableHeadProps { columnVirtualizer?: MRT_ColumnVirtualizer - table: MRT_TableInstance } export const MRT_TableHead = ({ columnVirtualizer, - table, ...rest -}: MRT_TableHeadProps) => { +}: MRT_TableHeadProps) => { + const table = useMRTContext() const { state, options: { @@ -73,7 +67,7 @@ export const MRT_TableHead = ({ padding: 0, }} > - + ) : ( @@ -84,7 +78,6 @@ export const MRT_TableHead = ({ columnVirtualizer={columnVirtualizer} headerGroup={headerGroup as any} key={headerGroup.id} - table={table} /> )) )} diff --git a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCell.tsx b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCell.tsx index b51fc183db..49a7e4a6b6 100644 --- a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCell.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCell.tsx @@ -5,6 +5,7 @@ import { useTheme } from '@mui/material/styles' import { getCommonMRTCellStyles } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' import { cellKeyboardShortcuts } from '../../utils/cell.utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableHeadCellColumnActionsButton } from './MRT_TableHeadCellColumnActionsButton' import { MRT_TableHeadCellFilterContainer } from './MRT_TableHeadCellFilterContainer' import { MRT_TableHeadCellFilterLabel } from './MRT_TableHeadCellFilterLabel' @@ -15,7 +16,6 @@ import type { MRT_ColumnVirtualizer, MRT_Header, MRT_RowData, - MRT_TableInstance, } from '../../types' import type { Theme } from '@mui/material/styles' import type { DragEvent } from 'react' @@ -27,16 +27,15 @@ export interface MRT_TableHeadCellProps< columnVirtualizer?: MRT_ColumnVirtualizer header: MRT_Header staticColumnIndex?: number - table: MRT_TableInstance } export const MRT_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex, - table, ...rest }: MRT_TableHeadCellProps) => { + const table = useMRTContext() const theme = useTheme() const { state, @@ -309,10 +308,10 @@ export const MRT_TableHeadCell = ({ {HeaderElement} {column.getCanFilter() && ( - + )} {column.getCanSort() && ( - + )} {columnDefType !== 'group' && ( @@ -325,27 +324,23 @@ export const MRT_TableHeadCell = ({ {showDragHandle && ( )} {showColumnActions && ( - + )} )} {column.getCanResize() && ( - + )} ))} {columnFilterDisplayMode === 'subheader' && column.getCanFilter() && ( - + )} ) diff --git a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellColumnActionsButton.tsx b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellColumnActionsButton.tsx index 37ba27b909..315fb2733b 100644 --- a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellColumnActionsButton.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellColumnActionsButton.tsx @@ -4,7 +4,8 @@ import Tooltip from '@mui/material/Tooltip' import { getCommonTooltipProps } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_ColumnActionMenu } from '../menus/MRT_ColumnActionMenu' -import type { MRT_Header, MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' +import type { MRT_Header, MRT_RowData } from '../../types' import type { IconButtonProps } from '@mui/material/IconButton' import type { MouseEvent } from 'react' @@ -12,16 +13,15 @@ export interface MRT_TableHeadCellColumnActionsButtonProps< TData extends MRT_RowData, > extends IconButtonProps { header: MRT_Header - table: MRT_TableInstance } export const MRT_TableHeadCellColumnActionsButton = < TData extends MRT_RowData, >({ header, - table, ...rest }: MRT_TableHeadCellColumnActionsButtonProps) => { + const table = useMRTContext() const { options: { icons: { MoreVertIcon }, @@ -86,7 +86,6 @@ export const MRT_TableHeadCellColumnActionsButton = < anchorEl={anchorEl} header={header} setAnchorEl={setAnchorEl} - table={table} /> )} diff --git a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellFilterContainer.tsx b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellFilterContainer.tsx index 2ac9a2091b..db13f6ead5 100644 --- a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellFilterContainer.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellFilterContainer.tsx @@ -4,21 +4,21 @@ import { MRT_FilterCheckbox } from '../inputs/MRT_FilterCheckbox' import { MRT_FilterRangeFields } from '../inputs/MRT_FilterRangeFields' import { MRT_FilterRangeSlider } from '../inputs/MRT_FilterRangeSlider' import { MRT_FilterTextField } from '../inputs/MRT_FilterTextField' -import type { MRT_Header, MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' +import type { MRT_Header, MRT_RowData } from '../../types' import type { CollapseProps } from '@mui/material/Collapse' export interface MRT_TableHeadCellFilterContainerProps< TData extends MRT_RowData, > extends CollapseProps { header: MRT_Header - table: MRT_TableInstance } export const MRT_TableHeadCellFilterContainer = ({ header, - table, ...rest }: MRT_TableHeadCellFilterContainerProps) => { + const table = useMRTContext() const { state, options: { columnFilterDisplayMode }, @@ -36,13 +36,13 @@ export const MRT_TableHeadCellFilterContainer = ({ {...rest} > {columnDef.filterVariant === 'checkbox' ? ( - + ) : columnDef.filterVariant === 'range-slider' ? ( - + ) : isRangeFilter ? ( - + ) : ( - + )} ) diff --git a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellFilterLabel.tsx b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellFilterLabel.tsx index 2fd2568801..66484d1636 100644 --- a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellFilterLabel.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellFilterLabel.tsx @@ -9,8 +9,9 @@ import { useDropdownOptions, } from '../../utils/column.utils' import { getValueAndLabel, parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableHeadCellFilterContainer } from './MRT_TableHeadCellFilterContainer' -import type { MRT_Header, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Header, MRT_RowData } from '../../types' import type { IconButtonProps } from '@mui/material/IconButton' import type { MouseEvent } from 'react' @@ -18,14 +19,13 @@ export interface MRT_TableHeadCellFilterLabelProps< TData extends MRT_RowData, > extends IconButtonProps { header: MRT_Header - table: MRT_TableInstance } export const MRT_TableHeadCellFilterLabel = ({ header, - table, ...rest }: MRT_TableHeadCellFilterLabelProps) => { + const table = useMRTContext() const { options: { columnFilterDisplayMode, @@ -168,7 +168,7 @@ export const MRT_TableHeadCellFilterLabel = ({ }} > - + )} diff --git a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellGrabHandle.tsx b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellGrabHandle.tsx index e4ae9e969c..98d690159e 100644 --- a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellGrabHandle.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellGrabHandle.tsx @@ -1,24 +1,24 @@ import { reorderColumn } from '../../utils/column.utils' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_GrabHandleButton } from '../buttons/MRT_GrabHandleButton' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { DragEvent, RefObject } from 'react' import type { IconButtonProps } from '@mui/material/IconButton' -import type { MRT_Column, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Column, MRT_RowData } from '../../types' export interface MRT_TableHeadCellGrabHandleProps< TData extends MRT_RowData, > extends IconButtonProps { column: MRT_Column - table: MRT_TableInstance tableHeadCellRef: RefObject } export const MRT_TableHeadCellGrabHandle = ({ column, - table, tableHeadCellRef, ...rest }: MRT_TableHeadCellGrabHandleProps) => { + const table = useMRTContext() const { state, options: { enableColumnOrdering, muiColumnDragHandleProps }, @@ -82,7 +82,6 @@ export const MRT_TableHeadCellGrabHandle = ({ {...iconButtonProps} onDragEnd={handleDragEnd} onDragStart={handleDragStart} - table={table} /> ) } diff --git a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellResizeHandle.tsx b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellResizeHandle.tsx index bb708f30a8..962693ee35 100644 --- a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellResizeHandle.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellResizeHandle.tsx @@ -1,21 +1,21 @@ import Box from '@mui/material/Box' import Divider from '@mui/material/Divider' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { DividerProps } from '@mui/material/Divider' -import type { MRT_Header, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Header, MRT_RowData } from '../../types' export interface MRT_TableHeadCellResizeHandleProps< TData extends MRT_RowData, > extends DividerProps { header: MRT_Header - table: MRT_TableInstance } export const MRT_TableHeadCellResizeHandle = ({ header, - table, ...rest }: MRT_TableHeadCellResizeHandleProps) => { + const table = useMRTContext() const { state, options: { columnResizeDirection, columnResizeMode }, diff --git a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellSortLabel.tsx b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellSortLabel.tsx index 5a14fcc00e..6db54a5b52 100644 --- a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellSortLabel.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellSortLabel.tsx @@ -2,21 +2,21 @@ import Badge from '@mui/material/Badge' import TableSortLabel from '@mui/material/TableSortLabel' import Tooltip from '@mui/material/Tooltip' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { TableSortLabelProps } from '@mui/material/TableSortLabel' -import type { MRT_Header, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Header, MRT_RowData } from '../../types' export interface MRT_TableHeadCellSortLabelProps< TData extends MRT_RowData, > extends TableSortLabelProps { header: MRT_Header - table: MRT_TableInstance } export const MRT_TableHeadCellSortLabel = ({ header, - table, ...rest }: MRT_TableHeadCellSortLabelProps) => { + const table = useMRTContext() const { state, options: { diff --git a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadRow.tsx b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadRow.tsx index deb45b64b8..d29c0448a6 100644 --- a/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadRow.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadRow.tsx @@ -1,13 +1,13 @@ import TableRow from '@mui/material/TableRow' import { alpha } from '@mui/material/styles' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableHeadCell } from './MRT_TableHeadCell' import type { MRT_ColumnVirtualizer, MRT_Header, MRT_HeaderGroup, MRT_RowData, - MRT_TableInstance, MRT_VirtualItem, } from '../../types' import type { TableRowProps } from '@mui/material/TableRow' @@ -17,15 +17,14 @@ export interface MRT_TableHeadRowProps< > extends TableRowProps { columnVirtualizer?: MRT_ColumnVirtualizer headerGroup: MRT_HeaderGroup - table: MRT_TableInstance } export const MRT_TableHeadRow = ({ columnVirtualizer, headerGroup, - table, ...rest }: MRT_TableHeadRowProps) => { + const table = useMRTContext() const { options: { enableStickyHeader, @@ -78,7 +77,6 @@ export const MRT_TableHeadRow = ({ header={header} key={header.id} staticColumnIndex={staticColumnIndex} - table={table} /> ) : null }, diff --git a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_EditCellTextField.tsx b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_EditCellTextField.tsx index 95a9bd64b8..3aeaba819e 100644 --- a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_EditCellTextField.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_EditCellTextField.tsx @@ -2,22 +2,22 @@ import { useState } from 'react' import MenuItem from '@mui/material/MenuItem' import TextField from '@mui/material/TextField' import { getValueAndLabel, parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { ChangeEvent, FocusEvent, KeyboardEvent } from 'react' import type { TextFieldProps } from '@mui/material/TextField' -import type { MRT_Cell, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Cell, MRT_RowData } from '../../types' export interface MRT_EditCellTextFieldProps< TData extends MRT_RowData, > extends TextFieldProps<'standard'> { cell: MRT_Cell - table: MRT_TableInstance } export const MRT_EditCellTextField = ({ cell, - table, ...rest }: MRT_EditCellTextFieldProps) => { + const table = useMRTContext() const { state, options: { createDisplayMode, editDisplayMode, muiEditTextFieldProps }, @@ -63,7 +63,6 @@ export const MRT_EditCellTextField = ({ const isSelectEdit = editVariant === 'select' || textFieldProps?.select const saveInputValueToRowCache = (newValue: string) => { - // @ts-expect-error row._valuesCache[column.id] = newValue if (isCreating) { setCreatingRow(row) diff --git a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterCheckbox.tsx b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterCheckbox.tsx index 53c6773596..5cd4cfa33d 100644 --- a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterCheckbox.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterCheckbox.tsx @@ -3,21 +3,21 @@ import FormControlLabel from '@mui/material/FormControlLabel' import Tooltip from '@mui/material/Tooltip' import { getCommonTooltipProps } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_Column, MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' +import type { MRT_Column, MRT_RowData } from '../../types' import type { CheckboxProps } from '@mui/material/Checkbox' export interface MRT_FilterCheckboxProps< TData extends MRT_RowData, > extends CheckboxProps { column: MRT_Column - table: MRT_TableInstance } export const MRT_FilterCheckbox = ({ column, - table, ...rest }: MRT_FilterCheckboxProps) => { + const table = useMRTContext() const { state, options: { localization, muiFilterCheckboxProps }, diff --git a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterRangeFields.tsx b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterRangeFields.tsx index d46853f403..650ec881d3 100644 --- a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterRangeFields.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterRangeFields.tsx @@ -1,19 +1,17 @@ import Box from '@mui/material/Box' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_FilterTextField } from './MRT_FilterTextField' -import type { MRT_Header, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Header, MRT_RowData } from '../../types' import type { BoxProps } from '@mui/material/Box' export interface MRT_FilterRangeFieldsProps< TData extends MRT_RowData, > extends BoxProps { header: MRT_Header - table: MRT_TableInstance } export const MRT_FilterRangeFields = ({ header, - table, ...rest }: MRT_FilterRangeFieldsProps) => { return ( @@ -31,7 +29,6 @@ export const MRT_FilterRangeFields = ({ header={header} key={rangeFilterIndex} rangeFilterIndex={rangeFilterIndex} - table={table} /> ))} diff --git a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterRangeSlider.tsx b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterRangeSlider.tsx index 599f903d23..46fe6155eb 100644 --- a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterRangeSlider.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterRangeSlider.tsx @@ -3,21 +3,21 @@ import FormHelperText from '@mui/material/FormHelperText' import Slider from '@mui/material/Slider' import Stack from '@mui/material/Stack' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { SliderProps } from '@mui/material/Slider' -import type { MRT_Header, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Header, MRT_RowData } from '../../types' export interface MRT_FilterRangeSliderProps< TData extends MRT_RowData, > extends SliderProps { header: MRT_Header - table: MRT_TableInstance } export const MRT_FilterRangeSlider = ({ header, - table, ...rest }: MRT_FilterRangeSliderProps) => { + const table = useMRTContext() const { options: { enableColumnFilterModes, localization, muiFilterSliderProps }, refs: { filterInputRefs }, @@ -25,7 +25,7 @@ export const MRT_FilterRangeSlider = ({ const { column } = header const { columnDef } = column - const currentFilterOption = columnDef._filterFn + const currentFilterOption = columnDef._filterFn! const showChangeModeButton = enableColumnFilterModes && columnDef.enableColumnFilterModes !== false diff --git a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterTextField.tsx b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterTextField.tsx index 5fd79525c0..94f9bf37fc 100644 --- a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterTextField.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_FilterTextField.tsx @@ -18,12 +18,8 @@ import { } from '../../utils/column.utils' import { getValueAndLabel, parseFromValuesOrFunc } from '../../utils/utils' import { MRT_FilterOptionMenu } from '../menus/MRT_FilterOptionMenu' -import type { - DropdownOption, - MRT_Header, - MRT_RowData, - MRT_TableInstance, -} from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' +import type { DropdownOption, MRT_Header, MRT_RowData } from '../../types' import type { TextFieldProps } from '@mui/material/TextField' import type { ChangeEvent, MouseEvent, SyntheticEvent } from 'react' import type { AutocompleteInputChangeReason } from '@mui/material/Autocomplete' @@ -33,15 +29,14 @@ export interface MRT_FilterTextFieldProps< > extends TextFieldProps<'standard'> { header: MRT_Header rangeFilterIndex?: number - table: MRT_TableInstance } export const MRT_FilterTextField = ({ header, rangeFilterIndex, - table, ...rest }: MRT_FilterTextFieldProps) => { + const table = useMRTContext() const { options: { enableColumnFilterModes, @@ -103,11 +98,11 @@ export const MRT_FilterTextField = ({ const dropdownOptions = useDropdownOptions({ header, table }) - const filterChipLabel = ['empty', 'notEmpty'].includes(currentFilterOption) + const filterChipLabel = ['empty', 'notEmpty'].includes(currentFilterOption!) ? localization[ `filter${ - currentFilterOption?.charAt?.(0)?.toUpperCase() + - currentFilterOption?.slice(1) + currentFilterOption!.charAt(0)?.toUpperCase() + + currentFilterOption!.slice(1) }` as keyof typeof localization ] : '' @@ -312,8 +307,8 @@ export const MRT_FilterTextField = ({ '{filterType}', localization[ `filter${ - currentFilterOption?.charAt(0)?.toUpperCase() + - currentFilterOption?.slice(1) + currentFilterOption!.charAt(0)?.toUpperCase() + + currentFilterOption!.slice(1) }` as keyof typeof localization ], )} @@ -568,7 +563,6 @@ export const MRT_FilterTextField = ({ header={header} setAnchorEl={setAnchorEl} setFilterValue={setFilterValue} - table={table} /> ) diff --git a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_GlobalFilterTextField.tsx b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_GlobalFilterTextField.tsx index ba86eaf588..acde4cbb49 100644 --- a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_GlobalFilterTextField.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_GlobalFilterTextField.tsx @@ -7,20 +7,17 @@ import Tooltip from '@mui/material/Tooltip' import { useDebouncedCallback } from '@tanstack/react-pacer/debouncer' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_FilterOptionMenu } from '../menus/MRT_FilterOptionMenu' -import type { MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' +import type { MRT_RowData } from '../../types' import type { TextFieldProps } from '@mui/material/TextField' import type { ChangeEvent, MouseEvent } from 'react' -export interface MRT_GlobalFilterTextFieldProps< - TData extends MRT_RowData, -> extends TextFieldProps<'standard'> { - table: MRT_TableInstance -} +export interface MRT_GlobalFilterTextFieldProps extends TextFieldProps<'standard'> {} export const MRT_GlobalFilterTextField = ({ - table, ...rest -}: MRT_GlobalFilterTextFieldProps) => { +}: MRT_GlobalFilterTextFieldProps) => { + const table = useMRTContext() const { state, options: { @@ -152,7 +149,6 @@ export const MRT_GlobalFilterTextField = ({ anchorEl={anchorEl} onSelect={handleClear} setAnchorEl={setAnchorEl} - table={table} /> ) diff --git a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_SelectCheckbox.tsx b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_SelectCheckbox.tsx index 6cc01b30f0..d85ead1543 100644 --- a/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_SelectCheckbox.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/inputs/MRT_SelectCheckbox.tsx @@ -8,7 +8,8 @@ import { } from '../../utils/row.utils' import { getCommonTooltipProps } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_Row, MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' +import type { MRT_Row, MRT_RowData } from '../../types' import type { Theme } from '@mui/material/styles' import type { RadioProps } from '@mui/material/Radio' import type { CheckboxProps } from '@mui/material/Checkbox' @@ -19,15 +20,14 @@ export interface MRT_SelectCheckboxProps< > extends CheckboxProps { row?: MRT_Row staticRowIndex?: number - table: MRT_TableInstance } export const MRT_SelectCheckbox = ({ row, staticRowIndex, - table, ...rest }: MRT_SelectCheckboxProps) => { + const table = useMRTContext() const { state, options: { diff --git a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ActionMenuItem.tsx b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ActionMenuItem.tsx index 3dbb9e54a6..5e4ac2bdb0 100644 --- a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ActionMenuItem.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ActionMenuItem.tsx @@ -2,26 +2,23 @@ import Box from '@mui/material/Box' import IconButton from '@mui/material/IconButton' import ListItemIcon from '@mui/material/ListItemIcon' import MenuItem from '@mui/material/MenuItem' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { ReactNode } from 'react' import type { MenuItemProps } from '@mui/material/MenuItem' -import type { MRT_RowData, MRT_TableInstance } from '../../types' -export interface MRT_ActionMenuItemProps< - TData extends MRT_RowData, -> extends MenuItemProps { +export interface MRT_ActionMenuItemProps extends MenuItemProps { icon: ReactNode label: string onOpenSubMenu?: MenuItemProps['onClick'] | MenuItemProps['onMouseEnter'] - table: MRT_TableInstance } -export const MRT_ActionMenuItem = ({ +export const MRT_ActionMenuItem = ({ icon, label, onOpenSubMenu, - table, ...rest -}: MRT_ActionMenuItemProps) => { +}: MRT_ActionMenuItemProps) => { + const table = useMRTContext() const { options: { icons: { ArrowRightIcon }, diff --git a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_CellActionMenu.tsx b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_CellActionMenu.tsx index b049300d19..50cf04b115 100644 --- a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_CellActionMenu.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_CellActionMenu.tsx @@ -1,20 +1,15 @@ import Menu from '@mui/material/Menu' import { openEditingCell } from '../../utils/cell.utils' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_ActionMenuItem } from './MRT_ActionMenuItem' -import type { MRT_RowData, MRT_TableInstance } from '../../types' import type { MenuProps } from '@mui/material/Menu' +import type { MRT_Cell, MRT_RowData } from '../../types' -export interface MRT_CellActionMenuProps< - TData extends MRT_RowData, -> extends Partial { - table: MRT_TableInstance -} +export interface MRT_CellActionMenuProps extends Partial {} -export const MRT_CellActionMenu = ({ - table, - ...rest -}: MRT_CellActionMenuProps) => { +export const MRT_CellActionMenu = ({ ...rest }: MRT_CellActionMenuProps) => { + const table = useMRTContext() const { state, options: { @@ -29,7 +24,9 @@ export const MRT_CellActionMenu = ({ refs: { actionCellRef }, } = table const { actionCell, density } = state - const cell = actionCell! + // `actionCell` is stored as `Cell` on the (non-generic) state + // map; narrow it back to the MRT cell shape for the render props below. + const cell = actionCell! as MRT_Cell const { row } = cell const { column } = cell const { columnDef } = column @@ -53,7 +50,6 @@ export const MRT_CellActionMenu = ({ navigator.clipboard.writeText(cell.getValue() as string) handleClose() }} - table={table} /> ), parseFromValuesOrFunc(enableEditing, row) && editDisplayMode === 'cell' && ( @@ -65,7 +61,6 @@ export const MRT_CellActionMenu = ({ openEditingCell({ cell, table }) handleClose() }} - table={table} /> ), ].filter(Boolean) diff --git a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ColumnActionMenu.tsx b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ColumnActionMenu.tsx index c8eb11038d..bda5933021 100644 --- a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ColumnActionMenu.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ColumnActionMenu.tsx @@ -1,8 +1,9 @@ import { useState } from 'react' import Menu from '@mui/material/Menu' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_ActionMenuItem } from './MRT_ActionMenuItem' import { MRT_FilterOptionMenu } from './MRT_FilterOptionMenu' -import type { MRT_Header, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Header, MRT_RowData } from '../../types' import type { MenuProps } from '@mui/material/Menu' import type { MouseEvent } from 'react' @@ -12,16 +13,15 @@ export interface MRT_ColumnActionMenuProps< anchorEl: HTMLElement | null header: MRT_Header setAnchorEl: (anchorEl: HTMLElement | null) => void - table: MRT_TableInstance } export const MRT_ColumnActionMenu = ({ anchorEl, header, setAnchorEl, - table, ...rest }: MRT_ColumnActionMenuProps) => { + const table = useMRTContext() const { getAllLeafColumns, state, @@ -105,7 +105,7 @@ export const MRT_ColumnActionMenu = ({ const handleClearFilter = () => { column.setFilterValue(undefined) setAnchorEl(null) - if (['empty', 'notEmpty'].includes(columnDef._filterFn)) { + if (['empty', 'notEmpty'].includes(columnDef._filterFn!)) { setColumnFilterFns((prev) => ({ ...prev, [header.id]: allowedColumnFilterOptions?.[0] ?? 'fuzzy', @@ -153,7 +153,6 @@ export const MRT_ColumnActionMenu = ({ key={0} label={localization.clearSort} onClick={handleClearSort} - table={table} /> ), ({ String(columnDef.header), )} onClick={handleSortAsc} - table={table} />, ({ String(columnDef.header), )} onClick={handleSortDesc} - table={table} />, ] : []), @@ -195,7 +192,6 @@ export const MRT_ColumnActionMenu = ({ key={3} label={localization.clearFilter} onClick={handleClearFilter} - table={table} />, columnFilterDisplayMode === 'subheader' && ( ({ onOpenSubMenu={ showFilterModeSubMenu ? handleOpenFilterModeMenu : undefined } - table={table} /> ), showFilterModeSubMenu && ( @@ -225,7 +220,6 @@ export const MRT_ColumnActionMenu = ({ key={5} onSelect={handleFilterByColumn} setAnchorEl={setFilterMenuAnchorEl} - table={table} /> ), ].filter(Boolean) @@ -240,7 +234,6 @@ export const MRT_ColumnActionMenu = ({ column.getIsGrouped() ? 'ungroupByColumn' : 'groupByColumn' ]?.replace('{column}', String(columnDef.header))} onClick={handleGroupByColumn} - table={table} />, ] : []), @@ -252,7 +245,6 @@ export const MRT_ColumnActionMenu = ({ key={7} label={localization.pinToLeft} onClick={() => handlePinColumn('left')} - table={table} />, ({ key={8} label={localization.pinToRight} onClick={() => handlePinColumn('right')} - table={table} />, ({ key={9} label={localization.unpin} onClick={() => handlePinColumn(false)} - table={table} />, ] : []), @@ -281,7 +271,6 @@ export const MRT_ColumnActionMenu = ({ key={10} label={localization.resetColumnSize} onClick={handleResetColumnSize} - table={table} />, ] : []), @@ -296,7 +285,6 @@ export const MRT_ColumnActionMenu = ({ String(columnDef.header), )} onClick={handleHideColumn} - table={table} />, ({ String(columnDef.header), )} onClick={handleShowAllColumns} - table={table} />, ] : []), diff --git a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_FilterOptionMenu.tsx b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_FilterOptionMenu.tsx index 88272c9026..f84c6a062b 100644 --- a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_FilterOptionMenu.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_FilterOptionMenu.tsx @@ -1,5 +1,6 @@ import { useMemo } from 'react' import Menu from '@mui/material/Menu' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_ActionMenuItem } from './MRT_ActionMenuItem' import type { MRT_FilterOption, @@ -7,7 +8,6 @@ import type { MRT_InternalFilterOption, MRT_Localization, MRT_RowData, - MRT_TableInstance, } from '../../types' import type { MenuProps } from '@mui/material/Menu' @@ -113,7 +113,6 @@ export interface MRT_FilterOptionMenuProps< onSelect?: () => void setAnchorEl: (anchorEl: HTMLElement | null) => void setFilterValue?: (filterValue: any) => void - table: MRT_TableInstance } export const MRT_FilterOptionMenu = ({ @@ -122,9 +121,9 @@ export const MRT_FilterOptionMenu = ({ onSelect, setAnchorEl, setFilterValue, - table, ...rest }: MRT_FilterOptionMenuProps) => { + const table = useMRTContext() const { state, options: { @@ -284,7 +283,6 @@ export const MRT_FilterOptionMenu = ({ label={label} onClick={() => handleSelectFilterMode(option)} selected={option === filterOption} - table={table} value={option} /> ), diff --git a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_RowActionMenu.tsx b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_RowActionMenu.tsx index 0b9230ac91..6b2f110e8e 100644 --- a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_RowActionMenu.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_RowActionMenu.tsx @@ -1,8 +1,9 @@ import { useMemo } from 'react' import Menu from '@mui/material/Menu' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_ActionMenuItem } from './MRT_ActionMenuItem' -import type { MRT_Row, MRT_RowData, MRT_TableInstance } from '../../types' +import type { MRT_Row, MRT_RowData } from '../../types' import type { MenuProps } from '@mui/material/Menu' import type { MouseEvent, ReactNode } from 'react' @@ -14,7 +15,6 @@ export interface MRT_RowActionMenuProps< row: MRT_Row setAnchorEl: (anchorEl: HTMLElement | null) => void staticRowIndex?: number - table: MRT_TableInstance } export const MRT_RowActionMenu = ({ @@ -23,9 +23,9 @@ export const MRT_RowActionMenu = ({ row, setAnchorEl, staticRowIndex, - table, ...rest }: MRT_RowActionMenuProps) => { + const table = useMRTContext() const { state, options: { @@ -48,7 +48,6 @@ export const MRT_RowActionMenu = ({ icon={} label={localization.edit} onClick={handleEdit} - table={table} /> ) if (editItem) items.push(editItem) diff --git a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ShowHideColumnsMenu.tsx b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ShowHideColumnsMenu.tsx index 7a99d835a9..011c0a2b86 100644 --- a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ShowHideColumnsMenu.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ShowHideColumnsMenu.tsx @@ -4,30 +4,29 @@ import Button from '@mui/material/Button' import Divider from '@mui/material/Divider' import Menu from '@mui/material/Menu' import { getDefaultColumnOrderIds } from '../../utils/displayColumn.utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_ShowHideColumnsMenuItems } from './MRT_ShowHideColumnsMenuItems' import type { MRT_Column, MRT_ColumnVisibilityState, MRT_RowData, - MRT_TableInstance, } from '../../types' import type { MenuProps } from '@mui/material/Menu' -export interface MRT_ShowHideColumnsMenuProps< - TData extends MRT_RowData, -> extends Partial { +export interface MRT_ShowHideColumnsMenuProps extends Partial { anchorEl: HTMLElement | null isSubMenu?: boolean setAnchorEl: (anchorEl: HTMLElement | null) => void - table: MRT_TableInstance } -export const MRT_ShowHideColumnsMenu = ({ +export const MRT_ShowHideColumnsMenu = < + TData extends MRT_RowData = MRT_RowData, +>({ anchorEl, setAnchorEl, - table, ...rest -}: MRT_ShowHideColumnsMenuProps) => { +}: MRT_ShowHideColumnsMenuProps) => { + const table = useMRTContext() const { getAllColumns, getAllLeafColumns, @@ -172,7 +171,6 @@ export const MRT_ShowHideColumnsMenu = ({ isNestedColumns={isNestedColumns} key={`${index}-${column.id}`} setHoveredColumn={setHoveredColumn} - table={table} /> ))} diff --git a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ShowHideColumnsMenuItems.tsx b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ShowHideColumnsMenuItems.tsx index c17a1f5bf9..efb1ecf5c7 100644 --- a/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ShowHideColumnsMenuItems.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/menus/MRT_ShowHideColumnsMenuItems.tsx @@ -10,7 +10,8 @@ import { getCommonTooltipProps } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_ColumnPinningButtons } from '../buttons/MRT_ColumnPinningButtons' import { MRT_GrabHandleButton } from '../buttons/MRT_GrabHandleButton' -import type { MRT_Column, MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' +import type { MRT_Column, MRT_RowData } from '../../types' import type { MenuItemProps } from '@mui/material/MenuItem' import type { Dispatch, DragEvent, SetStateAction } from 'react' @@ -22,7 +23,6 @@ export interface MRT_ShowHideColumnsMenuItemsProps< hoveredColumn: MRT_Column | null isNestedColumns: boolean setHoveredColumn: Dispatch | null>> - table: MRT_TableInstance } export const MRT_ShowHideColumnsMenuItems = ({ @@ -31,9 +31,9 @@ export const MRT_ShowHideColumnsMenuItems = ({ hoveredColumn, isNestedColumns, setHoveredColumn, - table, ...rest }: MRT_ShowHideColumnsMenuItemsProps) => { + const table = useMRTContext() const { state, options: { @@ -135,14 +135,13 @@ export const MRT_ShowHideColumnsMenuItems = ({ ) : ( ))} {enableColumnPinning && (column.getCanPin() ? ( - + ) : ( ))} @@ -184,7 +183,6 @@ export const MRT_ShowHideColumnsMenuItems = ({ isNestedColumns={isNestedColumns} key={`${i}-${c.id}`} setHoveredColumn={setHoveredColumn} - table={table} /> ))} diff --git a/examples/react/material-react-table/src/material-react-table/components/modals/MRT_EditRowModal.tsx b/examples/react/material-react-table/src/material-react-table/components/modals/MRT_EditRowModal.tsx index 9d2f21e03c..fe96b946ea 100644 --- a/examples/react/material-react-table/src/material-react-table/components/modals/MRT_EditRowModal.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/modals/MRT_EditRowModal.tsx @@ -6,21 +6,19 @@ import Stack from '@mui/material/Stack' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_EditActionButtons } from '../buttons/MRT_EditActionButtons' import { MRT_EditCellTextField } from '../inputs/MRT_EditCellTextField' -import type { MRT_Row, MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' +import type { MRT_Row, MRT_RowData } from '../../types' import type { DialogProps } from '@mui/material/Dialog' -export interface MRT_EditRowModalProps< - TData extends MRT_RowData, -> extends Partial { +export interface MRT_EditRowModalProps extends Partial { open: boolean - table: MRT_TableInstance } -export const MRT_EditRowModal = ({ +export const MRT_EditRowModal = ({ open, - table, ...rest -}: MRT_EditRowModalProps) => { +}: MRT_EditRowModalProps) => { + const table = useMRTContext() const { state, options: { @@ -48,13 +46,7 @@ export const MRT_EditRowModal = ({ const internalEditComponents = row .getAllCells() .filter((cell) => cell.column.columnDef.columnDefType === 'data') - .map((cell) => ( - - )) + .map((cell) => ) return ( ({ onEditingRowCancel?.({ row, table }) setEditingRow(null) } - row._valuesCache = {} as any // reset values cache + row._valuesCache = {} // reset values cache dialogProps.onClose?.(event, reason) }} open={open} @@ -103,7 +95,7 @@ export const MRT_EditRowModal = ({ - + )} diff --git a/examples/react/material-react-table/src/material-react-table/components/table/MRT_Table.tsx b/examples/react/material-react-table/src/material-react-table/components/table/MRT_Table.tsx index 47d882b176..c4f91d700a 100644 --- a/examples/react/material-react-table/src/material-react-table/components/table/MRT_Table.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/table/MRT_Table.tsx @@ -6,17 +6,13 @@ import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_TableBody, Memo_MRT_TableBody } from '../body/MRT_TableBody' import { MRT_TableFooter } from '../footer/MRT_TableFooter' import { MRT_TableHead } from '../head/MRT_TableHead' -import type { MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { TableProps } from '@mui/material/Table' -export interface MRT_TableProps extends TableProps { - table: MRT_TableInstance -} +export interface MRT_TableProps extends TableProps {} -export const MRT_Table = ({ - table, - ...rest -}: MRT_TableProps) => { +export const MRT_Table = ({ ...rest }: MRT_TableProps) => { + const table = useMRTContext() const { getFlatHeaders, state, @@ -56,7 +52,6 @@ export const MRT_Table = ({ const commonTableGroupProps = { columnVirtualizer, - table, } return ( diff --git a/examples/react/material-react-table/src/material-react-table/components/table/MRT_TableContainer.tsx b/examples/react/material-react-table/src/material-react-table/components/table/MRT_TableContainer.tsx index f8d7e3cb39..bc4c9a1153 100644 --- a/examples/react/material-react-table/src/material-react-table/components/table/MRT_TableContainer.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/table/MRT_TableContainer.tsx @@ -3,24 +3,18 @@ import TableContainer from '@mui/material/TableContainer' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_CellActionMenu } from '../menus/MRT_CellActionMenu' import { MRT_EditRowModal } from '../modals/MRT_EditRowModal' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableLoadingOverlay } from './MRT_TableLoadingOverlay' import { MRT_Table } from './MRT_Table' -import type { MRT_RowData, MRT_TableInstance } from '../../types' import type { TableContainerProps } from '@mui/material/TableContainer' const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect -export interface MRT_TableContainerProps< - TData extends MRT_RowData, -> extends TableContainerProps { - table: MRT_TableInstance -} +export interface MRT_TableContainerProps extends TableContainerProps {} -export const MRT_TableContainer = ({ - table, - ...rest -}: MRT_TableContainerProps) => { +export const MRT_TableContainer = ({ ...rest }: MRT_TableContainerProps) => { + const table = useMRTContext() const { state, options: { @@ -100,12 +94,10 @@ export const MRT_TableContainer = ({ ...(parseFromValuesOrFunc(tableContainerProps?.sx, theme) as any), })} > - {loading ? : null} - - {(createModalOpen || editModalOpen) && ( - - )} - {enableCellActions && actionCell && } + {loading ? : null} + + {(createModalOpen || editModalOpen) && } + {enableCellActions && actionCell && } ) } diff --git a/examples/react/material-react-table/src/material-react-table/components/table/MRT_TableLoadingOverlay.tsx b/examples/react/material-react-table/src/material-react-table/components/table/MRT_TableLoadingOverlay.tsx index 093df19810..a1381d5174 100644 --- a/examples/react/material-react-table/src/material-react-table/components/table/MRT_TableLoadingOverlay.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/table/MRT_TableLoadingOverlay.tsx @@ -2,19 +2,15 @@ import Box from '@mui/material/Box' import CircularProgress from '@mui/material/CircularProgress' import { alpha } from '@mui/material/styles' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { CircularProgressProps } from '@mui/material/CircularProgress' -import type { MRT_RowData, MRT_TableInstance } from '../../types' -export interface MRT_TableLoadingOverlayProps< - TData extends MRT_RowData, -> extends CircularProgressProps { - table: MRT_TableInstance -} +export interface MRT_TableLoadingOverlayProps extends CircularProgressProps {} -export const MRT_TableLoadingOverlay = ({ - table, +export const MRT_TableLoadingOverlay = ({ ...rest -}: MRT_TableLoadingOverlayProps) => { +}: MRT_TableLoadingOverlayProps) => { + const table = useMRTContext() const { options: { id, diff --git a/examples/react/material-react-table/src/material-react-table/components/table/MRT_TablePaper.tsx b/examples/react/material-react-table/src/material-react-table/components/table/MRT_TablePaper.tsx index b6936df019..5496f0fa09 100644 --- a/examples/react/material-react-table/src/material-react-table/components/table/MRT_TablePaper.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/table/MRT_TablePaper.tsx @@ -3,20 +3,14 @@ import { useTheme } from '@mui/material/styles' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_BottomToolbar } from '../toolbar/MRT_BottomToolbar' import { MRT_TopToolbar } from '../toolbar/MRT_TopToolbar' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_TableContainer } from './MRT_TableContainer' -import type { MRT_RowData, MRT_TableInstance } from '../../types' import type { PaperProps } from '@mui/material/Paper' -export interface MRT_TablePaperProps< - TData extends MRT_RowData, -> extends PaperProps { - table: MRT_TableInstance -} +export interface MRT_TablePaperProps extends PaperProps {} -export const MRT_TablePaper = ({ - table, - ...rest -}: MRT_TablePaperProps) => { +export const MRT_TablePaper = ({ ...rest }: MRT_TablePaperProps) => { + const table = useMRTContext() const { state, options: { @@ -79,12 +73,12 @@ export const MRT_TablePaper = ({ > {enableTopToolbar && (parseFromValuesOrFunc(renderTopToolbar, { table }) ?? ( - + ))} - + {enableBottomToolbar && (parseFromValuesOrFunc(renderBottomToolbar, { table }) ?? ( - + ))} ) diff --git a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_BottomToolbar.tsx b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_BottomToolbar.tsx index 1828a3b976..719e5172cd 100644 --- a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_BottomToolbar.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_BottomToolbar.tsx @@ -3,23 +3,17 @@ import { alpha } from '@mui/material/styles' import useMediaQuery from '@mui/material/useMediaQuery' import { getCommonToolbarStyles } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_LinearProgressBar } from './MRT_LinearProgressBar' import { MRT_TablePagination } from './MRT_TablePagination' import { MRT_ToolbarAlertBanner } from './MRT_ToolbarAlertBanner' import { MRT_ToolbarDropZone } from './MRT_ToolbarDropZone' -import type { MRT_RowData, MRT_TableInstance } from '../../types' import type { BoxProps } from '@mui/material/Box' -export interface MRT_BottomToolbarProps< - TData extends MRT_RowData, -> extends BoxProps { - table: MRT_TableInstance -} +export interface MRT_BottomToolbarProps extends BoxProps {} -export const MRT_BottomToolbar = ({ - table, - ...rest -}: MRT_BottomToolbarProps) => { +export const MRT_BottomToolbar = ({ ...rest }: MRT_BottomToolbarProps) => { + const table = useMRTContext() const { state, options: { @@ -68,15 +62,12 @@ export const MRT_BottomToolbar = ({ ...(parseFromValuesOrFunc(toolbarProps?.sx, theme) as any), })} > - + {positionToolbarAlertBanner === 'bottom' && ( - + )} {['both', 'bottom'].includes(positionToolbarDropZone ?? '') && ( - + )} ({ > {enablePagination && ['both', 'bottom'].includes(positionPagination ?? '') && ( - + )} diff --git a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_LinearProgressBar.tsx b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_LinearProgressBar.tsx index 820eeeba78..bf93761c2d 100644 --- a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_LinearProgressBar.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_LinearProgressBar.tsx @@ -1,21 +1,18 @@ import Collapse from '@mui/material/Collapse' import LinearProgress from '@mui/material/LinearProgress' import { parseFromValuesOrFunc } from '../../utils/utils' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { LinearProgressProps } from '@mui/material/LinearProgress' -import type { MRT_RowData, MRT_TableInstance } from '../../types' -export interface MRT_LinearProgressBarProps< - TData extends MRT_RowData, -> extends LinearProgressProps { +export interface MRT_LinearProgressBarProps extends LinearProgressProps { isTopToolbar: boolean - table: MRT_TableInstance } -export const MRT_LinearProgressBar = ({ +export const MRT_LinearProgressBar = ({ isTopToolbar, - table, ...rest -}: MRT_LinearProgressBarProps) => { +}: MRT_LinearProgressBarProps) => { + const table = useMRTContext() const { state, options: { muiLinearProgressProps }, diff --git a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_TablePagination.tsx b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_TablePagination.tsx index f669d6a0b0..b9d6a381cc 100644 --- a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_TablePagination.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_TablePagination.tsx @@ -11,15 +11,13 @@ import { useTheme } from '@mui/material/styles' import useMediaQuery from '@mui/material/useMediaQuery' import { flipIconStyles, getCommonTooltipProps } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { SelectProps } from '@mui/material/Select' import type { PaginationProps } from '@mui/material/Pagination' const defaultRowsPerPage = [5, 10, 15, 20, 25, 30, 50, 100] -export interface MRT_TablePaginationProps< - TData extends MRT_RowData, -> extends Partial< +export interface MRT_TablePaginationProps extends Partial< PaginationProps & { SelectProps?: Partial disabled?: boolean @@ -28,14 +26,13 @@ export interface MRT_TablePaginationProps< } > { position?: 'bottom' | 'top' - table: MRT_TableInstance } -export const MRT_TablePagination = ({ +export const MRT_TablePagination = ({ position = 'bottom', - table, ...rest -}: MRT_TablePaginationProps) => { +}: MRT_TablePaginationProps) => { + const table = useMRTContext() const theme = useTheme() const isMobile = useMediaQuery('(max-width: 720px)') diff --git a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarAlertBanner.tsx b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarAlertBanner.tsx index 3cbe0d6766..7d40da0fe8 100644 --- a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarAlertBanner.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarAlertBanner.tsx @@ -9,21 +9,18 @@ import Stack from '@mui/material/Stack' import { getMRT_SelectAllHandler } from '../../utils/row.utils' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_SelectCheckbox } from '../inputs/MRT_SelectCheckbox' -import type { MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { AlertProps } from '@mui/material/Alert' -export interface MRT_ToolbarAlertBannerProps< - TData extends MRT_RowData, -> extends AlertProps { +export interface MRT_ToolbarAlertBannerProps extends AlertProps { stackAlertBanner?: boolean - table: MRT_TableInstance } -export const MRT_ToolbarAlertBanner = ({ +export const MRT_ToolbarAlertBanner = ({ stackAlertBanner, - table, ...rest -}: MRT_ToolbarAlertBannerProps) => { +}: MRT_ToolbarAlertBannerProps) => { + const table = useMRTContext() const { getFilteredSelectedRowModel, getCoreRowModel, @@ -96,8 +93,8 @@ export const MRT_ToolbarAlertBanner = ({ {index > 0 ? localization.thenBy : ''} table.getColumn(columnId).toggleGrouping()} + label={table.getColumn(columnId)!.columnDef.header} + onDelete={() => table.getColumn(columnId)!.toggleGrouping()} {...chipProps} /> @@ -165,7 +162,7 @@ export const MRT_ToolbarAlertBanner = ({ {enableRowSelection && enableSelectAll && positionToolbarAlertBanner === 'head-overlay' && ( - + )}{' '} {selectedAlert} diff --git a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarDropZone.tsx b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarDropZone.tsx index 992a050239..09b60da1fa 100644 --- a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarDropZone.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarDropZone.tsx @@ -4,20 +4,14 @@ import Fade from '@mui/material/Fade' import Typography from '@mui/material/Typography' import { alpha } from '@mui/material/styles' import { parseFromValuesOrFunc } from '../../utils/utils' -import type { MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { BoxProps } from '@mui/material/Box' import type { DragEvent } from 'react' -export interface MRT_ToolbarDropZoneProps< - TData extends MRT_RowData, -> extends BoxProps { - table: MRT_TableInstance -} +export interface MRT_ToolbarDropZoneProps extends BoxProps {} -export const MRT_ToolbarDropZone = ({ - table, - ...rest -}: MRT_ToolbarDropZoneProps) => { +export const MRT_ToolbarDropZone = ({ ...rest }: MRT_ToolbarDropZoneProps) => { + const table = useMRTContext() const { state, options: { enableGrouping, localization }, diff --git a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarInternalButtons.tsx b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarInternalButtons.tsx index 62187f6ff7..9a490e6458 100644 --- a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarInternalButtons.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_ToolbarInternalButtons.tsx @@ -5,19 +5,15 @@ import { MRT_ToggleDensePaddingButton } from '../buttons/MRT_ToggleDensePaddingB import { MRT_ToggleFiltersButton } from '../buttons/MRT_ToggleFiltersButton' import { MRT_ToggleFullScreenButton } from '../buttons/MRT_ToggleFullScreenButton' import { MRT_ToggleGlobalFilterButton } from '../buttons/MRT_ToggleGlobalFilterButton' -import type { MRT_RowData, MRT_TableInstance } from '../../types' +import { useMRTContext } from '../../hooks/mrtTableHook' import type { BoxProps } from '@mui/material/Box' -export interface MRT_ToolbarInternalButtonsProps< - TData extends MRT_RowData, -> extends BoxProps { - table: MRT_TableInstance -} +export interface MRT_ToolbarInternalButtonsProps extends BoxProps {} -export const MRT_ToolbarInternalButtons = ({ - table, +export const MRT_ToolbarInternalButtons = ({ ...rest -}: MRT_ToolbarInternalButtonsProps) => { +}: MRT_ToolbarInternalButtonsProps) => { + const table = useMRTContext() const { options: { columnFilterDisplayMode, @@ -50,23 +46,17 @@ export const MRT_ToolbarInternalButtons = ({ <> {enableFilters && enableGlobalFilter && - !initialState?.showGlobalFilter && ( - - )} + !initialState?.showGlobalFilter && } {enableFilters && enableColumnFilters && columnFilterDisplayMode !== 'popover' && ( - + )} {(enableHiding || enableColumnOrdering || enableColumnPinning) && ( - - )} - {enableDensityToggle && ( - - )} - {enableFullScreenToggle && ( - + )} + {enableDensityToggle && } + {enableFullScreenToggle && } )} diff --git a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_TopToolbar.tsx b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_TopToolbar.tsx index ff5f3f4571..0e792e3c0d 100644 --- a/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_TopToolbar.tsx +++ b/examples/react/material-react-table/src/material-react-table/components/toolbar/MRT_TopToolbar.tsx @@ -3,20 +3,17 @@ import useMediaQuery from '@mui/material/useMediaQuery' import { getCommonToolbarStyles } from '../../utils/style.utils' import { parseFromValuesOrFunc } from '../../utils/utils' import { MRT_GlobalFilterTextField } from '../inputs/MRT_GlobalFilterTextField' +import { useMRTContext } from '../../hooks/mrtTableHook' import { MRT_LinearProgressBar } from './MRT_LinearProgressBar' import { MRT_TablePagination } from './MRT_TablePagination' import { MRT_ToolbarAlertBanner } from './MRT_ToolbarAlertBanner' import { MRT_ToolbarDropZone } from './MRT_ToolbarDropZone' import { MRT_ToolbarInternalButtons } from './MRT_ToolbarInternalButtons' -import type { MRT_RowData, MRT_TableInstance } from '../../types' -export interface MRT_TopToolbarProps { - table: MRT_TableInstance -} +export interface MRT_TopToolbarProps {} -export const MRT_TopToolbar = ({ - table, -}: MRT_TopToolbarProps) => { +export const MRT_TopToolbar = (_props: MRT_TopToolbarProps) => { + const table = useMRTContext() const { state, options: { @@ -72,13 +69,10 @@ export const MRT_TopToolbar = ({ })} > {positionToolbarAlertBanner === 'top' && ( - + )} {['both', 'top'].includes(positionToolbarDropZone ?? '') && ( - + )} ({ {enableGlobalFilter && positionGlobalFilter === 'right' && ( )} - + ) : ( enableGlobalFilter && @@ -122,9 +116,9 @@ export const MRT_TopToolbar = ({ {enablePagination && ['both', 'top'].includes(positionPagination ?? '') && ( - + )} - + ) } diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtCellActionsFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtCellActionsFeature.ts new file mode 100644 index 0000000000..25a74206be --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtCellActionsFeature.ts @@ -0,0 +1,80 @@ +import { + assignTableAPIs, + functionalUpdate, + makeStateUpdater, +} from '@tanstack/react-table' +import type { + Cell, + OnChangeFn, + RowData, + TableFeature, + TableFeatures, + Updater, +} from '@tanstack/react-table' + +/** + * `TableState_FeatureMap` is non-generic, so instance-bearing slices are typed + * with `Cell`. The `MRT_Cell` shape is what components see + * through the (Phase 1) `MRT_TableInstance` wrapper. + */ +export interface MRT_TableState_CellActions { + actionCell: Cell | null +} + +export interface MRT_TableOptions_CellActions { + onActionCellChange?: OnChangeFn | null> +} + +export interface MRT_Table_CellActions< + TFeatures extends TableFeatures, + TData extends RowData, +> { + setActionCell: ( + updater: Updater | null>, + ) => void +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtCellActionsFeature: TableFeature + } + interface TableState_FeatureMap { + mrtCellActionsFeature: MRT_TableState_CellActions + } + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtCellActionsFeature: MRT_TableOptions_CellActions + } + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtCellActionsFeature: MRT_Table_CellActions + } +} + +/** + * Tracks the cell whose action menu is open (`actionCell`) plus the + * `table.setActionCell` API. + */ +export const mrtCellActionsFeature: TableFeature = { + getInitialState: (initialState) => ({ + actionCell: null, + ...initialState, + }), + getDefaultTableOptions: (table) => ({ + onActionCellChange: makeStateUpdater('actionCell', table), + }), + constructTableAPIs: (table) => { + assignTableAPIs('mrtCellActionsFeature', table, { + table_setActionCell: { + fn: (updater: Updater | null>) => + (table.options as MRT_TableOptions_CellActions).onActionCellChange?.( + (old) => functionalUpdate(updater, old), + ), + }, + }) + }, +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtColumnDraggingFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtColumnDraggingFeature.ts new file mode 100644 index 0000000000..9d1f6c7df9 --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtColumnDraggingFeature.ts @@ -0,0 +1,88 @@ +import { + assignTableAPIs, + functionalUpdate, + makeStateUpdater, +} from '@tanstack/react-table' +import type { + Column, + OnChangeFn, + RowData, + TableFeature, + TableFeatures, + Updater, +} from '@tanstack/react-table' + +export interface MRT_TableState_ColumnDragging { + draggingColumn: Column | null + hoveredColumn: Partial> | null +} + +export interface MRT_TableOptions_ColumnDragging { + onDraggingColumnChange?: OnChangeFn | null> + onHoveredColumnChange?: OnChangeFn> | null> +} + +export interface MRT_Table_ColumnDragging< + TFeatures extends TableFeatures, + TData extends RowData, +> { + setDraggingColumn: ( + updater: Updater | null>, + ) => void + setHoveredColumn: ( + updater: Updater> | null>, + ) => void +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtColumnDraggingFeature: TableFeature + } + interface TableState_FeatureMap { + mrtColumnDraggingFeature: MRT_TableState_ColumnDragging + } + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtColumnDraggingFeature: MRT_TableOptions_ColumnDragging + } + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtColumnDraggingFeature: MRT_Table_ColumnDragging + } +} + +/** + * Tracks the column being dragged and the column currently hovered during a + * drag/reorder gesture, plus the `setDraggingColumn` / `setHoveredColumn` APIs. + */ +export const mrtColumnDraggingFeature: TableFeature = { + getInitialState: (initialState) => ({ + draggingColumn: null, + hoveredColumn: null, + ...initialState, + }), + getDefaultTableOptions: (table) => ({ + onDraggingColumnChange: makeStateUpdater('draggingColumn', table), + onHoveredColumnChange: makeStateUpdater('hoveredColumn', table), + }), + constructTableAPIs: (table) => { + assignTableAPIs('mrtColumnDraggingFeature', table, { + table_setDraggingColumn: { + fn: (updater: Updater | null>) => + ( + table.options as MRT_TableOptions_ColumnDragging + ).onDraggingColumnChange?.((old) => functionalUpdate(updater, old)), + }, + table_setHoveredColumn: { + fn: (updater: Updater> | null>) => + ( + table.options as MRT_TableOptions_ColumnDragging + ).onHoveredColumnChange?.((old) => functionalUpdate(updater, old)), + }, + }) + }, +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtConfigFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtConfigFeature.ts new file mode 100644 index 0000000000..7313c877f4 --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtConfigFeature.ts @@ -0,0 +1,778 @@ +import type { ReactNode, RefObject } from 'react' +import type { + Cell, + CellData, + Column, + DeepKeys, + Header, + HeaderGroup, + Row, + RowData, + Table, + TableFeature, + TableFeatures, +} from '@tanstack/react-table' +import type { VirtualizerOptions } from '@tanstack/react-virtual' +import type { AlertProps } from '@mui/material/Alert' +import type { AutocompleteProps } from '@mui/material/Autocomplete' +import type { BoxProps } from '@mui/material/Box' +import type { ButtonProps } from '@mui/material/Button' +import type { CheckboxProps } from '@mui/material/Checkbox' +import type { ChipProps } from '@mui/material/Chip' +import type { CircularProgressProps } from '@mui/material/CircularProgress' +import type { DialogProps } from '@mui/material/Dialog' +import type { IconButtonProps } from '@mui/material/IconButton' +import type { LinearProgressProps } from '@mui/material/LinearProgress' +import type { PaginationProps } from '@mui/material/Pagination' +import type { PaperProps } from '@mui/material/Paper' +import type { RadioProps } from '@mui/material/Radio' +import type { SelectProps } from '@mui/material/Select' +import type { SkeletonProps } from '@mui/material/Skeleton' +import type { SliderProps } from '@mui/material/Slider' +import type { TableProps } from '@mui/material/Table' +import type { TableBodyProps } from '@mui/material/TableBody' +import type { TableCellProps } from '@mui/material/TableCell' +import type { TableContainerProps } from '@mui/material/TableContainer' +import type { TableFooterProps } from '@mui/material/TableFooter' +import type { TableHeadProps } from '@mui/material/TableHead' +import type { TableRowProps } from '@mui/material/TableRow' +import type { TextFieldProps } from '@mui/material/TextField' +import type { Theme } from '@mui/material/styles' +import type { + DatePickerProps, + DateTimePickerProps, + TimePickerProps, +} from '@mui/x-date-pickers' +import type { + DropdownOption, + LiteralUnion, + MRT_ColumnVirtualizer, + MRT_DisplayColumnDef, + MRT_DisplayColumnIds, + MRT_FilterOption, + MRT_Icons, + MRT_InternalFilterOption, + MRT_Localization, + MRT_RowVirtualizer, + MRT_Theme, +} from '../types' + +/** + * A runtime no-op feature whose sole purpose is to move Material React Table's + * option and column-def types onto v9's feature-map declaration-merging system. + * + * Rather than hand-writing `MRT_TableOptions` / `MRT_ColumnDef` wrapper + * interfaces, the members below are merged into `TableOptions` + * and `ColumnDef` via `TableOptions_FeatureMap` / + * `ColumnDef_FeatureMap`. Core-owned options and members already declared by + * sibling MRT features (the `onXChange` handlers, etc.) are intentionally left + * out so the intersection stays conflict-free. + */ +export const mrtConfigFeature: TableFeature = {} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtConfigFeature: TableFeature + } + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtConfigFeature: MRT_TableOptions_Config + } + interface ColumnDef_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData, + > { + mrtConfigFeature: MRT_ColumnDef_Config + } +} + +export interface MRT_TableOptions_Config< + TFeatures extends TableFeatures, + TData extends RowData, +> { + columnFilterDisplayMode?: 'custom' | 'popover' | 'subheader' + columnFilterModeOptions?: Array< + LiteralUnion + > | null + columnVirtualizerInstanceRef?: RefObject + columnVirtualizerOptions?: + | ((props: { + table: Table + }) => Partial>) + | Partial> + createDisplayMode?: 'custom' | 'modal' | 'row' + defaultDisplayColumn?: Partial> + displayColumnDefOptions?: Partial<{ + [key in MRT_DisplayColumnIds]: Partial> + }> + editDisplayMode?: 'cell' | 'custom' | 'modal' | 'row' | 'table' + enableBatchRowSelection?: boolean + enableBottomToolbar?: boolean + enableCellActions?: + | ((cell: Cell) => boolean) + | boolean + enableClickToCopy?: + | 'context-menu' + | ((cell: Cell) => 'context-menu' | boolean) + | boolean + enableColumnActions?: boolean + enableColumnDragging?: boolean + enableColumnFilterModes?: boolean + enableColumnOrdering?: boolean + enableColumnVirtualization?: boolean + enableDensityToggle?: boolean + enableEditing?: ((row: Row) => boolean) | boolean + enableExpandAll?: boolean + enableFacetedValues?: boolean + enableFilterMatchHighlighting?: boolean + enableFullScreenToggle?: boolean + enableGlobalFilterModes?: boolean + enableGlobalFilterRankedResults?: boolean + enableKeyboardShortcuts?: boolean + enablePagination?: boolean + enableRowActions?: boolean + enableRowDragging?: boolean + enableRowNumbers?: boolean + enableRowOrdering?: boolean + enableRowVirtualization?: boolean + enableSelectAll?: boolean + enableStickyFooter?: boolean + enableStickyHeader?: boolean + enableTableFooter?: boolean + enableTableHead?: boolean + enableToolbarInternalActions?: boolean + enableTopToolbar?: boolean + globalFilterModeOptions?: Array | null + icons?: Partial + id?: string + /** + * Changes which kind of CSS layout is used to render the table. `semantic` uses default semantic HTML elements, while `grid` adds CSS grid and flexbox styles + */ + layoutMode?: 'grid' | 'grid-no-grow' | 'semantic' + /** + * Pass in either a locale imported from `material-react-table/locales/*` or a custom locale object. + * + * See the localization (i18n) guide for more info: + * @link https://www.material-react-table.com/docs/guides/localization + */ + localization?: Partial + /** + * Memoize cells, rows, or the entire table body to potentially improve render performance. + * + * @warning This will break some dynamic rendering features. See the memoization guide for more info: + * @link https://www.material-react-table.com/docs/guides/memoize-components + */ + memoMode?: 'cells' | 'rows' | 'table-body' + mrtTheme?: ((theme: Theme) => Partial) | Partial + muiBottomToolbarProps?: + | ((props: { table: Table }) => BoxProps) + | BoxProps + muiCircularProgressProps?: + | ((props: { + table: Table + }) => CircularProgressProps & { Component?: ReactNode }) + | (CircularProgressProps & { Component?: ReactNode }) + muiColumnActionsButtonProps?: + | ((props: { + column: Column + table: Table + }) => IconButtonProps) + | IconButtonProps + muiColumnDragHandleProps?: + | ((props: { + column: Column + table: Table + }) => IconButtonProps) + | IconButtonProps + muiCopyButtonProps?: + | ((props: { + cell: Cell + column: Column + row: Row + table: Table + }) => ButtonProps) + | ButtonProps + muiCreateRowModalProps?: + | ((props: { + row: Row + table: Table + }) => DialogProps) + | DialogProps + muiDetailPanelProps?: + | ((props: { + row: Row + table: Table + }) => TableCellProps) + | TableCellProps + muiEditRowDialogProps?: + | ((props: { + row: Row + table: Table + }) => DialogProps) + | DialogProps + muiEditTextFieldProps?: + | ((props: { + cell: Cell + column: Column + row: Row + table: Table + }) => TextFieldProps) + | TextFieldProps + muiExpandAllButtonProps?: + | ((props: { table: Table }) => IconButtonProps) + | IconButtonProps + muiExpandButtonProps?: + | ((props: { + row: Row + staticRowIndex?: number + table: Table + }) => IconButtonProps) + | IconButtonProps + muiFilterAutocompleteProps?: + | ((props: { + column: Column + table: Table + }) => AutocompleteProps) + | AutocompleteProps + muiFilterCheckboxProps?: + | ((props: { + column: Column + table: Table + }) => CheckboxProps) + | CheckboxProps + muiFilterDatePickerProps?: + | ((props: { + column: Column + rangeFilterIndex?: number + table: Table + }) => DatePickerProps) + | DatePickerProps + muiFilterDateTimePickerProps?: + | ((props: { + column: Column + rangeFilterIndex?: number + table: Table + }) => DateTimePickerProps) + | DateTimePickerProps + muiFilterSliderProps?: + | ((props: { + column: Column + table: Table + }) => SliderProps) + | SliderProps + muiFilterTextFieldProps?: + | ((props: { + column: Column + rangeFilterIndex?: number + table: Table + }) => TextFieldProps) + | TextFieldProps + muiFilterTimePickerProps?: + | ((props: { + column: Column + rangeFilterIndex?: number + table: Table + }) => TimePickerProps) + | TimePickerProps + muiLinearProgressProps?: + | ((props: { + isTopToolbar: boolean + table: Table + }) => LinearProgressProps) + | LinearProgressProps + muiPaginationProps?: + | ((props: { table: Table }) => Partial< + PaginationProps & { + SelectProps?: Partial + disabled?: boolean + rowsPerPageOptions?: + | Array<{ label: string; value: number }> + | Array + showRowsPerPage?: boolean + } + >) + | Partial< + PaginationProps & { + SelectProps?: Partial + disabled?: boolean + rowsPerPageOptions?: + | Array<{ label: string; value: number }> + | Array + showRowsPerPage?: boolean + } + > + muiRowDragHandleProps?: + | ((props: { + row: Row + table: Table + }) => IconButtonProps) + | IconButtonProps + muiSearchTextFieldProps?: + | ((props: { table: Table }) => TextFieldProps) + | TextFieldProps + muiSelectAllCheckboxProps?: + | ((props: { table: Table }) => CheckboxProps) + | CheckboxProps + muiSelectCheckboxProps?: + | ((props: { + row: Row + staticRowIndex?: number + table: Table + }) => CheckboxProps | RadioProps) + | (CheckboxProps | RadioProps) + muiSkeletonProps?: + | ((props: { + cell: Cell + column: Column + row: Row + table: Table + }) => SkeletonProps) + | SkeletonProps + muiTableBodyCellProps?: + | ((props: { + cell: Cell + column: Column + row: Row + table: Table + }) => TableCellProps) + | TableCellProps + muiTableBodyProps?: + | ((props: { table: Table }) => TableBodyProps) + | TableBodyProps + muiTableBodyRowProps?: + | ((props: { + isDetailPanel?: boolean + row: Row + staticRowIndex: number + table: Table + }) => TableRowProps) + | TableRowProps + muiTableContainerProps?: + | ((props: { table: Table }) => TableContainerProps) + | TableContainerProps + muiTableFooterCellProps?: + | ((props: { + column: Column + table: Table + }) => TableCellProps) + | TableCellProps + muiTableFooterProps?: + | ((props: { table: Table }) => TableFooterProps) + | TableFooterProps + muiTableFooterRowProps?: + | ((props: { + footerGroup: HeaderGroup + table: Table + }) => TableRowProps) + | TableRowProps + muiTableHeadCellProps?: + | ((props: { + column: Column + table: Table + }) => TableCellProps) + | TableCellProps + muiTableHeadProps?: + | ((props: { table: Table }) => TableHeadProps) + | TableHeadProps + muiTableHeadRowProps?: + | ((props: { + headerGroup: HeaderGroup + table: Table + }) => TableRowProps) + | TableRowProps + muiTablePaperProps?: + | ((props: { table: Table }) => PaperProps) + | PaperProps + muiTableProps?: + | ((props: { table: Table }) => TableProps) + | TableProps + muiToolbarAlertBannerChipProps?: + | ((props: { table: Table }) => ChipProps) + | ChipProps + muiToolbarAlertBannerProps?: + | ((props: { table: Table }) => AlertProps) + | AlertProps + muiTopToolbarProps?: + | ((props: { table: Table }) => BoxProps) + | BoxProps + onCreatingRowCancel?: (props: { + row: Row + table: Table + }) => void + onCreatingRowSave?: (props: { + exitCreatingMode: () => void + row: Row + table: Table + values: Record>, any> + }) => Promise | void + onEditingRowCancel?: (props: { + row: Row + table: Table + }) => void + onEditingRowSave?: (props: { + exitEditingMode: () => void + row: Row + table: Table + values: Record>, any> + }) => Promise | void + paginationDisplayMode?: 'custom' | 'default' | 'pages' + positionActionsColumn?: 'first' | 'last' + positionCreatingRow?: 'bottom' | 'top' | number + positionExpandColumn?: 'first' | 'last' + positionGlobalFilter?: 'left' | 'none' | 'right' + positionPagination?: 'both' | 'bottom' | 'none' | 'top' + positionToolbarAlertBanner?: 'bottom' | 'head-overlay' | 'none' | 'top' + positionToolbarDropZone?: 'both' | 'bottom' | 'none' | 'top' + renderBottomToolbar?: + | ((props: { table: Table }) => ReactNode) + | ReactNode + renderBottomToolbarCustomActions?: (props: { + table: Table + }) => ReactNode + renderCaption?: + | ((props: { table: Table }) => ReactNode) + | ReactNode + renderCellActionMenuItems?: (props: { + cell: Cell + closeMenu: () => void + column: Column + internalMenuItems: Array + row: Row + staticColumnIndex?: number + staticRowIndex?: number + table: Table + }) => Array + renderColumnActionsMenuItems?: (props: { + closeMenu: () => void + column: Column + internalColumnMenuItems: Array + table: Table + }) => Array + renderColumnFilterModeMenuItems?: (props: { + column: Column + internalFilterOptions: Array + onSelectFilterMode: (filterMode: MRT_FilterOption) => void + table: Table + }) => Array + renderCreateRowDialogContent?: (props: { + internalEditComponents: Array + row: Row + table: Table + }) => ReactNode + renderDetailPanel?: (props: { + row: Row + table: Table + }) => ReactNode + renderEditRowDialogContent?: (props: { + internalEditComponents: Array + row: Row + table: Table + }) => ReactNode + renderEmptyRowsFallback?: (props: { + table: Table + }) => ReactNode + renderGlobalFilterModeMenuItems?: (props: { + internalFilterOptions: Array + onSelectFilterMode: (filterMode: MRT_FilterOption) => void + table: Table + }) => Array + renderRowActionMenuItems?: (props: { + closeMenu: () => void + row: Row + staticRowIndex?: number + table: Table + }) => Array | undefined + renderRowActions?: (props: { + cell: Cell + row: Row + staticRowIndex?: number + table: Table + }) => ReactNode + renderToolbarAlertBannerContent?: (props: { + groupedAlert: ReactNode | null + selectedAlert: ReactNode | null + table: Table + }) => ReactNode + renderToolbarInternalActions?: (props: { + table: Table + }) => ReactNode + renderTopToolbar?: + | ((props: { table: Table }) => ReactNode) + | ReactNode + renderTopToolbarCustomActions?: (props: { + table: Table + }) => ReactNode + rowNumberDisplayMode?: 'original' | 'static' + rowPinningDisplayMode?: + | 'bottom' + | 'select-bottom' + | 'select-sticky' + | 'select-top' + | 'sticky' + | 'top' + | 'top-and-bottom' + rowVirtualizerInstanceRef?: RefObject + rowVirtualizerOptions?: + | ((props: { + table: Table + }) => Partial>) + | Partial> + selectAllMode?: 'all' | 'page' +} + +export interface MRT_ColumnDef_Config< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData, +> { + /** + * The resolved filter-fn name for this column, written onto the column def by + * `prepareColumns` at construction. Optional here (present only after + * resolution); `MRT_DefinedColumnDef` narrows it to required. + */ + _filterFn?: MRT_FilterOption + AggregatedCell?: (props: { + cell: Cell + column: Column + row: Row + table: Table + staticColumnIndex?: number + staticRowIndex?: number + }) => ReactNode + Cell?: (props: { + cell: Cell + column: Column + renderedCellValue: ReactNode + row: Row + rowRef?: RefObject + staticColumnIndex?: number + staticRowIndex?: number + table: Table + }) => ReactNode + /** + * MRT does not render core's lowercase `cell` template; use the capital + * `Cell` slot instead. Narrowed to `never` so passing it is a type error. + */ + cell?: never + /** + * Specify what type of column this is. Either `data`, `display`, or `group`. Defaults to `data`. + * Leave this blank if you are just creating a normal data column. + * + * @default 'data' + * + * @example columnDefType: 'display' + */ + columnDefType?: 'data' | 'display' | 'group' + columnFilterModeOptions?: Array< + LiteralUnion + > | null + Edit?: (props: { + cell: Cell + column: Column + row: Row + table: Table + }) => ReactNode + editSelectOptions?: + | ((props: { + cell: Cell + column: Column + row: Row + table: Table + }) => Array) + | Array + editVariant?: 'select' | 'text' + enableClickToCopy?: + | 'context-menu' + | ((cell: Cell) => 'context-menu' | boolean) + | boolean + enableColumnActions?: boolean + enableColumnDragging?: boolean + enableColumnFilterModes?: boolean + enableColumnOrdering?: boolean + enableEditing?: ((row: Row) => boolean) | boolean + enableFilterMatchHighlighting?: boolean + Filter?: (props: { + column: Column + header: Header + rangeFilterIndex?: number + table: Table + }) => ReactNode + filterSelectOptions?: Array + filterVariant?: + | 'autocomplete' + | 'checkbox' + | 'date' + | 'date-range' + | 'datetime' + | 'datetime-range' + | 'multi-select' + | 'range' + | 'range-slider' + | 'select' + | 'text' + | 'time' + | 'time-range' + Footer?: + | ((props: { + column: Column + footer: Header + table: Table + }) => ReactNode) + | ReactNode + /** + * MRT narrows core's `footer` template to a plain string; use the capital + * `Footer` slot for custom markup. + */ + footer?: string + GroupedCell?: (props: { + cell: Cell + column: Column + row: Row + table: Table + staticColumnIndex?: number + staticRowIndex?: number + }) => ReactNode + /** + * If `layoutMode` is `'grid'` or `'grid-no-grow'`, you can specify the flex grow value for individual columns to still grow and take up remaining space, or set to `false`/0 to not grow. + */ + grow?: boolean | number + Header?: + | ((props: { + column: Column + header: Header + table: Table + }) => ReactNode) + | ReactNode + /** + * MRT narrows core's `header` template to a required plain string: it renders + * as text in menus, filter labels, tooltips, and the alert banner. Use the + * capital `Header` slot for custom header markup. + */ + header: string + muiColumnActionsButtonProps?: + | ((props: { + column: Column + table: Table + }) => IconButtonProps) + | IconButtonProps + muiColumnDragHandleProps?: + | ((props: { + column: Column + table: Table + }) => IconButtonProps) + | IconButtonProps + muiCopyButtonProps?: + | ((props: { + cell: Cell + column: Column + row: Row + table: Table + }) => ButtonProps) + | ButtonProps + muiEditTextFieldProps?: + | ((props: { + cell: Cell + column: Column + row: Row + table: Table + }) => TextFieldProps) + | TextFieldProps + muiFilterAutocompleteProps?: + | ((props: { + column: Column + table: Table + }) => AutocompleteProps) + | AutocompleteProps + muiFilterCheckboxProps?: + | ((props: { + column: Column + table: Table + }) => CheckboxProps) + | CheckboxProps + muiFilterDatePickerProps?: + | ((props: { + column: Column + rangeFilterIndex?: number + table: Table + }) => DatePickerProps) + | DatePickerProps + muiFilterDateTimePickerProps?: + | ((props: { + column: Column + rangeFilterIndex?: number + table: Table + }) => DateTimePickerProps) + | DateTimePickerProps + muiFilterSliderProps?: + | ((props: { + column: Column + table: Table + }) => SliderProps) + | SliderProps + muiFilterTextFieldProps?: + | ((props: { + column: Column + rangeFilterIndex?: number + table: Table + }) => TextFieldProps) + | TextFieldProps + muiFilterTimePickerProps?: + | ((props: { + column: Column + rangeFilterIndex?: number + table: Table + }) => TimePickerProps) + | TimePickerProps + muiTableBodyCellProps?: + | ((props: { + cell: Cell + column: Column + row: Row + table: Table + }) => TableCellProps) + | TableCellProps + muiTableFooterCellProps?: + | ((props: { + column: Column + table: Table + }) => TableCellProps) + | TableCellProps + muiTableHeadCellProps?: + | ((props: { + column: Column + table: Table + }) => TableCellProps) + | TableCellProps + PlaceholderCell?: (props: { + cell: Cell + column: Column + row: Row + table: Table + }) => ReactNode + renderCellActionMenuItems?: (props: { + cell: Cell + closeMenu: () => void + column: Column + internalMenuItems: Array + row: Row + staticColumnIndex?: number + staticRowIndex?: number + table: Table + }) => Array + renderColumnActionsMenuItems?: (props: { + closeMenu: () => void + column: Column + internalColumnMenuItems: Array + table: Table + }) => Array + renderColumnFilterModeMenuItems?: (props: { + column: Column + internalFilterOptions: Array + onSelectFilterMode: (filterMode: MRT_FilterOption) => void + table: Table + }) => Array + visibleInShowHideMenu?: boolean +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtDensityFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtDensityFeature.ts new file mode 100644 index 0000000000..484afaf7c7 --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtDensityFeature.ts @@ -0,0 +1,76 @@ +import { + assignTableAPIs, + functionalUpdate, + makeStateUpdater, +} from '@tanstack/react-table' +import type { + OnChangeFn, + RowData, + TableFeature, + TableFeatures, + Updater, +} from '@tanstack/react-table' +import type { MRT_DensityState } from '../types' + +export interface MRT_TableState_Density { + density: MRT_DensityState +} + +export interface MRT_TableOptions_Density { + enableDensityToggle?: boolean + onDensityChange?: OnChangeFn +} + +export interface MRT_Table_Density { + setDensity: (updater: Updater) => void +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtDensityFeature: TableFeature + } + interface TableState_FeatureMap { + mrtDensityFeature: MRT_TableState_Density + } + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtDensityFeature: MRT_TableOptions_Density + } + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtDensityFeature: MRT_Table_Density + } +} + +/** + * Adds the MRT-only `density` state slice, the `onDensityChange` option + * (defaulted to a base-atom updater), and the `table.setDensity` API. + * + * In v9 a custom feature's `getInitialState` key automatically gets a base + * atom, `table.state.density` tracking, controlled-state sync, and Subscribe — + * so this replaces the hand-rolled atom + setter that MRT maintained in + * `useMRT_TableInstance`. + */ +export const mrtDensityFeature: TableFeature = { + getInitialState: (initialState) => ({ + density: 'comfortable', + ...initialState, + }), + getDefaultTableOptions: (table) => ({ + onDensityChange: makeStateUpdater('density', table), + }), + constructTableAPIs: (table) => { + assignTableAPIs('mrtDensityFeature', table, { + table_setDensity: { + fn: (updater: Updater) => + (table.options as MRT_TableOptions_Density).onDensityChange?.((old) => + functionalUpdate(updater, old), + ), + }, + }) + }, +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtEditingFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtEditingFeature.ts new file mode 100644 index 0000000000..37bf0746ee --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtEditingFeature.ts @@ -0,0 +1,106 @@ +import { + assignTableAPIs, + functionalUpdate, + makeStateUpdater, +} from '@tanstack/react-table' +import { createRow } from '../utils/tanstack.helpers' +import type { + Cell, + OnChangeFn, + Row, + RowData, + TableFeature, + TableFeatures, + Updater, +} from '@tanstack/react-table' + +export interface MRT_TableState_Editing { + creatingRow: Row | null + editingCell: Cell | null + editingRow: Row | null +} + +export interface MRT_TableOptions_Editing { + onCreatingRowChange?: OnChangeFn | null> + onEditingCellChange?: OnChangeFn | null> + onEditingRowChange?: OnChangeFn | null> +} + +export interface MRT_Table_Editing< + TFeatures extends TableFeatures, + TData extends RowData, +> { + setCreatingRow: ( + updater: Updater | null | true>, + ) => void + setEditingCell: ( + updater: Updater | null>, + ) => void + setEditingRow: (updater: Updater | null>) => void +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtEditingFeature: TableFeature + } + interface TableState_FeatureMap { + mrtEditingFeature: MRT_TableState_Editing + } + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtEditingFeature: MRT_TableOptions_Editing + } + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtEditingFeature: MRT_Table_Editing + } +} + +/** + * Owns the `creatingRow` / `editingCell` / `editingRow` state slices and their + * setters. `setCreatingRow(true)` is sugar for "start creating a blank row" — + * it fabricates one via `createRow(table)`, preserving MRT's existing behavior. + */ +export const mrtEditingFeature: TableFeature = { + getInitialState: (initialState) => ({ + creatingRow: null, + editingCell: null, + editingRow: null, + ...initialState, + }), + getDefaultTableOptions: (table) => ({ + onCreatingRowChange: makeStateUpdater('creatingRow', table), + onEditingCellChange: makeStateUpdater('editingCell', table), + onEditingRowChange: makeStateUpdater('editingRow', table), + }), + constructTableAPIs: (table) => { + assignTableAPIs('mrtEditingFeature', table, { + table_setCreatingRow: { + fn: (updater: Updater | null | true>) => + (table.options as MRT_TableOptions_Editing).onCreatingRowChange?.( + (old) => { + let next = functionalUpdate(updater, old as any) + if (next === true) next = createRow(table as any) as any + return next as Row | null + }, + ), + }, + table_setEditingCell: { + fn: (updater: Updater | null>) => + (table.options as MRT_TableOptions_Editing).onEditingCellChange?.( + (old) => functionalUpdate(updater, old), + ), + }, + table_setEditingRow: { + fn: (updater: Updater | null>) => + (table.options as MRT_TableOptions_Editing).onEditingRowChange?.( + (old) => functionalUpdate(updater, old), + ), + }, + }) + }, +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtFeatures.ts b/examples/react/material-react-table/src/material-react-table/features/mrtFeatures.ts new file mode 100644 index 0000000000..c0d6a603da --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtFeatures.ts @@ -0,0 +1,75 @@ +import { + createCoreRowModel, + createExpandedRowModel, + createFacetedMinMaxValues, + createFacetedRowModel, + createFacetedUniqueValues, + createFilteredRowModel, + createGroupedRowModel, + createPaginatedRowModel, + createSortedRowModel, + stockFeatures, + tableFeatures, +} from '@tanstack/react-table' +import { MRT_AggregationFns } from '../fns/aggregationFns' +import { MRT_FilterFns } from '../fns/filterFns' +import { MRT_SortFns } from '../fns/sortingFns' +import { mrtCellActionsFeature } from './mrtCellActionsFeature' +import { mrtColumnDraggingFeature } from './mrtColumnDraggingFeature' +import { mrtConfigFeature } from './mrtConfigFeature' +import { mrtDensityFeature } from './mrtDensityFeature' +import { mrtEditingFeature } from './mrtEditingFeature' +import { mrtFilterModesFeature } from './mrtFilterModesFeature' +import { mrtFullScreenFeature } from './mrtFullScreenFeature' +import { mrtLoadingFeature } from './mrtLoadingFeature' +import { mrtRefsFeature } from './mrtRefsFeature' +import { mrtRowDraggingFeature } from './mrtRowDraggingFeature' +import { mrtToolbarsFeature } from './mrtToolbarsFeature' + +/** + * The complete, static feature registry for Material React Table. + * + * Every stock feature plus every MRT custom feature is included unconditionally. + * Row models are runtime-gated by the `manual*` options (see + * `coreRowModelsFeature.utils`), so a client that disables a feature simply runs + * that model over empty state (an identity pass) — the same result MRT's old + * conditional feature assembly produced, without rebuilding `features` per table. + * + * The `filterFns` / `sortFns` / `aggregationFns` registries here supply the + * built-in named functions and their string-name types. Client-supplied custom + * functions (`options.filterFns` etc.) are merged over these at construction + * time in `useMRT_TableInstance`. + */ +export const mrtFeatures = tableFeatures({ + ...stockFeatures, + mrtCellActionsFeature, + mrtColumnDraggingFeature, + mrtConfigFeature, + mrtDensityFeature, + mrtEditingFeature, + mrtFilterModesFeature, + mrtFullScreenFeature, + mrtLoadingFeature, + mrtRefsFeature, + mrtRowDraggingFeature, + mrtToolbarsFeature, + coreRowModel: createCoreRowModel(), + filteredRowModel: createFilteredRowModel(), + sortedRowModel: createSortedRowModel(), + groupedRowModel: createGroupedRowModel(), + expandedRowModel: createExpandedRowModel(), + paginatedRowModel: createPaginatedRowModel(), + facetedRowModel: createFacetedRowModel(), + facetedMinMaxValues: createFacetedMinMaxValues(), + facetedUniqueValues: createFacetedUniqueValues(), + // These MRT fn registries are authored against `Row`, which is + // invariant against the `Row` the feature slot expects, so they're + // cast here. Named-function string typing still flows through `MRT_FilterOption` + // / `MRT_SortingOption` / `MRT_AggregationOption` (derived from `typeof` each + // registry), so nothing downstream loses inference. + filterFns: MRT_FilterFns as any, + sortFns: MRT_SortFns as any, + aggregationFns: MRT_AggregationFns as any, +}) + +export type MRT_Features = typeof mrtFeatures diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtFilterModesFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtFilterModesFeature.ts new file mode 100644 index 0000000000..67ce0bf281 --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtFilterModesFeature.ts @@ -0,0 +1,112 @@ +import { + assignTableAPIs, + functionalUpdate, + makeStateUpdater, +} from '@tanstack/react-table' +import type { + OnChangeFn, + RowData, + TableFeature, + TableFeatures, + Updater, +} from '@tanstack/react-table' +import type { MRT_ColumnFilterFnsState, MRT_FilterOption } from '../types' + +export interface MRT_TableState_FilterModes { + columnFilterFns: MRT_ColumnFilterFnsState + globalFilterFn: MRT_FilterOption + showColumnFilters: boolean + showGlobalFilter: boolean +} + +export interface MRT_TableOptions_FilterModes { + onColumnFilterFnsChange?: OnChangeFn + onGlobalFilterFnChange?: OnChangeFn + onShowColumnFiltersChange?: OnChangeFn + onShowGlobalFilterChange?: OnChangeFn +} + +export interface MRT_Table_FilterModes { + setColumnFilterFns: (updater: Updater) => void + setGlobalFilterFn: (updater: Updater) => void + setShowColumnFilters: (updater: Updater) => void + setShowGlobalFilter: (updater: Updater) => void +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtFilterModesFeature: TableFeature + } + interface TableState_FeatureMap { + mrtFilterModesFeature: MRT_TableState_FilterModes + } + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtFilterModesFeature: MRT_TableOptions_FilterModes + } + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtFilterModesFeature: MRT_Table_FilterModes + } +} + +/** + * MRT-only filtering state that core doesn't own: the per-column filter-fn map + * (`columnFilterFns`), the chosen global filter fn (`globalFilterFn`), and the + * two subheader/search visibility flags. Their setters route through the + * matching `onXChange` options (defaulted to base-atom updaters). + * + * The initial `columnFilterFns` map is derived from each column's `filterVariant` + * in `useMRT_TableInstance` (it needs the column defs, which `getInitialState` + * can't see) and passed in via `initialState.columnFilterFns`, which overrides + * the empty default below. + */ +export const mrtFilterModesFeature: TableFeature = { + getInitialState: (initialState) => ({ + columnFilterFns: {}, + globalFilterFn: 'fuzzy', + showColumnFilters: false, + showGlobalFilter: false, + ...initialState, + }), + getDefaultTableOptions: (table) => ({ + onColumnFilterFnsChange: makeStateUpdater('columnFilterFns', table), + onGlobalFilterFnChange: makeStateUpdater('globalFilterFn', table), + onShowColumnFiltersChange: makeStateUpdater('showColumnFilters', table), + onShowGlobalFilterChange: makeStateUpdater('showGlobalFilter', table), + }), + constructTableAPIs: (table) => { + assignTableAPIs('mrtFilterModesFeature', table, { + table_setColumnFilterFns: { + fn: (updater: Updater) => + ( + table.options as MRT_TableOptions_FilterModes + ).onColumnFilterFnsChange?.((old) => functionalUpdate(updater, old)), + }, + table_setGlobalFilterFn: { + fn: (updater: Updater) => + ( + table.options as MRT_TableOptions_FilterModes + ).onGlobalFilterFnChange?.((old) => functionalUpdate(updater, old)), + }, + table_setShowColumnFilters: { + fn: (updater: Updater) => + ( + table.options as MRT_TableOptions_FilterModes + ).onShowColumnFiltersChange?.((old) => + functionalUpdate(updater, old), + ), + }, + table_setShowGlobalFilter: { + fn: (updater: Updater) => + ( + table.options as MRT_TableOptions_FilterModes + ).onShowGlobalFilterChange?.((old) => functionalUpdate(updater, old)), + }, + }) + }, +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtFullScreenFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtFullScreenFeature.ts new file mode 100644 index 0000000000..20e9d9be53 --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtFullScreenFeature.ts @@ -0,0 +1,70 @@ +import { + assignTableAPIs, + functionalUpdate, + makeStateUpdater, +} from '@tanstack/react-table' +import type { + OnChangeFn, + RowData, + TableFeature, + TableFeatures, + Updater, +} from '@tanstack/react-table' + +export interface MRT_TableState_FullScreen { + isFullScreen: boolean +} + +export interface MRT_TableOptions_FullScreen { + enableFullScreenToggle?: boolean + onIsFullScreenChange?: OnChangeFn +} + +export interface MRT_Table_FullScreen { + setIsFullScreen: (updater: Updater) => void +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtFullScreenFeature: TableFeature + } + interface TableState_FeatureMap { + mrtFullScreenFeature: MRT_TableState_FullScreen + } + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtFullScreenFeature: MRT_TableOptions_FullScreen + } + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtFullScreenFeature: MRT_Table_FullScreen + } +} + +/** + * Adds the `isFullScreen` state slice, `onIsFullScreenChange` option, and the + * `table.setIsFullScreen` API. + */ +export const mrtFullScreenFeature: TableFeature = { + getInitialState: (initialState) => ({ + isFullScreen: false, + ...initialState, + }), + getDefaultTableOptions: (table) => ({ + onIsFullScreenChange: makeStateUpdater('isFullScreen', table), + }), + constructTableAPIs: (table) => { + assignTableAPIs('mrtFullScreenFeature', table, { + table_setIsFullScreen: { + fn: (updater: Updater) => + (table.options as MRT_TableOptions_FullScreen).onIsFullScreenChange?.( + (old) => functionalUpdate(updater, old), + ), + }, + }) + }, +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtLoadingFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtLoadingFeature.ts new file mode 100644 index 0000000000..389066ec57 --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtLoadingFeature.ts @@ -0,0 +1,35 @@ +import type { TableFeature } from '@tanstack/react-table' + +export interface MRT_TableState_Loading { + isLoading: boolean + isSaving: boolean + showLoadingOverlay: boolean + showProgressBars: boolean + showSkeletons: boolean +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtLoadingFeature: TableFeature + } + interface TableState_FeatureMap { + mrtLoadingFeature: MRT_TableState_Loading + } +} + +/** + * The loading/saving flags are driven entirely by the controlled `state` + * option (no setters). Registering them as feature state gives each one a base + * atom, so a controlled `state: { isLoading: true }` is synced into + * `table.state.isLoading` and picked up by the loading overlay / skeletons. + */ +export const mrtLoadingFeature: TableFeature = { + getInitialState: (initialState) => ({ + isLoading: false, + isSaving: false, + showLoadingOverlay: false, + showProgressBars: false, + showSkeletons: false, + ...initialState, + }), +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtRefsFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtRefsFeature.ts new file mode 100644 index 0000000000..86d5e52f0d --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtRefsFeature.ts @@ -0,0 +1,62 @@ +import type { + RowData, + TableFeature, + TableFeatures, +} from '@tanstack/react-table' +import type { RefObject } from 'react' + +export interface MRT_TableRefs { + actionCellRef: RefObject + bottomToolbarRef: RefObject + editInputRefs: RefObject | null> + filterInputRefs: RefObject | null> + lastSelectedRowId: RefObject + searchInputRef: RefObject + tableContainerRef: RefObject + tableFooterRef: RefObject + tableHeadCellRefs: RefObject | null> + tableHeadRef: RefObject + tablePaperRef: RefObject + topToolbarRef: RefObject +} + +export interface MRT_Table_Refs { + refs: MRT_TableRefs +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtRefsFeature: TableFeature + } + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtRefsFeature: MRT_Table_Refs + } +} + +/** + * The v9 table instance is constructed once (via `useState(() => + * constructTable(...))`), so a bag of plain mutable `{ current: null }` refs + * assigned here persists for the table's lifetime — no `useRef` needed. This + * replaces the twelve `useRef`s MRT threaded through `useMRT_TableInstance`. + */ +export const mrtRefsFeature: TableFeature = { + constructTableAPIs: (table) => { + ;(table as unknown as MRT_Table_Refs).refs = { + actionCellRef: { current: null }, + bottomToolbarRef: { current: null }, + editInputRefs: { current: null }, + filterInputRefs: { current: null }, + lastSelectedRowId: { current: null }, + searchInputRef: { current: null }, + tableContainerRef: { current: null }, + tableFooterRef: { current: null }, + tableHeadCellRefs: { current: null }, + tableHeadRef: { current: null }, + tablePaperRef: { current: null }, + topToolbarRef: { current: null }, + } + }, +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtRowDraggingFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtRowDraggingFeature.ts new file mode 100644 index 0000000000..4c0ce4086c --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtRowDraggingFeature.ts @@ -0,0 +1,86 @@ +import { + assignTableAPIs, + functionalUpdate, + makeStateUpdater, +} from '@tanstack/react-table' +import type { + OnChangeFn, + Row, + RowData, + TableFeature, + TableFeatures, + Updater, +} from '@tanstack/react-table' + +export interface MRT_TableState_RowDragging { + draggingRow: Row | null + hoveredRow: Partial> | null +} + +export interface MRT_TableOptions_RowDragging { + onDraggingRowChange?: OnChangeFn | null> + onHoveredRowChange?: OnChangeFn> | null> +} + +export interface MRT_Table_RowDragging< + TFeatures extends TableFeatures, + TData extends RowData, +> { + setDraggingRow: (updater: Updater | null>) => void + setHoveredRow: ( + updater: Updater> | null>, + ) => void +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtRowDraggingFeature: TableFeature + } + interface TableState_FeatureMap { + mrtRowDraggingFeature: MRT_TableState_RowDragging + } + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtRowDraggingFeature: MRT_TableOptions_RowDragging + } + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtRowDraggingFeature: MRT_Table_RowDragging + } +} + +/** + * Tracks the row being dragged and the row currently hovered during a + * drag/reorder gesture, plus the `setDraggingRow` / `setHoveredRow` APIs. + */ +export const mrtRowDraggingFeature: TableFeature = { + getInitialState: (initialState) => ({ + draggingRow: null, + hoveredRow: null, + ...initialState, + }), + getDefaultTableOptions: (table) => ({ + onDraggingRowChange: makeStateUpdater('draggingRow', table), + onHoveredRowChange: makeStateUpdater('hoveredRow', table), + }), + constructTableAPIs: (table) => { + assignTableAPIs('mrtRowDraggingFeature', table, { + table_setDraggingRow: { + fn: (updater: Updater | null>) => + (table.options as MRT_TableOptions_RowDragging).onDraggingRowChange?.( + (old) => functionalUpdate(updater, old), + ), + }, + table_setHoveredRow: { + fn: (updater: Updater> | null>) => + (table.options as MRT_TableOptions_RowDragging).onHoveredRowChange?.( + (old) => functionalUpdate(updater, old), + ), + }, + }) + }, +} diff --git a/examples/react/material-react-table/src/material-react-table/features/mrtToolbarsFeature.ts b/examples/react/material-react-table/src/material-react-table/features/mrtToolbarsFeature.ts new file mode 100644 index 0000000000..37ca8067cf --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/features/mrtToolbarsFeature.ts @@ -0,0 +1,82 @@ +import { + assignTableAPIs, + functionalUpdate, + makeStateUpdater, +} from '@tanstack/react-table' +import type { + OnChangeFn, + RowData, + TableFeature, + TableFeatures, + Updater, +} from '@tanstack/react-table' + +export interface MRT_TableState_Toolbars { + showAlertBanner: boolean + showToolbarDropZone: boolean +} + +export interface MRT_TableOptions_Toolbars { + onShowAlertBannerChange?: OnChangeFn + onShowToolbarDropZoneChange?: OnChangeFn +} + +export interface MRT_Table_Toolbars { + setShowAlertBanner: (updater: Updater) => void + setShowToolbarDropZone: (updater: Updater) => void +} + +declare module '@tanstack/react-table' { + interface Plugins { + mrtToolbarsFeature: TableFeature + } + interface TableState_FeatureMap { + mrtToolbarsFeature: MRT_TableState_Toolbars + } + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtToolbarsFeature: MRT_TableOptions_Toolbars + } + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + mrtToolbarsFeature: MRT_Table_Toolbars + } +} + +/** + * Tracks the toolbar alert banner / drop-zone visibility flags plus their + * `setShowAlertBanner` / `setShowToolbarDropZone` APIs. + */ +export const mrtToolbarsFeature: TableFeature = { + getInitialState: (initialState) => ({ + showAlertBanner: false, + showToolbarDropZone: false, + ...initialState, + }), + getDefaultTableOptions: (table) => ({ + onShowAlertBannerChange: makeStateUpdater('showAlertBanner', table), + onShowToolbarDropZoneChange: makeStateUpdater('showToolbarDropZone', table), + }), + constructTableAPIs: (table) => { + assignTableAPIs('mrtToolbarsFeature', table, { + table_setShowAlertBanner: { + fn: (updater: Updater) => + ( + table.options as MRT_TableOptions_Toolbars + ).onShowAlertBannerChange?.((old) => functionalUpdate(updater, old)), + }, + table_setShowToolbarDropZone: { + fn: (updater: Updater) => + ( + table.options as MRT_TableOptions_Toolbars + ).onShowToolbarDropZoneChange?.((old) => + functionalUpdate(updater, old), + ), + }, + }) + }, +} diff --git a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowActionsColumnDef.tsx b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowActionsColumnDef.tsx index aec7fb1035..5bf4cdba8b 100644 --- a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowActionsColumnDef.tsx +++ b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowActionsColumnDef.tsx @@ -10,12 +10,11 @@ export const getMRT_RowActionsColumnDef = ( tableOptions: MRT_StatefulTableOptions, ): MRT_ColumnDef => { return { - Cell: ({ cell, row, staticRowIndex, table }) => ( + Cell: ({ cell, row, staticRowIndex }) => ( ), ...defaultDisplayColumnProps({ diff --git a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowDragColumnDef.tsx b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowDragColumnDef.tsx index 0fe6f4cb45..7e291f42de 100644 --- a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowDragColumnDef.tsx +++ b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowDragColumnDef.tsx @@ -11,11 +11,10 @@ export const getMRT_RowDragColumnDef = ( tableOptions: MRT_StatefulTableOptions, ): MRT_ColumnDef => { return { - Cell: ({ row, rowRef, table }) => ( + Cell: ({ row, rowRef }) => ( } - table={table} /> ), grow: false, diff --git a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowExpandColumnDef.tsx b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowExpandColumnDef.tsx index c8481a27f3..5425a733dd 100644 --- a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowExpandColumnDef.tsx +++ b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowExpandColumnDef.tsx @@ -32,7 +32,7 @@ export const getMRT_RowExpandColumnDef = ( return { Cell: ({ cell, column, row, staticRowIndex, table }) => { - const expandButtonProps = { row, staticRowIndex, table } + const expandButtonProps = { row, staticRowIndex } const subRowsLength = row.subRows?.length if (groupedColumnMode === 'remove' && row.groupingColumnId) { return ( @@ -46,7 +46,7 @@ export const getMRT_RowExpandColumnDef = ( {row.groupingValue as ReactNode} @@ -66,12 +66,12 @@ export const getMRT_RowExpandColumnDef = ( ? ({ table }) => { return ( <> - + {groupedColumnMode === 'remove' && grouping ?.map( (groupedColumnId) => - table.getColumn(groupedColumnId).columnDef.header, + table.getColumn(groupedColumnId)!.columnDef.header, ) ?.join(', ')} diff --git a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowPinningColumnDef.tsx b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowPinningColumnDef.tsx index ab9ca0b607..8345341191 100644 --- a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowPinningColumnDef.tsx +++ b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowPinningColumnDef.tsx @@ -10,9 +10,7 @@ export const getMRT_RowPinningColumnDef = ( tableOptions: MRT_StatefulTableOptions, ): MRT_ColumnDef => { return { - Cell: ({ row, table }) => ( - - ), + Cell: ({ row }) => , grow: false, ...defaultDisplayColumnProps({ header: 'pin', diff --git a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowSelectColumnDef.tsx b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowSelectColumnDef.tsx index 502c2a2c48..73f03be969 100644 --- a/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowSelectColumnDef.tsx +++ b/examples/react/material-react-table/src/material-react-table/hooks/display-columns/getMRT_RowSelectColumnDef.tsx @@ -12,16 +12,12 @@ export const getMRT_RowSelectColumnDef = ( const { enableMultiRowSelection, enableSelectAll } = tableOptions return { - Cell: ({ row, staticRowIndex, table }) => ( - + Cell: ({ row, staticRowIndex }) => ( + ), Header: enableSelectAll && enableMultiRowSelection - ? ({ table }) => + ? () => : undefined, grow: false, ...defaultDisplayColumnProps({ diff --git a/examples/react/material-react-table/src/material-react-table/hooks/mrtTableHook.ts b/examples/react/material-react-table/src/material-react-table/hooks/mrtTableHook.ts new file mode 100644 index 0000000000..6369950cd7 --- /dev/null +++ b/examples/react/material-react-table/src/material-react-table/hooks/mrtTableHook.ts @@ -0,0 +1,48 @@ +import { createTableHook } from '@tanstack/react-table' +import { mrtFeatures } from '../features/mrtFeatures' +import type { MRT_RowData, MRT_TableInstance } from '../types' + +/** + * The MRT table hook, built on TanStack's `createTableHook`. It binds the + * static `mrtFeatures` bundle once and hands back: + * + * - `useAppTable` — constructs the table and attaches the `AppTable` / `AppCell` + * / `AppHeader` context-provider wrappers plus any registered `tableComponents`. + * `useMRT_TableInstance` wraps this with MRT's option-time transforms. + * - `useTableContext` / `useCellContext` / `useHeaderContext` — let MRT + * components read the table / cell / header from React context instead of + * threading a `table` prop through every component. + * - `createAppColumnHelper` — a column helper pre-bound to `mrtFeatures`. + * + * Component registries are intentionally empty for now; components are migrated + * onto the context hooks incrementally and registered here as they land. + */ +export const { + useAppTable, + useTableContext, + useCellContext, + useHeaderContext, + createAppColumnHelper, +} = createTableHook({ + features: mrtFeatures, + tableComponents: {}, + cellComponents: {}, + headerComponents: {}, +}) + +/** + * Reads the current table from context (provided by ``), typed + * as `MRT_TableInstance` so every MRT component keeps its existing + * `table.state.X` / `table.options.X` / `table.setX` typing. + * + * This is the single seam MRT components use instead of a threaded `table` + * prop. `useTableContext` returns the core-typed extended instance; the cast + * re-applies MRT's wrapper types (the `MRT_*` return-type retypings that don't + * live on the feature maps yet). Phase 3 removes the wrapper and this cast + * becomes an identity. + */ +export function useMRTContext< + TData extends MRT_RowData = MRT_RowData, +>(): MRT_TableInstance { + return useTableContext() as unknown as MRT_TableInstance +} diff --git a/examples/react/material-react-table/src/material-react-table/hooks/useMRT_TableInstance.ts b/examples/react/material-react-table/src/material-react-table/hooks/useMRT_TableInstance.ts index 1ac96e51ce..54397a807c 100644 --- a/examples/react/material-react-table/src/material-react-table/hooks/useMRT_TableInstance.ts +++ b/examples/react/material-react-table/src/material-react-table/hooks/useMRT_TableInstance.ts @@ -1,6 +1,4 @@ import { useMemo, useRef } from 'react' -import { useCreateAtom, useSelector } from '@tanstack/react-store' -import { useTable } from '@tanstack/react-table' import { getAllLeafColumnDefs, getColumnId, @@ -17,7 +15,7 @@ import { showRowSelectionColumn, showRowSpacerColumn, } from '../utils/displayColumn.utils' -import { createRow } from '../utils/tanstack.helpers' +import { useAppTable } from './mrtTableHook' import { getMRT_RowActionsColumnDef } from './display-columns/getMRT_RowActionsColumnDef' import { getMRT_RowDragColumnDef } from './display-columns/getMRT_RowDragColumnDef' import { getMRT_RowExpandColumnDef } from './display-columns/getMRT_RowExpandColumnDef' @@ -27,65 +25,58 @@ import { getMRT_RowSelectColumnDef } from './display-columns/getMRT_RowSelectCol import { getMRT_RowSpacerColumnDef } from './display-columns/getMRT_RowSpacerColumnDef' import { useMRT_Effects } from './useMRT_Effects' import type { - MRT_Cell, - MRT_Column, MRT_ColumnDef, MRT_ColumnFilterFnsState, - MRT_ColumnOrderState, - MRT_ColumnResizingState, MRT_DefinedTableOptions, - MRT_DensityState, - MRT_FilterOption, - MRT_GroupingState, - MRT_PaginationState, - MRT_Row, MRT_RowData, MRT_StatefulTableOptions, MRT_TableInstance, MRT_TableState, - MRT_Updater, } from '../types' /** - * The MRT hook that wraps the TanStack `useTable` hook and adds MRT-specific - * state, refs, and helpers. State management is built on top of TanStack - * Store atoms (`useCreateAtom` from `@tanstack/react-store`): + * Wraps the TanStack v9 `useTable` hook, adding the MRT display-column + * injection, skeleton-row fabrication, and initial-state massaging that can't + * live inside a feature. * - * - **TanStack-aware slices** (`columnOrder`, `columnResizing`, `grouping`, - * `pagination`) are passed via the `atoms` option on `useTable`. Library - * writes (e.g. `table.setSorting(...)`, `table.firstPage()`) flow directly - * through these atoms, and they're automatically tracked in - * `table.state` by the v9 store. - * - **MRT-only slices** (`density`, `isFullScreen`, `actionCell`, - * `creatingRow`, `editingCell`, `editingRow`, `draggingColumn`, - * `draggingRow`, `hoveredColumn`, `hoveredRow`, `globalFilterFn`, - * `columnFilterFns`, `showAlertBanner`, `showColumnFilters`, - * `showGlobalFilter`, `showToolbarDropZone`) live in atoms outside the - * v9 store and are merged into `table.state` after construction so MRT - * components can read them via the same `state` surface. - * - * @param definedTableOptions - table options with proper defaults set - * @returns the MRT table instance + * All MRT-only state, setters, and refs now come from the custom features + * bundled in `mrtFeatures` (see `../features`). `useTable` constructs a base + * atom for every feature-contributed state key, so `table.state.density`, + * `table.setDensity`, `table.refs`, etc. are all provided natively — the + * hand-rolled atoms, setter aliases, and `table.state` patching that MRT + * previously maintained here are gone. */ export const useMRT_TableInstance = ( definedTableOptions: MRT_DefinedTableOptions, ): MRT_TableInstance => { - const lastSelectedRowId = useRef(null) - const actionCellRef = useRef(null) - const bottomToolbarRef = useRef(null) - const editInputRefs = useRef>({}) - const filterInputRefs = useRef>({}) - const searchInputRef = useRef(null) - const tableContainerRef = useRef(null) - const tableHeadCellRefs = useRef>({}) - const tablePaperRef = useRef(null) - const topToolbarRef = useRef(null) - const tableHeadRef = useRef(null) - const tableFooterRef = useRef(null) + const tableRef = useRef | null>(null) + const columnDefsRef = useRef>>([]) - // transform initial state with proper column order - const initialState: Partial> = useMemo(() => { + // --------------------------------------------------------------------------- + // Initial state — the column-order default and the per-column filter-fn map + // both need the column defs, which a feature's `getInitialState` can't see, so + // they're computed here and flow in via `initialState` (overriding the empty + // defaults the filter-modes feature seeds). + // --------------------------------------------------------------------------- + const initialState = useMemo>>(() => { const initState = definedTableOptions.initialState ?? {} + + const columnFilterFns: MRT_ColumnFilterFnsState = { + ...initState.columnFilterFns, + } + for (const col of getAllLeafColumnDefs( + definedTableOptions.columns as Array>, + )) { + const id = getColumnId(col) + if (columnFilterFns[id] == null) { + columnFilterFns[id] = + col.filterFn instanceof Function + ? (col.filterFn.name ?? 'custom') + : (col.filterFn ?? getDefaultColumnFilterFn(col)) + } + } + initState.columnFilterFns = columnFilterFns + initState.columnOrder = initState.columnOrder ?? getDefaultColumnOrderIds({ @@ -95,325 +86,127 @@ export const useMRT_TableInstance = ( ...definedTableOptions.state, }, } as MRT_StatefulTableOptions) - initState.globalFilterFn = definedTableOptions.globalFilterFn ?? 'fuzzy' + // Core's `globalFilterFn` option also admits a raw `FilterFn`; MRT's state + // slice only stores the string fn name, so narrow it here. + initState.globalFilterFn = + typeof definedTableOptions.globalFilterFn === 'string' + ? definedTableOptions.globalFilterFn + : 'fuzzy' return initState }, []) - definedTableOptions.initialState = initialState - - // --------------------------------------------------------------------------- - // TanStack-aware atoms (passed to `useTable` via `atoms` option). The library - // both reads and writes through these. - // --------------------------------------------------------------------------- - const columnOrderAtom = useCreateAtom( - initialState.columnOrder ?? [], - ) - const columnResizingAtom = useCreateAtom( - initialState.columnResizing ?? ({} as MRT_ColumnResizingState), - ) - const groupingAtom = useCreateAtom( - initialState.grouping ?? [], - ) - const paginationAtom = useCreateAtom( - initialState?.pagination ?? { pageIndex: 0, pageSize: 10 }, - ) - - // Subscribe so the consumer re-renders when these slices change. (The library - // also reads from these atoms internally; the subscriptions here are for the - // MRT component tree.) - const columnOrder = useSelector(columnOrderAtom) - const columnResizing = useSelector(columnResizingAtom) - const grouping = useSelector(groupingAtom) - const pagination = useSelector(paginationAtom) + // `initialState` is readonly on the resolved core options type; assign through + // a cast (the hook owns this options object). + ;( + definedTableOptions as { initialState?: Partial> } + ).initialState = initialState // --------------------------------------------------------------------------- - // MRT-only atoms — these slices aren't part of v9's `TableState` so they - // can't be passed via the `atoms` option. They're maintained as standalone - // atoms and merged into `table.state` after construction. + // State used only for the option-time transforms below (display-column + // injection, the resize/drag column freeze, skeleton data). It's sourced from + // the previous render's `table.state` (the full-state selector re-renders this + // hook on every change) and falls back to initial state on the first render. + // It is NOT passed to `useTable` as controlled `state` — only the client's own + // `state` option controls slices; everything else is owned by core/feature + // base atoms. // --------------------------------------------------------------------------- - const actionCellAtom = useCreateAtom | null>( - initialState.actionCell ?? null, - ) - const creatingRowAtom = useCreateAtom | null>( - initialState.creatingRow ?? null, - ) - // Build the initial columnFilterFns map from each column's `filterFn` (or - // the registered default if none set). Constructed as a plain Record so - // `useCreateAtom`'s overload resolves to `Atom` (writable) rather than - // the function-style `ReadonlyAtom` overload. - const initialColumnFilterFns: MRT_ColumnFilterFnsState = {} - for (const col of getAllLeafColumnDefs( - definedTableOptions.columns as Array>, - )) { - initialColumnFilterFns[getColumnId(col)] = - col.filterFn instanceof Function - ? (col.filterFn.name ?? 'custom') - : (col.filterFn ?? - initialState?.columnFilterFns?.[getColumnId(col)] ?? - getDefaultColumnFilterFn(col)) + const transformStateDefaults = { + columnOrder: [], + columnResizing: {}, + creatingRow: null, + draggingColumn: null, + draggingRow: null, + grouping: [], + isLoading: false, + pagination: { pageIndex: 0, pageSize: 10 }, + showSkeletons: false, } - const columnFilterFnsAtom = useCreateAtom( - initialColumnFilterFns, - ) - const densityAtom = useCreateAtom( - initialState?.density ?? 'comfortable', - ) - const draggingColumnAtom = useCreateAtom | null>( - initialState.draggingColumn ?? null, - ) - const draggingRowAtom = useCreateAtom | null>( - initialState.draggingRow ?? null, - ) - const editingCellAtom = useCreateAtom | null>( - initialState.editingCell ?? null, - ) - const editingRowAtom = useCreateAtom | null>( - initialState.editingRow ?? null, - ) - const globalFilterFnAtom = useCreateAtom( - initialState.globalFilterFn ?? 'fuzzy', - ) - const hoveredColumnAtom = useCreateAtom> | null>( - initialState.hoveredColumn ?? null, - ) - const hoveredRowAtom = useCreateAtom> | null>( - initialState.hoveredRow ?? null, - ) - const isFullScreenAtom = useCreateAtom( - initialState?.isFullScreen ?? false, - ) - const showAlertBannerAtom = useCreateAtom( - initialState?.showAlertBanner ?? false, - ) - const showColumnFiltersAtom = useCreateAtom( - initialState?.showColumnFilters ?? false, - ) - const showGlobalFilterAtom = useCreateAtom( - initialState?.showGlobalFilter ?? false, - ) - const showToolbarDropZoneAtom = useCreateAtom( - initialState?.showToolbarDropZone ?? false, - ) - - const actionCell = useSelector(actionCellAtom) - const creatingRow = useSelector(creatingRowAtom) - const columnFilterFns = useSelector(columnFilterFnsAtom) - const density = useSelector(densityAtom) - const draggingColumn = useSelector(draggingColumnAtom) - const draggingRow = useSelector(draggingRowAtom) - const editingCell = useSelector(editingCellAtom) - const editingRow = useSelector(editingRowAtom) - const globalFilterFn = useSelector(globalFilterFnAtom) - const hoveredColumn = useSelector(hoveredColumnAtom) - const hoveredRow = useSelector(hoveredRowAtom) - const isFullScreen = useSelector(isFullScreenAtom) - const showAlertBanner = useSelector(showAlertBannerAtom) - const showColumnFilters = useSelector(showColumnFiltersAtom) - const showGlobalFilter = useSelector(showGlobalFilterAtom) - const showToolbarDropZone = useSelector(showToolbarDropZoneAtom) - - // Mirror values into options.state so utilities that read - // `tableOptions.state.X` (e.g. column prep, display-column factories) keep - // working. The user can still override individual slices by setting - // `definedTableOptions.state` from outside. - definedTableOptions.state = { - actionCell, - columnFilterFns, - columnOrder, - columnResizing, - creatingRow, - density, - draggingColumn, - draggingRow, - editingCell, - editingRow, - globalFilterFn, - grouping, - hoveredColumn, - hoveredRow, - isFullScreen, - pagination, - showAlertBanner, - showColumnFilters, - showGlobalFilter, - showToolbarDropZone, + const stateForTransforms = { + ...transformStateDefaults, + ...initialState, ...definedTableOptions.state, - } - - // The table options now include all state needed to help determine column visibility and order logic - const statefulTableOptions = - definedTableOptions as MRT_StatefulTableOptions - - // don't recompute columnDefs while resizing column or dragging column/row - const columnDefsRef = useRef>>([]) - statefulTableOptions.columns = - statefulTableOptions.state.columnResizing.isResizingColumn || - statefulTableOptions.state.draggingColumn || - statefulTableOptions.state.draggingRow + ...(tableRef.current?.state ?? {}), + } as MRT_TableState + + const optionsForTransforms = { + ...definedTableOptions, + state: stateForTransforms, + } as MRT_StatefulTableOptions + + // Don't recompute columnDefs while resizing or dragging a column/row. + const preparedColumns = + stateForTransforms.columnResizing.isResizingColumn || + stateForTransforms.draggingColumn || + stateForTransforms.draggingRow ? columnDefsRef.current : prepareColumns({ columnDefs: [ ...([ - showRowPinningColumn(statefulTableOptions) && - getMRT_RowPinningColumnDef(statefulTableOptions), - showRowDragColumn(statefulTableOptions) && - getMRT_RowDragColumnDef(statefulTableOptions), - showRowActionsColumn(statefulTableOptions) && - getMRT_RowActionsColumnDef(statefulTableOptions), - showRowExpandColumn(statefulTableOptions) && - getMRT_RowExpandColumnDef(statefulTableOptions), - showRowSelectionColumn(statefulTableOptions) && - getMRT_RowSelectColumnDef(statefulTableOptions), - showRowNumbersColumn(statefulTableOptions) && - getMRT_RowNumbersColumnDef(statefulTableOptions), + showRowPinningColumn(optionsForTransforms) && + getMRT_RowPinningColumnDef(optionsForTransforms), + showRowDragColumn(optionsForTransforms) && + getMRT_RowDragColumnDef(optionsForTransforms), + showRowActionsColumn(optionsForTransforms) && + getMRT_RowActionsColumnDef(optionsForTransforms), + showRowExpandColumn(optionsForTransforms) && + getMRT_RowExpandColumnDef(optionsForTransforms), + showRowSelectionColumn(optionsForTransforms) && + getMRT_RowSelectColumnDef(optionsForTransforms), + showRowNumbersColumn(optionsForTransforms) && + getMRT_RowNumbersColumnDef(optionsForTransforms), ].filter(Boolean) as Array>), - ...statefulTableOptions.columns, + ...optionsForTransforms.columns, ...([ - showRowSpacerColumn(statefulTableOptions) && - getMRT_RowSpacerColumnDef(statefulTableOptions), + showRowSpacerColumn(optionsForTransforms) && + getMRT_RowSpacerColumnDef(optionsForTransforms), ].filter(Boolean) as Array>), ], - tableOptions: statefulTableOptions, + tableOptions: optionsForTransforms, }) - columnDefsRef.current = statefulTableOptions.columns + columnDefsRef.current = preparedColumns - // if loading, generate blank rows to show skeleton loaders - statefulTableOptions.data = useMemo( + // If loading with empty data, generate blank rows to show skeleton loaders. + const data = useMemo( () => - (statefulTableOptions.state.isLoading || - statefulTableOptions.state.showSkeletons) && - !statefulTableOptions.data.length + (stateForTransforms.isLoading || stateForTransforms.showSkeletons) && + !definedTableOptions.data.length ? [ - ...Array( - Math.min(statefulTableOptions.state.pagination.pageSize, 20), - ).fill(null), + ...Array(Math.min(stateForTransforms.pagination.pageSize, 20)).fill( + null, + ), ].map(() => Object.assign( {}, - ...getAllLeafColumnDefs(statefulTableOptions.columns).map( - (col) => ({ - [getColumnId(col)]: null, - }), - ), + ...getAllLeafColumnDefs(preparedColumns).map((col) => ({ + [getColumnId(col)]: null, + })), ), ) - : statefulTableOptions.data, + : definedTableOptions.data, [ - statefulTableOptions.data, - statefulTableOptions.state.isLoading, - statefulTableOptions.state.showSkeletons, + definedTableOptions.data, + stateForTransforms.isLoading, + stateForTransforms.showSkeletons, ], ) - const table = useTable( + // `useAppTable` (from `createTableHook`) owns the `mrtFeatures` bundle and + // attaches the App* context wrappers. MRT's option-time transforms above are + // applied before handing the options over, and the previous render's + // `table.state` (via the full-state selector) feeds the next render's + // transforms through `tableRef`. + const table = useAppTable( { - ...(statefulTableOptions as any), - globalFilterFn: (globalFilterFn ?? 'fuzzy') as any, - // Hand TanStack-aware slices over to our external atoms — library writes - // (e.g. `table.setPageIndex(...)`, drag-resize) flow straight into them. - atoms: { - columnOrder: columnOrderAtom, - columnResizing: columnResizingAtom, - grouping: groupingAtom, - pagination: paginationAtom, - }, + ...(definedTableOptions as any), + columns: preparedColumns, + data, + initialState, + globalFilterFn: (stateForTransforms.globalFilterFn ?? 'fuzzy') as any, }, - (state) => state, // default selector + (state) => state, // full-state selector; MRT reads table.state.X synchronously ) as unknown as MRT_TableInstance - // v9 spells the resize setter `setcolumnResizing` (lowercase 'c') because - // it's auto-generated from the state-key name. Expose a camelCase alias so - // MRT consumers don't need to know about that quirk; route writes through - // our owned atom directly. - table.setColumnResizing = columnResizingAtom.set as any - - // The v9 store doesn't track MRT-only slices, so `table.state` is missing - // them after `useTable` returns. Patch them in here so all MRT components - // can read `table.state.density`, `table.state.isFullScreen`, etc. - table.state = { - ...table.state, - actionCell, - columnFilterFns, - creatingRow, - density, - draggingColumn, - draggingRow, - editingCell, - editingRow, - globalFilterFn, - hoveredColumn, - hoveredRow, - isFullScreen, - showAlertBanner, - showColumnFilters, - showGlobalFilter, - showToolbarDropZone, - } - - // v8-style `getState()` alias for any consumer that still calls it. - table.getState = () => table.state - - table.refs = { - actionCellRef, - bottomToolbarRef, - editInputRefs, - filterInputRefs, - lastSelectedRowId, - searchInputRef, - tableContainerRef, - tableFooterRef, - tableHeadCellRefs, - tableHeadRef, - tablePaperRef, - topToolbarRef, - } - - // Setters write through atom.set (or call the user-supplied on*Change - // handler if one was provided so external state ownership still works). - // The `as any` casts bridge atom.set's overloaded signature with React's - // `Dispatch>` shape — the runtime contract is identical - // (both accept a value or an updater function). - table.setActionCell = (statefulTableOptions.onActionCellChange ?? - actionCellAtom.set) as any - table.setCreatingRow = (row: MRT_Updater | null | true>) => { - let _row = row - if (row === true) { - _row = createRow(table) - } - statefulTableOptions?.onCreatingRowChange?.( - _row as MRT_Row | null, - ) ?? creatingRowAtom.set(_row as MRT_Row | null) - } - table.setColumnFilterFns = (statefulTableOptions.onColumnFilterFnsChange ?? - columnFilterFnsAtom.set) as any - table.setDensity = (statefulTableOptions.onDensityChange ?? - densityAtom.set) as any - table.setDraggingColumn = (statefulTableOptions.onDraggingColumnChange ?? - draggingColumnAtom.set) as any - table.setDraggingRow = (statefulTableOptions.onDraggingRowChange ?? - draggingRowAtom.set) as any - table.setEditingCell = (statefulTableOptions.onEditingCellChange ?? - editingCellAtom.set) as any - table.setEditingRow = (statefulTableOptions.onEditingRowChange ?? - editingRowAtom.set) as any - table.setGlobalFilterFn = (statefulTableOptions.onGlobalFilterFnChange ?? - globalFilterFnAtom.set) as any - table.setHoveredColumn = (statefulTableOptions.onHoveredColumnChange ?? - hoveredColumnAtom.set) as any - table.setHoveredRow = (statefulTableOptions.onHoveredRowChange ?? - hoveredRowAtom.set) as any - table.setIsFullScreen = (statefulTableOptions.onIsFullScreenChange ?? - isFullScreenAtom.set) as any - table.setShowAlertBanner = (statefulTableOptions.onShowAlertBannerChange ?? - showAlertBannerAtom.set) as any - table.setShowColumnFilters = - (statefulTableOptions.onShowColumnFiltersChange ?? - showColumnFiltersAtom.set) as any - table.setShowGlobalFilter = (statefulTableOptions.onShowGlobalFilterChange ?? - showGlobalFilterAtom.set) as any - table.setShowToolbarDropZone = - (statefulTableOptions.onShowToolbarDropZoneChange ?? - showToolbarDropZoneAtom.set) as any + tableRef.current = table useMRT_Effects(table) diff --git a/examples/react/material-react-table/src/material-react-table/hooks/useMRT_TableOptions.ts b/examples/react/material-react-table/src/material-react-table/hooks/useMRT_TableOptions.ts index 005365fb9a..cb745b0d59 100644 --- a/examples/react/material-react-table/src/material-react-table/hooks/useMRT_TableOptions.ts +++ b/examples/react/material-react-table/src/material-react-table/hooks/useMRT_TableOptions.ts @@ -1,19 +1,5 @@ import { useId, useMemo } from 'react' -import { - createExpandedRowModel, - createFacetedMinMaxValues, - createFacetedRowModel, - createFacetedUniqueValues, - createFilteredRowModel, - createGroupedRowModel, - createPaginatedRowModel, - createSortedRowModel, - stockFeatures, -} from '@tanstack/react-table' import { useTheme } from '@mui/material/styles' -import { MRT_AggregationFns } from '../fns/aggregationFns' -import { MRT_FilterFns } from '../fns/filterFns' -import { MRT_SortFns } from '../fns/sortingFns' import { MRT_Default_Icons } from '../icons' import { MRT_Localization_EN } from '../locales/en' import { getMRTTheme } from '../utils/style.utils' @@ -48,7 +34,6 @@ export const MRT_DefaultDisplayColumn = { export const useMRT_TableOptions: ( tableOptions: MRT_TableOptions, ) => MRT_DefinedTableOptions = ({ - aggregationFns, autoResetExpanded = false, columnFilterDisplayMode = 'subheader', columnResizeDirection, @@ -90,7 +75,6 @@ export const useMRT_TableOptions: ( enableTableHead = true, enableToolbarInternalActions = true, enableTopToolbar = true, - filterFns, icons, id = useId(), layoutMode, @@ -111,7 +95,6 @@ export const useMRT_TableOptions: ( rowNumberDisplayMode = 'static', rowPinningDisplayMode = 'sticky', selectAllMode = 'page', - sortFns, ...rest }: MRT_TableOptions) => { const theme = useTheme() @@ -125,15 +108,6 @@ export const useMRT_TableOptions: ( [localization], ) mrtTheme = useMemo(() => getMRTTheme(mrtTheme, theme), [mrtTheme, theme]) - aggregationFns = useMemo( - () => ({ ...MRT_AggregationFns, ...aggregationFns }), - [], - ) - filterFns = useMemo( - () => ({ ...MRT_FilterFns, ...filterFns }) as typeof filterFns, - [], - ) - sortFns = useMemo(() => ({ ...MRT_SortFns, ...sortFns }), []) defaultColumn = useMemo( () => ({ ...MRT_DefaultColumn, ...defaultColumn }), [defaultColumn], @@ -180,7 +154,6 @@ export const useMRT_TableOptions: ( } return { - aggregationFns, autoResetExpanded, columnFilterDisplayMode, columnResizeDirection, @@ -222,36 +195,11 @@ export const useMRT_TableOptions: ( enableTableHead, enableToolbarInternalActions, enableTopToolbar, - filterFns, - features: { - ...stockFeatures, - ...((enableColumnFilters || enableGlobalFilter || enableFilters) && - !manualFiltering - ? { filteredRowModel: createFilteredRowModel(), filterFns } - : {}), - ...(enableSorting && !manualSorting - ? { sortedRowModel: createSortedRowModel(), sortFns } - : {}), - ...(enablePagination && !manualPagination - ? { paginatedRowModel: createPaginatedRowModel() } - : {}), - ...(enableExpanding || enableGrouping - ? { expandedRowModel: createExpandedRowModel() } - : {}), - ...(enableGrouping && !manualGrouping - ? { - groupedRowModel: createGroupedRowModel(), - aggregationFns, - } - : {}), - ...(enableFacetedValues - ? { - facetedRowModel: createFacetedRowModel(), - facetedMinMaxValues: createFacetedMinMaxValues(), - facetedUniqueValues: createFacetedUniqueValues(), - } - : {}), - }, + // `features` is no longer assembled here — the static `mrtFeatures` bundle + // owns every feature + row model, gated at runtime by the `manual*` flags + // computed below. `useMRT_TableInstance` merges any client-supplied custom + // `filterFns` / `sortFns` / `aggregationFns` (carried through `...rest`) over + // the built-ins registered on `mrtFeatures`. getSubRows: (row: TData) => (row as any)?.subRows, icons, id, @@ -273,7 +221,6 @@ export const useMRT_TableOptions: ( rowNumberDisplayMode, rowPinningDisplayMode, selectAllMode, - sortFns, ...rest, } as MRT_DefinedTableOptions } diff --git a/examples/react/material-react-table/src/material-react-table/types.ts b/examples/react/material-react-table/src/material-react-table/types.ts index eef0236c4e..2ec73eb84e 100644 --- a/examples/react/material-react-table/src/material-react-table/types.ts +++ b/examples/react/material-react-table/src/material-react-table/types.ts @@ -1,4 +1,3 @@ -import type { Dispatch, ReactNode, RefObject, SetStateAction } from 'react' import type { AccessorFn, AggregationFn, @@ -18,53 +17,24 @@ import type { GroupingState, Header, HeaderGroup, - OnChangeFn, PaginationState, + ReactTable, Row, + RowModel, RowSelectionState, SortFn, SortingState, StockFeatures, - Table, TableOptions, TableState, Updater, } from '@tanstack/react-table' +import type { MRT_Features } from './features/mrtFeatures' import type { VirtualItem, Virtualizer, VirtualizerOptions, } from '@tanstack/react-virtual' -import type { AlertProps } from '@mui/material/Alert' -import type { AutocompleteProps } from '@mui/material/Autocomplete' -import type { BoxProps } from '@mui/material/Box' -import type { ButtonProps } from '@mui/material/Button' -import type { CheckboxProps } from '@mui/material/Checkbox' -import type { ChipProps } from '@mui/material/Chip' -import type { CircularProgressProps } from '@mui/material/CircularProgress' -import type { DialogProps } from '@mui/material/Dialog' -import type { IconButtonProps } from '@mui/material/IconButton' -import type { LinearProgressProps } from '@mui/material/LinearProgress' -import type { PaginationProps } from '@mui/material/Pagination' -import type { PaperProps } from '@mui/material/Paper' -import type { RadioProps } from '@mui/material/Radio' -import type { SelectProps } from '@mui/material/Select' -import type { SkeletonProps } from '@mui/material/Skeleton' -import type { SliderProps } from '@mui/material/Slider' -import type { TableProps } from '@mui/material/Table' -import type { TableBodyProps } from '@mui/material/TableBody' -import type { TableCellProps } from '@mui/material/TableCell' -import type { TableContainerProps } from '@mui/material/TableContainer' -import type { TableFooterProps } from '@mui/material/TableFooter' -import type { TableHeadProps } from '@mui/material/TableHead' -import type { TableRowProps } from '@mui/material/TableRow' -import type { TextFieldProps } from '@mui/material/TextField' -import type { Theme } from '@mui/material/styles' -import type { - DatePickerProps, - DateTimePickerProps, - TimePickerProps, -} from '@mui/x-date-pickers' import type { MRT_AggregationFns } from './fns/aggregationFns' import type { MRT_FilterFns } from './fns/filterFns' import type { MRT_SortFns } from './fns/sortingFns' @@ -291,464 +261,68 @@ export interface MRT_Theme { selectedRowBackgroundColor: string } -export interface MRT_RowModel { - flatRows: Array> - rows: Array> - rowsById: { [key: string]: MRT_Row } -} +export type MRT_RowModel = RowModel< + MRT_Features, + TData +> + +// --------------------------------------------------------------------------- +// Core-backed instance / options / state / column / row / cell / header types. +// +// These were hand-maintained `Omit`-and-retype wrappers over the v9 core types. +// Now that every MRT state slice, API, option, and column-def field is declared +// on the v9 feature maps (see `./features/*`), the core types instantiated with +// `MRT_Features` already carry the full MRT surface, so these collapse to thin +// definitions. The `MRT_*` names are kept as the stable seam components import. +// --------------------------------------------------------------------------- export type MRT_TableInstance = Omit< - Table, - | 'getAllColumns' - | 'getAllFlatColumns' - | 'getAllLeafColumns' - | 'getBottomRows' - | 'getCenterLeafColumns' - | 'getCenterRows' - | 'getColumn' - | 'getExpandedRowModel' - | 'getFlatHeaders' - | 'getFooterGroups' - | 'getHeaderGroups' - | 'getLeafHeaders' - | 'getLeftLeafColumns' - | 'getPaginationRowModel' - | 'getPreFilteredRowModel' - | 'getPrePaginatedRowModel' - | 'getRightLeafColumns' - | 'getRowModel' - | 'getSelectedRowModel' - | 'getState' - | 'getTopRows' - | 'options' + ReactTable, + 'options' | 'state' > & { - getAllColumns: () => Array> - getAllFlatColumns: () => Array> - getAllLeafColumns: () => Array> - getBottomRows: () => Array> - getCenterLeafColumns: () => Array> - getCenterRows: () => Array> - getColumn: (columnId: string) => MRT_Column - getExpandedRowModel: () => MRT_RowModel - getFlatHeaders: () => Array> - getFooterGroups: () => Array> - getHeaderGroups: () => Array> - getLeafHeaders: () => Array> - getLeftLeafColumns: () => Array> - getPaginationRowModel: () => MRT_RowModel - getPreFilteredRowModel: () => MRT_RowModel - getPrePaginatedRowModel: () => MRT_RowModel - getRightLeafColumns: () => Array> - getRowModel: () => MRT_RowModel - getSelectedRowModel: () => MRT_RowModel - getState: () => MRT_TableState - getTopRows: () => Array> + // `options` is narrowed to the resolved/stateful shape (icons, localization, + // mrtTheme guaranteed present; `state` populated) that MRT's hook produces. options: MRT_StatefulTableOptions - /** - * The current full table state. Populated by useTable's `state => state` selector. - * Use this in place of v8's `table.getState()`. - */ state: MRT_TableState - /** - * v9 calls this `setcolumnResizing` (lowercase 'c') on the underlying table — - * we expose a normal camelCase alias here. - */ - setColumnResizing: ( - updater: Updater['columnResizing']>, - ) => void - refs: { - actionCellRef: RefObject - bottomToolbarRef: RefObject - editInputRefs: RefObject | null> - filterInputRefs: RefObject | null> - lastSelectedRowId: RefObject - searchInputRef: RefObject - tableContainerRef: RefObject - tableFooterRef: RefObject - tableHeadCellRefs: RefObject | null> - tableHeadRef: RefObject - tablePaperRef: RefObject - topToolbarRef: RefObject - } - setActionCell: Dispatch | null>> - setColumnFilterFns: Dispatch> - setCreatingRow: Dispatch | null | true>> - setDensity: Dispatch> - setDraggingColumn: Dispatch | null>> - setDraggingRow: Dispatch | null>> - setEditingCell: Dispatch | null>> - setEditingRow: Dispatch | null>> - setGlobalFilterFn: Dispatch> - setHoveredColumn: Dispatch> | null>> - setHoveredRow: Dispatch> | null>> - setIsFullScreen: Dispatch> - setShowAlertBanner: Dispatch> - setShowColumnFilters: Dispatch> - setShowGlobalFilter: Dispatch> - setShowToolbarDropZone: Dispatch> } -export type MRT_DefinedTableOptions = Omit< - MRT_TableOptions, - 'icons' | 'localization' | 'mrtTheme' -> & { - icons: MRT_Icons - localization: MRT_Localization - mrtTheme: Required -} +export type MRT_DefinedTableOptions = + MRT_TableOptions & { + // `features` is optional on the user-facing `MRT_TableOptions` (the hook + // injects `mrtFeatures`), but required once resolved so the stateful options + // stay assignable to core `TableOptions`. + features: MRT_Features + icons: MRT_Icons + localization: MRT_Localization + mrtTheme: Required + } export type MRT_StatefulTableOptions = MRT_DefinedTableOptions & { - state: Pick< - MRT_TableState, - | 'columnFilterFns' - | 'columnOrder' - | 'columnResizing' - | 'creatingRow' - | 'density' - | 'draggingColumn' - | 'draggingRow' - | 'editingCell' - | 'editingRow' - | 'globalFilterFn' - | 'grouping' - | 'hoveredColumn' - | 'hoveredRow' - | 'isFullScreen' - | 'pagination' - | 'showAlertBanner' - | 'showColumnFilters' - | 'showGlobalFilter' - | 'showToolbarDropZone' - > + state: MRT_TableState } -export interface MRT_TableState< - TData extends MRT_RowData, -> extends TableState { - actionCell?: MRT_Cell | null - columnFilterFns: MRT_ColumnFilterFnsState - creatingRow: MRT_Row | null - density: MRT_DensityState - draggingColumn: MRT_Column | null - draggingRow: MRT_Row | null - editingCell: MRT_Cell | null - editingRow: MRT_Row | null - globalFilterFn: MRT_FilterOption - hoveredColumn: Partial> | null - hoveredRow: Partial> | null - isFullScreen: boolean - isLoading: boolean - isSaving: boolean - showAlertBanner: boolean - showColumnFilters: boolean - showGlobalFilter: boolean - showLoadingOverlay: boolean - showProgressBars: boolean - showSkeletons: boolean - showToolbarDropZone: boolean -} +// State slices are non-generic on the feature map; the `TData` param is kept for +// call-site arity (`MRT_TableState`) via a no-op conditional. +export type MRT_TableState = TData extends any + ? TableState + : never -export interface MRT_ColumnDef< +export type MRT_ColumnDef< TData extends MRT_RowData, TValue = unknown, -> extends Omit< - ColumnDef, - | 'accessorKey' - | 'aggregatedCell' - | 'aggregationFn' - | 'cell' - | 'columns' - | 'filterFn' - | 'footer' - | 'header' - | 'id' - | 'sortFn' -> { - /** - * Either an `accessorKey` or a combination of an `accessorFn` and `id` are required for a data column definition. - * Specify a function here to point to the correct property in the data object. - * - * @example accessorFn: (row) => row.username - */ - accessorFn?: (originalRow: TData) => TValue - /** - * Either an `accessorKey` or a combination of an `accessorFn` and `id` are required for a data column definition. - * Specify which key in the row this column should use to access the correct data. - * Also supports Deep Key Dot Notation. - * - * @example accessorKey: 'username' //simple - * @example accessorKey: 'name.firstName' //deep key dot notation - */ - accessorKey?: DeepKeys | (string & {}) - AggregatedCell?: (props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - staticColumnIndex?: number - staticRowIndex?: number - }) => ReactNode - aggregationFn?: Array> | MRT_AggregationFn - Cell?: (props: { - cell: MRT_Cell - column: MRT_Column - renderedCellValue: ReactNode - row: MRT_Row - rowRef?: RefObject - staticColumnIndex?: number - staticRowIndex?: number - table: MRT_TableInstance - }) => ReactNode - /** - * Specify what type of column this is. Either `data`, `display`, or `group`. Defaults to `data`. - * Leave this blank if you are just creating a normal data column. - * - * @default 'data' - * - * @example columnDefType: 'display' - */ - columnDefType?: 'data' | 'display' | 'group' - columnFilterModeOptions?: Array< - LiteralUnion - > | null - columns?: Array> - Edit?: (props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => ReactNode - editSelectOptions?: - | ((props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => Array) - | Array - editVariant?: 'select' | 'text' - enableClickToCopy?: - | 'context-menu' - | ((cell: MRT_Cell) => 'context-menu' | boolean) - | boolean - enableColumnActions?: boolean - enableColumnDragging?: boolean - enableColumnFilterModes?: boolean - enableColumnOrdering?: boolean - enableEditing?: ((row: MRT_Row) => boolean) | boolean - enableFilterMatchHighlighting?: boolean - Filter?: (props: { - column: MRT_Column - header: MRT_Header - rangeFilterIndex?: number - table: MRT_TableInstance - }) => ReactNode - filterFn?: MRT_FilterFn - filterSelectOptions?: Array - filterVariant?: - | 'autocomplete' - | 'checkbox' - | 'date' - | 'date-range' - | 'datetime' - | 'datetime-range' - | 'multi-select' - | 'range' - | 'range-slider' - | 'select' - | 'text' - | 'time' - | 'time-range' - /** - * footer must be a string. If you want custom JSX to render the footer, you can also specify a `Footer` option. (Capital F) - */ - footer?: string - Footer?: - | ((props: { - column: MRT_Column - footer: MRT_Header - table: MRT_TableInstance - }) => ReactNode) - | ReactNode - GroupedCell?: (props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - staticColumnIndex?: number - staticRowIndex?: number - }) => ReactNode - /** - * If `layoutMode` is `'grid'` or `'grid-no-grow'`, you can specify the flex grow value for individual columns to still grow and take up remaining space, or set to `false`/0 to not grow. - */ - grow?: boolean | number - /** - * header must be a string. If you want custom JSX to render the header, you can also specify a `Header` option. (Capital H) - */ - header: string - Header?: - | ((props: { - column: MRT_Column - header: MRT_Header - table: MRT_TableInstance - }) => ReactNode) - | ReactNode - /** - * Either an `accessorKey` or a combination of an `accessorFn` and `id` are required for a data column definition. - * - * If you have also specified an `accessorFn`, MRT still needs to have a valid `id` to be able to identify the column uniquely. - * - * `id` defaults to the `accessorKey` or `header` if not specified. - * - * @default gets set to the same value as `accessorKey` by default - */ - id?: LiteralUnion - muiColumnActionsButtonProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => IconButtonProps) - | IconButtonProps - muiColumnDragHandleProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => IconButtonProps) - | IconButtonProps - muiCopyButtonProps?: - | ((props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => ButtonProps) - | ButtonProps - muiEditTextFieldProps?: - | ((props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => TextFieldProps) - | TextFieldProps - muiFilterAutocompleteProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => AutocompleteProps) - | AutocompleteProps - muiFilterCheckboxProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => CheckboxProps) - | CheckboxProps - muiFilterDatePickerProps?: - | ((props: { - column: MRT_Column - rangeFilterIndex?: number - table: MRT_TableInstance - }) => DatePickerProps) - | DatePickerProps - muiFilterDateTimePickerProps?: - | ((props: { - column: MRT_Column - rangeFilterIndex?: number - table: MRT_TableInstance - }) => DateTimePickerProps) - | DateTimePickerProps - muiFilterSliderProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => SliderProps) - | SliderProps - muiFilterTextFieldProps?: - | ((props: { - column: MRT_Column - rangeFilterIndex?: number - table: MRT_TableInstance - }) => TextFieldProps) - | TextFieldProps - muiFilterTimePickerProps?: - | ((props: { - column: MRT_Column - rangeFilterIndex?: number - table: MRT_TableInstance - }) => TimePickerProps) - | TimePickerProps - muiTableBodyCellProps?: - | ((props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => TableCellProps) - | TableCellProps - muiTableFooterCellProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => TableCellProps) - | TableCellProps - muiTableHeadCellProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => TableCellProps) - | TableCellProps - PlaceholderCell?: (props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => ReactNode - renderCellActionMenuItems?: (props: { - cell: MRT_Cell - closeMenu: () => void - column: MRT_Column - internalMenuItems: Array - row: MRT_Row - staticColumnIndex?: number - staticRowIndex?: number - table: MRT_TableInstance - }) => Array - renderColumnActionsMenuItems?: (props: { - closeMenu: () => void - column: MRT_Column - internalColumnMenuItems: Array - table: MRT_TableInstance - }) => Array - renderColumnFilterModeMenuItems?: (props: { - column: MRT_Column - internalFilterOptions: Array - onSelectFilterMode: (filterMode: MRT_FilterOption) => void - table: MRT_TableInstance - }) => Array - sortFn?: MRT_SortFn - visibleInShowHideMenu?: boolean -} +> = ColumnDef export type MRT_DisplayColumnDef< TData extends MRT_RowData, TValue = unknown, -> = Omit, 'accessorFn' | 'accessorKey'> +> = MRT_ColumnDef -/** - * A data column with an `id` and an optional `header`. Used as the input shape - * for `columnHelper.accessor(key, ...)` — the `id` defaults to the accessor key - * so it's not required at the call site. Mirrors v9's `IdentifiedColumnDef`. - */ export type MRT_IdentifiedColumnDef< TData extends MRT_RowData, TValue = unknown, > = MRT_DisplayColumnDef -/** - * The result type of `columnHelper.accessor(fn, ...)`. Has a required - * `accessorFn`. Mirrors v9's `AccessorFnColumnDef`. - */ export type MRT_AccessorFnColumnDef< TData extends MRT_RowData, TValue = unknown, @@ -756,10 +330,6 @@ export type MRT_AccessorFnColumnDef< accessorFn: (originalRow: TData) => TValue } -/** - * The result type of `columnHelper.accessor(key, ...)`. Has a required - * `accessorKey`. Mirrors v9's `AccessorKeyColumnDef`. - */ export type MRT_AccessorKeyColumnDef< TData extends MRT_RowData, TValue = unknown, @@ -767,10 +337,6 @@ export type MRT_AccessorKeyColumnDef< accessorKey: DeepKeys | (string & {}) } -/** - * Union of `MRT_AccessorFnColumnDef` and `MRT_AccessorKeyColumnDef`. Mirrors - * v9's `AccessorColumnDef`. - */ export type MRT_AccessorColumnDef< TData extends MRT_RowData, TValue = unknown, @@ -788,63 +354,36 @@ export type MRT_GroupColumnDef< export type MRT_DefinedColumnDef< TData extends MRT_RowData, TValue = unknown, -> = Omit, 'defaultDisplayColumn' | 'id'> & { +> = MRT_ColumnDef & { _filterFn: MRT_FilterOption defaultDisplayColumn: Partial> id: string } -export type MRT_Column = Omit< - Column, - 'columnDef' | 'columns' | 'filterFn' | 'footer' | 'header' -> & { - columnDef: MRT_DefinedColumnDef - columns?: Array> - filterFn?: MRT_FilterFn - footer: string - header: string -} +export type MRT_Column = Column< + MRT_Features, + TData, + TValue +> -export type MRT_Header = Omit< - Header, - 'column' -> & { - column: MRT_Column -} +export type MRT_Header = Header< + MRT_Features, + TData, + unknown +> -export type MRT_HeaderGroup = Omit< - HeaderGroup, - 'headers' -> & { - headers: Array> -} +export type MRT_HeaderGroup = HeaderGroup< + MRT_Features, + TData +> -export type MRT_Row = Omit< - Row, - | '_valuesCache' - | 'getAllCells' - | 'getParentRow' - | 'getParentRows' - | 'getRow' - | 'getVisibleCells' - | 'subRows' -> & { - _valuesCache: Record>, any> - getAllCells: () => Array> - getParentRow: () => MRT_Row | null - getParentRows: () => Array> - getRow: () => MRT_Row - getVisibleCells: () => Array> - subRows?: Array> -} +export type MRT_Row = Row -export type MRT_Cell = Omit< - Cell, - 'column' | 'row' -> & { - column: MRT_Column - row: MRT_Row -} +export type MRT_Cell = Cell< + MRT_Features, + TData, + TValue +> export type MRT_AggregationOption = string & keyof typeof MRT_AggregationFns @@ -881,525 +420,14 @@ export type MRT_DisplayColumnIds = | 'mrt-row-spacer' /** - * `columns` and `data` props are the only required props, but there are over 170 other optional props. - * - * See more info on creating columns and data on the official docs site: - * @link https://www.material-react-table.com/docs/getting-started/usage + * `columns` and `data` are the only required table options; MRT's ~170 other + * options now live on `TableOptions` via the feature maps + * (`./features/mrtConfigFeature.ts` plus the stateful `mrt*Feature` files), so + * this is a thin alias. * - * See the full props list on the official docs site: - * @link https://www.material-react-table.com/docs/api/props + * @link https://www.material-react-table.com/docs/api/table-options */ -export interface MRT_TableOptions extends Omit< - Partial>, - | 'columns' - | 'data' - | 'defaultColumn' - | 'enableRowSelection' - | 'expandRowsFn' - | 'getRowId' - | 'globalFilterFn' - | 'initialState' - | 'onStateChange' - | 'state' -> { - /** - * Custom aggregation functions to apply to the table. These get merged with MRT's - * built-ins (`mean`, `min`, `max`, etc.) and passed into `createGroupedRowModel(...)`. - * @link https://www.material-react-table.com/docs/api/table-options#aggregationFns - */ - aggregationFns?: Record> - /** - * Custom filter functions to apply to the table. These get merged with MRT's - * built-ins (`fuzzy`, `contains`, `between`, etc.) and passed into - * `createFilteredRowModel(...)`. - * @link https://www.material-react-table.com/docs/api/table-options#filterFns - */ - filterFns?: Record> - /** - * Custom sort functions to apply to the table. These get merged with MRT's - * built-ins (`alphanumeric`, `fuzzy`, etc.) and passed into - * `createSortedRowModel(...)`. - * @link https://www.material-react-table.com/docs/api/table-options#sortFns - */ - sortFns?: Record> - columnFilterDisplayMode?: 'custom' | 'popover' | 'subheader' - columnFilterModeOptions?: Array< - LiteralUnion - > | null - /** - * The columns to display in the table. `accessorKey`s or `accessorFn`s must match keys in the `data` table option. - * - * See more info on creating columns on the official docs site: - * @link https://www.material-react-table.com/docs/guides/data-columns - * @link https://www.material-react-table.com/docs/guides/display-columns - * - * See all Columns Options on the official docs site: - * @link https://www.material-react-table.com/docs/api/column-options - */ - columns: Array> - columnVirtualizerInstanceRef?: RefObject - columnVirtualizerOptions?: - | ((props: { - table: MRT_TableInstance - }) => Partial>) - | Partial> - createDisplayMode?: 'custom' | 'modal' | 'row' - /** - * Pass your data as an array of objects. Objects can theoretically be any shape, but it's best to keep them consistent. - * - * See the usage guide for more info on creating columns and data: - * @link https://www.material-react-table.com/docs/getting-started/usage - */ - data: Array - /** - * Instead of specifying a bunch of the same options for each column, you can just change an option in the `defaultColumn` table option to change a default option for all columns. - */ - defaultColumn?: Partial> - /** - * Change the default options for display columns. - */ - defaultDisplayColumn?: Partial> - displayColumnDefOptions?: Partial<{ - [key in MRT_DisplayColumnIds]: Partial> - }> - editDisplayMode?: 'cell' | 'custom' | 'modal' | 'row' | 'table' - enableBatchRowSelection?: boolean - enableBottomToolbar?: boolean - enableCellActions?: ((cell: MRT_Cell) => boolean) | boolean - enableClickToCopy?: - | 'context-menu' - | ((cell: MRT_Cell) => 'context-menu' | boolean) - | boolean - enableColumnActions?: boolean - enableColumnDragging?: boolean - enableColumnFilterModes?: boolean - enableColumnOrdering?: boolean - enableColumnVirtualization?: boolean - enableDensityToggle?: boolean - enableEditing?: ((row: MRT_Row) => boolean) | boolean - enableExpandAll?: boolean - enableFacetedValues?: boolean - enableFilterMatchHighlighting?: boolean - enableFullScreenToggle?: boolean - enableGlobalFilterModes?: boolean - enableGlobalFilterRankedResults?: boolean - enableKeyboardShortcuts?: boolean - enablePagination?: boolean - enableRowActions?: boolean - enableRowDragging?: boolean - enableRowNumbers?: boolean - enableRowOrdering?: boolean - enableRowSelection?: ((row: MRT_Row) => boolean) | boolean - enableRowVirtualization?: boolean - enableSelectAll?: boolean - enableStickyFooter?: boolean - enableStickyHeader?: boolean - enableTableFooter?: boolean - enableTableHead?: boolean - enableToolbarInternalActions?: boolean - enableTopToolbar?: boolean - expandRowsFn?: (dataRow: TData) => Array - getRowId?: ( - originalRow: TData, - index: number, - parentRow: MRT_Row, - ) => string - globalFilterFn?: MRT_FilterOption - globalFilterModeOptions?: Array | null - icons?: Partial - id?: string - initialState?: Partial> - /** - * Changes which kind of CSS layout is used to render the table. `semantic` uses default semantic HTML elements, while `grid` adds CSS grid and flexbox styles - */ - layoutMode?: 'grid' | 'grid-no-grow' | 'semantic' - /** - * Pass in either a locale imported from `material-react-table/locales/*` or a custom locale object. - * - * See the localization (i18n) guide for more info: - * @link https://www.material-react-table.com/docs/guides/localization - */ - localization?: Partial - /** - * Memoize cells, rows, or the entire table body to potentially improve render performance. - * - * @warning This will break some dynamic rendering features. See the memoization guide for more info: - * @link https://www.material-react-table.com/docs/guides/memoize-components - */ - memoMode?: 'cells' | 'rows' | 'table-body' - mrtTheme?: ((theme: Theme) => Partial) | Partial - muiBottomToolbarProps?: - | ((props: { table: MRT_TableInstance }) => BoxProps) - | BoxProps - muiCircularProgressProps?: - | ((props: { - table: MRT_TableInstance - }) => CircularProgressProps & { Component?: ReactNode }) - | (CircularProgressProps & { Component?: ReactNode }) - muiColumnActionsButtonProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => IconButtonProps) - | IconButtonProps - muiColumnDragHandleProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => IconButtonProps) - | IconButtonProps - muiCopyButtonProps?: - | ((props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => ButtonProps) - | ButtonProps - muiCreateRowModalProps?: - | ((props: { - row: MRT_Row - table: MRT_TableInstance - }) => DialogProps) - | DialogProps - muiDetailPanelProps?: - | ((props: { - row: MRT_Row - table: MRT_TableInstance - }) => TableCellProps) - | TableCellProps - muiEditRowDialogProps?: - | ((props: { - row: MRT_Row - table: MRT_TableInstance - }) => DialogProps) - | DialogProps - muiEditTextFieldProps?: - | ((props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => TextFieldProps) - | TextFieldProps - muiExpandAllButtonProps?: - | ((props: { table: MRT_TableInstance }) => IconButtonProps) - | IconButtonProps - muiExpandButtonProps?: - | ((props: { - row: MRT_Row - staticRowIndex?: number - table: MRT_TableInstance - }) => IconButtonProps) - | IconButtonProps - muiFilterAutocompleteProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => AutocompleteProps) - | AutocompleteProps - muiFilterCheckboxProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => CheckboxProps) - | CheckboxProps - muiFilterDatePickerProps?: - | ((props: { - column: MRT_Column - rangeFilterIndex?: number - table: MRT_TableInstance - }) => DatePickerProps) - | DatePickerProps - muiFilterDateTimePickerProps?: - | ((props: { - column: MRT_Column - rangeFilterIndex?: number - table: MRT_TableInstance - }) => DateTimePickerProps) - | DateTimePickerProps - muiFilterSliderProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => SliderProps) - | SliderProps - muiFilterTextFieldProps?: - | ((props: { - column: MRT_Column - rangeFilterIndex?: number - table: MRT_TableInstance - }) => TextFieldProps) - | TextFieldProps - muiFilterTimePickerProps?: - | ((props: { - column: MRT_Column - rangeFilterIndex?: number - table: MRT_TableInstance - }) => TimePickerProps) - | TimePickerProps - muiLinearProgressProps?: - | ((props: { - isTopToolbar: boolean - table: MRT_TableInstance - }) => LinearProgressProps) - | LinearProgressProps - muiPaginationProps?: - | ((props: { table: MRT_TableInstance }) => Partial< - PaginationProps & { - SelectProps?: Partial - disabled?: boolean - rowsPerPageOptions?: - | Array<{ label: string; value: number }> - | Array - showRowsPerPage?: boolean - } - >) - | Partial< - PaginationProps & { - SelectProps?: Partial - disabled?: boolean - rowsPerPageOptions?: - | Array<{ label: string; value: number }> - | Array - showRowsPerPage?: boolean - } - > - muiRowDragHandleProps?: - | ((props: { - row: MRT_Row - table: MRT_TableInstance - }) => IconButtonProps) - | IconButtonProps - muiSearchTextFieldProps?: - | ((props: { table: MRT_TableInstance }) => TextFieldProps) - | TextFieldProps - muiSelectAllCheckboxProps?: - | ((props: { table: MRT_TableInstance }) => CheckboxProps) - | CheckboxProps - muiSelectCheckboxProps?: - | ((props: { - row: MRT_Row - staticRowIndex?: number - table: MRT_TableInstance - }) => CheckboxProps | RadioProps) - | (CheckboxProps | RadioProps) - muiSkeletonProps?: - | ((props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => SkeletonProps) - | SkeletonProps - muiTableBodyCellProps?: - | ((props: { - cell: MRT_Cell - column: MRT_Column - row: MRT_Row - table: MRT_TableInstance - }) => TableCellProps) - | TableCellProps - muiTableBodyProps?: - | ((props: { table: MRT_TableInstance }) => TableBodyProps) - | TableBodyProps - muiTableBodyRowProps?: - | ((props: { - isDetailPanel?: boolean - row: MRT_Row - staticRowIndex: number - table: MRT_TableInstance - }) => TableRowProps) - | TableRowProps - muiTableContainerProps?: - | ((props: { table: MRT_TableInstance }) => TableContainerProps) - | TableContainerProps - muiTableFooterCellProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => TableCellProps) - | TableCellProps - muiTableFooterProps?: - | ((props: { table: MRT_TableInstance }) => TableFooterProps) - | TableFooterProps - muiTableFooterRowProps?: - | ((props: { - footerGroup: MRT_HeaderGroup - table: MRT_TableInstance - }) => TableRowProps) - | TableRowProps - muiTableHeadCellProps?: - | ((props: { - column: MRT_Column - table: MRT_TableInstance - }) => TableCellProps) - | TableCellProps - muiTableHeadProps?: - | ((props: { table: MRT_TableInstance }) => TableHeadProps) - | TableHeadProps - muiTableHeadRowProps?: - | ((props: { - headerGroup: MRT_HeaderGroup - table: MRT_TableInstance - }) => TableRowProps) - | TableRowProps - muiTablePaperProps?: - | ((props: { table: MRT_TableInstance }) => PaperProps) - | PaperProps - muiTableProps?: - | ((props: { table: MRT_TableInstance }) => TableProps) - | TableProps - muiToolbarAlertBannerChipProps?: - | ((props: { table: MRT_TableInstance }) => ChipProps) - | ChipProps - muiToolbarAlertBannerProps?: - | ((props: { table: MRT_TableInstance }) => AlertProps) - | AlertProps - muiTopToolbarProps?: - | ((props: { table: MRT_TableInstance }) => BoxProps) - | BoxProps - onActionCellChange?: OnChangeFn | null> - onColumnFilterFnsChange?: OnChangeFn<{ [key: string]: MRT_FilterOption }> - onCreatingRowCancel?: (props: { - row: MRT_Row - table: MRT_TableInstance - }) => void - onCreatingRowChange?: OnChangeFn | null> - onCreatingRowSave?: (props: { - exitCreatingMode: () => void - row: MRT_Row - table: MRT_TableInstance - values: Record>, any> - }) => Promise | void - onDensityChange?: OnChangeFn - onDraggingColumnChange?: OnChangeFn | null> - onDraggingRowChange?: OnChangeFn | null> - onEditingCellChange?: OnChangeFn | null> - onEditingRowCancel?: (props: { - row: MRT_Row - table: MRT_TableInstance - }) => void - onEditingRowChange?: OnChangeFn | null> - onEditingRowSave?: (props: { - exitEditingMode: () => void - row: MRT_Row - table: MRT_TableInstance - values: Record>, any> - }) => Promise | void - onGlobalFilterFnChange?: OnChangeFn - onHoveredColumnChange?: OnChangeFn> | null> - onHoveredRowChange?: OnChangeFn> | null> - onIsFullScreenChange?: OnChangeFn - onShowAlertBannerChange?: OnChangeFn - onShowColumnFiltersChange?: OnChangeFn - onShowGlobalFilterChange?: OnChangeFn - onShowToolbarDropZoneChange?: OnChangeFn - paginationDisplayMode?: 'custom' | 'default' | 'pages' - positionActionsColumn?: 'first' | 'last' - positionCreatingRow?: 'bottom' | 'top' | number - positionExpandColumn?: 'first' | 'last' - positionGlobalFilter?: 'left' | 'none' | 'right' - positionPagination?: 'both' | 'bottom' | 'none' | 'top' - positionToolbarAlertBanner?: 'bottom' | 'head-overlay' | 'none' | 'top' - positionToolbarDropZone?: 'both' | 'bottom' | 'none' | 'top' - renderBottomToolbar?: - | ((props: { table: MRT_TableInstance }) => ReactNode) - | ReactNode - renderBottomToolbarCustomActions?: (props: { - table: MRT_TableInstance - }) => ReactNode - renderCaption?: - | ((props: { table: MRT_TableInstance }) => ReactNode) - | ReactNode - renderCellActionMenuItems?: (props: { - cell: MRT_Cell - closeMenu: () => void - column: MRT_Column - internalMenuItems: Array - row: MRT_Row - staticColumnIndex?: number - staticRowIndex?: number - table: MRT_TableInstance - }) => Array - renderColumnActionsMenuItems?: (props: { - closeMenu: () => void - column: MRT_Column - internalColumnMenuItems: Array - table: MRT_TableInstance - }) => Array - renderColumnFilterModeMenuItems?: (props: { - column: MRT_Column - internalFilterOptions: Array - onSelectFilterMode: (filterMode: MRT_FilterOption) => void - table: MRT_TableInstance - }) => Array - renderCreateRowDialogContent?: (props: { - internalEditComponents: Array - row: MRT_Row - table: MRT_TableInstance - }) => ReactNode - renderDetailPanel?: (props: { - row: MRT_Row - table: MRT_TableInstance - }) => ReactNode - renderEditRowDialogContent?: (props: { - internalEditComponents: Array - row: MRT_Row - table: MRT_TableInstance - }) => ReactNode - renderEmptyRowsFallback?: (props: { - table: MRT_TableInstance - }) => ReactNode - renderGlobalFilterModeMenuItems?: (props: { - internalFilterOptions: Array - onSelectFilterMode: (filterMode: MRT_FilterOption) => void - table: MRT_TableInstance - }) => Array - renderRowActionMenuItems?: (props: { - closeMenu: () => void - row: MRT_Row - staticRowIndex?: number - table: MRT_TableInstance - }) => Array | undefined - renderRowActions?: (props: { - cell: MRT_Cell - row: MRT_Row - staticRowIndex?: number - table: MRT_TableInstance - }) => ReactNode - renderToolbarAlertBannerContent?: (props: { - groupedAlert: ReactNode | null - selectedAlert: ReactNode | null - table: MRT_TableInstance - }) => ReactNode - renderToolbarInternalActions?: (props: { - table: MRT_TableInstance - }) => ReactNode - renderTopToolbar?: - | ((props: { table: MRT_TableInstance }) => ReactNode) - | ReactNode - renderTopToolbarCustomActions?: (props: { - table: MRT_TableInstance - }) => ReactNode - rowNumberDisplayMode?: 'original' | 'static' - rowPinningDisplayMode?: - | 'bottom' - | 'select-bottom' - | 'select-sticky' - | 'select-top' - | 'sticky' - | 'top' - | 'top-and-bottom' - rowVirtualizerInstanceRef?: RefObject - rowVirtualizerOptions?: - | ((props: { - table: MRT_TableInstance - }) => Partial>) - | Partial> - selectAllMode?: 'all' | 'page' - /** - * Manage state externally any way you want, then pass it back into MRT. - */ - state?: Partial> -} +export type MRT_TableOptions = Omit< + TableOptions, + 'features' +> & { features?: MRT_Features } diff --git a/examples/react/material-react-table/src/material-react-table/utils/column.utils.ts b/examples/react/material-react-table/src/material-react-table/utils/column.utils.ts index 5b80fffece..eb75aa9a82 100644 --- a/examples/react/material-react-table/src/material-react-table/utils/column.utils.ts +++ b/examples/react/material-react-table/src/material-react-table/utils/column.utils.ts @@ -13,10 +13,15 @@ import type { MRT_TableInstance, } from '../types' +// `MRT_ColumnDef` is now the core `ColumnDef` union, so accessor-key / group / +// MRT-specific fields live on individual union members. This resolution code +// reads and mutates them freely, so it operates on a loose view via `any`. export const getColumnId = ( columnDef: MRT_ColumnDef, -): string => - columnDef.id ?? columnDef.accessorKey?.toString?.() ?? columnDef.header +): string => { + const def = columnDef as any + return def.id ?? def.accessorKey?.toString?.() ?? def.header +} export const getAllLeafColumnDefs = ( columns: Array>, @@ -24,8 +29,11 @@ export const getAllLeafColumnDefs = ( const allLeafColumnDefs: Array> = [] const getLeafColumns = (cols: Array>) => { cols.forEach((col) => { - if (col.columns) { - getLeafColumns(col.columns) + const subCols = (col as any).columns as + | Array> + | undefined + if (subCols) { + getLeafColumns(subCols) } else { allLeafColumnDefs.push(col) } @@ -42,30 +50,34 @@ export const prepareColumns = ({ columnDefs: Array> tableOptions: MRT_DefinedTableOptions }): Array> => { + // `aggregationFns` / `filterFns` / `sortFns` are carried on the options object + // at runtime (client-supplied custom fns), but aren't declared as core options + // (they're feature-slot registries), so read them off a loose view. const { aggregationFns = {}, defaultDisplayColumn, filterFns = {}, sortFns = {}, state: { columnFilterFns = {} } = {}, - } = tableOptions + } = tableOptions as any return columnDefs.map((columnDef) => { + const def = columnDef as any // assign columnId - if (!columnDef.id) columnDef.id = getColumnId(columnDef) + if (!def.id) def.id = getColumnId(columnDef) // assign columnDefType - if (!columnDef.columnDefType) columnDef.columnDefType = 'data' - if (columnDef.columns?.length) { - columnDef.columnDefType = 'group' + if (!def.columnDefType) def.columnDefType = 'data' + if (def.columns?.length) { + def.columnDefType = 'group' // recursively prepare columns if this is a group column - columnDef.columns = prepareColumns({ - columnDefs: columnDef.columns, + def.columns = prepareColumns({ + columnDefs: def.columns, tableOptions, }) - } else if (columnDef.columnDefType === 'data') { + } else if (def.columnDefType === 'data') { // assign aggregationFns if multiple aggregationFns are provided - if (Array.isArray(columnDef.aggregationFn)) { - const aggFns = columnDef.aggregationFn as Array - columnDef.aggregationFn = ( + if (Array.isArray(def.aggregationFn)) { + const aggFns = def.aggregationFn as Array + def.aggregationFn = ( columnId: string, leafRows: Array>, childRows: Array>, @@ -76,18 +88,16 @@ export const prepareColumns = ({ } // assign filterFns - if (Object.keys(filterFns).includes(columnFilterFns[columnDef.id])) { - columnDef.filterFn = - filterFns[columnFilterFns[columnDef.id]] ?? filterFns.fuzzy - ;(columnDef as MRT_DefinedColumnDef)._filterFn = - columnFilterFns[columnDef.id] + if (Object.keys(filterFns).includes(columnFilterFns[def.id])) { + def.filterFn = filterFns[columnFilterFns[def.id]] ?? filterFns.fuzzy + def._filterFn = columnFilterFns[def.id] } // assign sortFns - if (Object.keys(sortFns).includes(columnDef.sortFn as string)) { - columnDef.sortFn = sortFns[columnDef.sortFn as string] + if (Object.keys(sortFns).includes(def.sortFn as string)) { + def.sortFn = sortFns[def.sortFn as string] } - } else if (columnDef.columnDefType === 'display') { + } else if (def.columnDefType === 'display') { columnDef = { ...(defaultDisplayColumn as MRT_ColumnDef), ...columnDef, @@ -146,7 +156,7 @@ export const getColumnFilterInfo = ({ const isRangeFilter = filterVariant?.includes('range') || ['between', 'betweenInclusive', 'inNumberRange'].includes( - columnDef._filterFn, + columnDef._filterFn!, ) const isSelectFilter = filterVariant === 'select' const isMultiSelectFilter = filterVariant === 'multi-select' diff --git a/examples/react/material-react-table/src/material-react-table/utils/displayColumn.utils.ts b/examples/react/material-react-table/src/material-react-table/utils/displayColumn.utils.ts index 02a092c1bb..edac958ffb 100644 --- a/examples/react/material-react-table/src/material-react-table/utils/displayColumn.utils.ts +++ b/examples/react/material-react-table/src/material-react-table/utils/displayColumn.utils.ts @@ -130,9 +130,9 @@ export const getDefaultColumnOrderIds = ( const trailingDisplayColIds: Array = getTrailingDisplayColumnIds(tableOptions) - const defaultColumnDefIds = getAllLeafColumnDefs(tableOptions.columns).map( - (columnDef) => getColumnId(columnDef), - ) + const defaultColumnDefIds = getAllLeafColumnDefs( + tableOptions.columns as any, + ).map((columnDef) => getColumnId(columnDef)) let allLeafColumnDefIds = reset ? defaultColumnDefIds diff --git a/examples/react/material-react-table/src/material-react-table/utils/row.utils.ts b/examples/react/material-react-table/src/material-react-table/utils/row.utils.ts index 850bb90b0a..4d497f842d 100644 --- a/examples/react/material-react-table/src/material-react-table/utils/row.utils.ts +++ b/examples/react/material-react-table/src/material-react-table/utils/row.utils.ts @@ -70,7 +70,7 @@ export const getMRT_Rows = ( : rows.length rows = [ ...rows.slice(0, creatingRowIndex), - creatingRow, + creatingRow as MRT_Row, ...rows.slice(creatingRowIndex), ] } diff --git a/examples/react/material-react-table/src/material-react-table/utils/tanstack.helpers.ts b/examples/react/material-react-table/src/material-react-table/utils/tanstack.helpers.ts index 32375bf7e5..b39c2efed4 100644 --- a/examples/react/material-react-table/src/material-react-table/utils/tanstack.helpers.ts +++ b/examples/react/material-react-table/src/material-react-table/utils/tanstack.helpers.ts @@ -75,7 +75,7 @@ export const createRow = ( originalRow ?? Object.assign( {}, - ...getAllLeafColumnDefs(table.options.columns).map((col) => ({ + ...getAllLeafColumnDefs(table.options.columns as any).map((col) => ({ [getColumnId(col)]: '', })), ), diff --git a/test-results/.last-run.json b/test-results/.last-run.json index cbcc1fbac1..f740f7c700 100644 --- a/test-results/.last-run.json +++ b/test-results/.last-run.json @@ -1,4 +1,4 @@ { "status": "passed", "failedTests": [] -} \ No newline at end of file +}