diff --git a/.changeset/polite-rice-serve.md b/.changeset/polite-rice-serve.md new file mode 100644 index 00000000..e8a382ca --- /dev/null +++ b/.changeset/polite-rice-serve.md @@ -0,0 +1,5 @@ +--- +"@heathmont/moon-table-v8-tw": patch +--- + +fix: add accessor key to select column to avoid crashing when no data is present [MDS-1321] diff --git a/.vscode/settings.json b/.vscode/settings.json index f085a3b4..c4ea87f0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,5 @@ "**/.git/subtree-cache/**": true }, "prettier.printWidth": 2, - "eslint.workingDirectories": [ - "./docs" - ] + "eslint.workingDirectories": ["./docs"] } diff --git a/packages/table-v8/package.json b/packages/table-v8/package.json index dc6963a7..2e05ee09 100644 --- a/packages/table-v8/package.json +++ b/packages/table-v8/package.json @@ -16,11 +16,10 @@ }, "dependencies": { "@heathmont/moon-core-tw": "^10.17.3", - "@tanstack/react-table": "^8.9.11", + "@tanstack/react-table": "^8.20.5", "react": "18.2.0", "react-dom": "18.2.0" }, - "devDependencies": {}, "peerDependencies": { "react": ">=16", "react-dom": ">=16" diff --git a/packages/table-v8/src/components/TD.tsx b/packages/table-v8/src/components/TD.tsx index bee4939e..2c54efac 100644 --- a/packages/table-v8/src/components/TD.tsx +++ b/packages/table-v8/src/components/TD.tsx @@ -8,6 +8,7 @@ import type { Cell } from "../private/types"; import type ClipProps from "../private/types/ClipProps"; import type StickyColumn from "../private/types/StickyColumn"; import type TDProps from "../private/types/TDProps"; +import TDContent from "./TDContent"; const getStickyShift = ( cells: Cell<{}, unknown>[], @@ -31,94 +32,72 @@ const getStickyShift = ( } }; -const TD = forwardRef( - ( - { - cell, - index, - cells, - rowSize, - noGap, - className, - isFirstColumn, - isLastColumn, - columnData, - textClip, - withBorder, - }, - ref, - ) => { - const stickyColumn: StickyColumn = cell.column.parent - ? cell.column.parent?.columnDef - : cell.column.columnDef; - const stickySide = stickyColumn.sticky; +const TD = forwardRef((props, ref) => { + const { + cell, + index, + cells, + rowSize, + noGap, + className, + isFirstColumn, + isLastColumn, + columnData, + textClip, + withBorder, + } = props; + const stickyColumn: StickyColumn = cell.column.parent + ? cell.column.parent?.columnDef + : cell.column.columnDef; + const stickySide = stickyColumn.sticky; - const styles = new Map([ - ["width", `${cell.column.getSize()}px`], - [ - "minWidth", - // prettier-ignore - `${stickySide ? cell.column.columnDef.size : cell.column.columnDef.minSize}px`, - ], - [ - "maxWidth", - // prettier-ignore - `${stickySide ? cell.column.columnDef.size : cell.column.columnDef.maxSize}px`, - ], - ]); + const styles = new Map([ + ["width", `${cell.column.getSize()}px`], + [ + "minWidth", + // prettier-ignore + `${stickySide ? cell.column.columnDef.size : cell.column.columnDef.minSize}px`, + ], + [ + "maxWidth", + // prettier-ignore + `${stickySide ? cell.column.columnDef.size : cell.column.columnDef.maxSize}px`, + ], + ]); - if (stickySide) { - styles.set( - stickySide, - stickySide === "left" - ? // prettier-ignore - `${columnData ? columnData?.left : getStickyShift(cells, index, "left")}px` - : // prettier-ignore - `${columnData ? columnData?.right : getStickyShift(cells, index, "right")}px`, - ); - } - - return ( - - { - - } - {textClip ? ( -
- {flexRender(cell.column.columnDef.cell, cell.getContext())} -
- ) : ( - flexRender(cell.column.columnDef.cell, cell.getContext()) - )} - + if (stickySide) { + styles.set( + stickySide, + stickySide === "left" + ? // prettier-ignore + `${columnData ? columnData?.left : getStickyShift(cells, index, "left")}px` + : // prettier-ignore + `${columnData ? columnData?.right : getStickyShift(cells, index, "right")}px`, ); - }, -); + } + + return ( + + + + ); +}); export default TD; diff --git a/packages/table-v8/src/components/TDContent.tsx b/packages/table-v8/src/components/TDContent.tsx new file mode 100644 index 00000000..5836e77f --- /dev/null +++ b/packages/table-v8/src/components/TDContent.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { FC } from "react"; +import TDProps from "../private/types/TDProps"; +import CellBorder from "./CellBorder"; +import TDFlexRender from "./TDFlexRender"; + +type Props = TDProps & { + stickySide?: string; +}; + +const TDContent: FC = (props) => { + const { isFirstColumn, stickySide, withBorder } = props; + + return ( + <> + + + + + ); +}; + +export default TDContent; diff --git a/packages/table-v8/src/components/TDFlexRender.tsx b/packages/table-v8/src/components/TDFlexRender.tsx new file mode 100644 index 00000000..8b84634f --- /dev/null +++ b/packages/table-v8/src/components/TDFlexRender.tsx @@ -0,0 +1,32 @@ +import React, { FC } from "react"; +import { mergeClassnames } from "@heathmont/moon-core-tw"; +import type ClipProps from "../private/types/ClipProps"; +import TDProps from "../private/types/TDProps"; +import { flexRender } from "../private/utils"; + +const TDFlexRender: FC = ({ cell, textClip }) => { + if (cell.getValue() === undefined) { + return null; + } + + const flexRenderedCell = flexRender( + cell.column.columnDef.cell, + cell.getContext(), + ); + + if (textClip) { + return ( +
+ {flexRenderedCell} +
+ ); + } + return flexRenderedCell; +}; + +export default TDFlexRender; diff --git a/packages/table-v8/src/components/Table.tsx b/packages/table-v8/src/components/Table.tsx index 67887973..3bf86d7b 100644 --- a/packages/table-v8/src/components/Table.tsx +++ b/packages/table-v8/src/components/Table.tsx @@ -19,6 +19,8 @@ import Minimap from "./Minimap"; import type { ColumnResizeMode } from "../private/types"; import type ColumnData from "../private/types/ColumnData"; import type TableProps from "../private/types/TableProps"; +import DataHelper from "../private/types/DataHelper"; +import handleSelectableTable from "../private/utils/handleSelectableTable"; const Table = ({ columns, @@ -60,10 +62,13 @@ const Table = ({ React.useState('ltr') */ + const { data: selectableData, columns: selectableColumns } = + handleSelectableTable({ data, columns, isSelectable }); + const table = useReactTable({ - columns, + columns: selectableColumns, columnResizeMode, - data, + data: selectableData, defaultColumn, state, enableColumnResizing: isResizable, diff --git a/packages/table-v8/src/private/utils/handleSelectableTable.ts b/packages/table-v8/src/private/utils/handleSelectableTable.ts new file mode 100644 index 00000000..ac6f6861 --- /dev/null +++ b/packages/table-v8/src/private/utils/handleSelectableTable.ts @@ -0,0 +1,44 @@ +import DataHelper from "../types/DataHelper"; +import TableProps from "../types/TableProps"; + +type Args = Pick & { + data: DataHelper[]; + isSelectable?: boolean; +}; + +const handleSelectableTable = ({ + data, + isSelectable = false, + columns, +}: Args) => { + const selectColumnIndex = columns.findIndex( + (column) => column.id === "select", + ); + + if (!isSelectable || selectColumnIndex < 0) { + return { data, columns }; + } + + const selectableData: DataHelper[] = data.map((dataItem) => ({ + ...dataItem, + select: dataItem.select ?? false, + })); + + const selectColumn = { + ...columns[selectColumnIndex], + accessorKey: "select", + }; + + const selectableColumns = [ + ...columns.slice(0, selectColumnIndex), + { ...selectColumn }, + ...columns.slice(selectColumnIndex + 1), + ]; + + return { + data: selectableData, + columns: selectableColumns, + }; +}; + +export default handleSelectableTable; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 106525a9..8887b581 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -209,7 +209,7 @@ importers: specifier: ^10.17.3 version: link:../core '@tanstack/react-table': - specifier: ^8.9.11 + specifier: ^8.20.5 version: 8.20.5(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 diff --git a/words.txt b/words.txt index 48b46112..84f53ab6 100644 --- a/words.txt +++ b/words.txt @@ -19,6 +19,7 @@ datetime datetimelocal dodoria Draghandle +esbenp fraunces frieza frontmatter