diff --git a/packages/ui-kit/src/components/table/table/Table.tsx b/packages/ui-kit/src/components/table/table/Table.tsx index c69b5c52a..703d08cbb 100644 --- a/packages/ui-kit/src/components/table/table/Table.tsx +++ b/packages/ui-kit/src/components/table/table/Table.tsx @@ -1,228 +1,256 @@ -import { ColumnResizeMode, getCoreRowModel, useReactTable, flexRender, createColumnHelper } from '@tanstack/react-table'; -import React, { FC, useEffect, useState, ReactNode, useRef } from 'react'; -import TableDraggableRow from "./TableDraggableRow"; -import cx from "classnames"; -import "../../table-v3/primary-table/table.sass"; -import classNames from 'classnames'; +import { FC, useEffect, useState, ReactNode, useRef } from 'react'; +import { + ColumnResizeMode, + getCoreRowModel, + useReactTable, + flexRender, + createColumnHelper, +} from '@tanstack/react-table'; +import cx from 'classnames'; +import TableDraggableRow from './TableDraggableRow'; +import '../../table-v3/primary-table/table.sass'; const Table: FC = ({ - name = "", - data = [], - columns, - tableResizable = false, - columnRenderer = () => { }, - cellRenderer = () => { }, - tableWidth = 200, - options = {} + name = '', + data = [], + columns, + resizable = false, + columnRenderer = () => {}, + cellRenderer = () => {}, + width = 200, + options = {}, }) => { + const [tableData, setTableData] = useState(() => []); + const [dragId, setDragId] = useState(0); + const [containerWidth, setContainerWidth] = useState(width); - const [tableData, setTableData] = useState(() => []) - const [dragId, setDragId] = useState(0); - const [containerWidth, setContainerWidth] = useState(tableWidth); - - - const tableRef = useRef(null); - const containerDivRef = useRef(null); - - - const [columnResizeMode, setColumnResizeMode] = React.useState('onChange') - - const columnHelper = createColumnHelper() - - const columnDisplay = [ - ...columns.map(column => columnHelper.accessor(column.name, - { - id: column.name, - ...(typeof column.width !== "undefined" ? { size: column.width } : {}), - minSize: ( - typeof column.minSize !== "undefined" ? column.minSize : - (typeof options.minColumnSize !== "undefined" ? options.minColumnSize : 50 ) - ), - enableResizing: (typeof column.enableResizing !== "undefined") ? column.enableResizing : false, - header: (col) => { - return columnRenderer((typeof column.displayName !== "undefined" ? column.displayName : column.name)) - }, - cell: ({cell}) => { - let cellValue = cell.getValue(); - if(cell.getValue() !== "undefined"){ - return cellRenderer({cellValue, - rowIndex : cell.row.index, - columnId: cell.column.id, - column: cell.column - }) - }else{ - return<> - } - - }, - } - )) - ]; - - useEffect(() => { - setTableData(data) - }, [data]); - - //get the width of container div in pixels - useEffect(() => { - if (!containerDivRef.current) return; - const resizeObserver = new ResizeObserver(() => { - setContainerWidth(containerDivRef.current.clientWidth) - }); - resizeObserver.observe(containerDivRef.current); - return () => resizeObserver.disconnect(); - }, [containerDivRef.current]); - - const table = useReactTable({ - data: tableData, - columns: columnDisplay, - enableColumnResizing: tableResizable, - ...(tableResizable ? { columnResizeMode: columnResizeMode } : {}), - getCoreRowModel: getCoreRowModel(), + const tableRef = useRef(null); + const containerDivRef = useRef(null); + + const [columnResizeMode, setColumnResizeMode] = + useState('onChange'); + + const columnHelper = createColumnHelper(); + + const columnDisplay = [ + ...columns.map((column) => + columnHelper.accessor(column.name, { + id: column.name, + ...(typeof column.width !== 'undefined' ? { size: column.width } : {}), + minSize: + typeof column.minSize !== 'undefined' + ? column.minSize + : typeof options.minColumnSize !== 'undefined' + ? options.minColumnSize + : 50, + enableResizing: + typeof column.enableResizing !== 'undefined' + ? column.enableResizing + : false, + header: (col) => { + return columnRenderer( + typeof column.displayName !== 'undefined' + ? column.displayName + : column.name + ); + }, + cell: ({ cell }) => { + let cellValue = cell.getValue(); + if (cell.getValue() !== 'undefined') { + return cellRenderer({ + cellValue, + rowIndex: cell.row.index, + columnId: cell.column.id, + column: cell.column, + }); + } else { + return <>; + } + }, + }) + ), + ]; + + useEffect(() => { + setTableData(data); + }, [data]); + + //get the width of container div in pixels + useEffect(() => { + if (!containerDivRef.current) return; + const resizeObserver = new ResizeObserver(() => { + setContainerWidth(containerDivRef.current.clientWidth); }); + resizeObserver.observe(containerDivRef.current); + return () => resizeObserver.disconnect(); + }, [containerDivRef.current]); + const table = useReactTable({ + data: tableData, + columns: columnDisplay, + enableColumnResizing: resizable, + ...(resizable ? { columnResizeMode: columnResizeMode } : {}), + getCoreRowModel: getCoreRowModel(), + }); - function drag(rowIndex: number) { - setDragId(rowIndex); - } + function drag(rowIndex: number) { + setDragId(rowIndex); + } - //reorder the index value for the table rows - function drop(rowIndex: number) { - tableData.splice(rowIndex, 0, tableData.splice(dragId, 1)[0]) - setTableData([...tableData]) - } + //reorder the index value for the table rows + function drop(rowIndex: number) { + tableData.splice(rowIndex, 0, tableData.splice(dragId, 1)[0]); + setTableData([...tableData]); + } - return ( -
- +
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + - - {table.getHeaderGroups().map(headerGroup => - - { - headerGroup.headers.map(header => { - return - }) - } - )} - - - {table.getRowModel().rows.map(row => { - return - })} - - -
-
table.getTotalSize()) ? header.getSize() + (containerWidth - table.getTotalSize() - 4) : header.getSize() - }} - > - { - header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext() - ) - } - { - header.column.getCanResize() && ( -
) - } -
-
) + minWidth: + header.index === columnDisplay.length - 1 && + containerWidth > table.getTotalSize() + ? header.getSize() + + (containerWidth - table.getTotalSize() - 4) + : header.getSize(), + }} + > + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + {header.column.getCanResize() && ( +
+ )} + + ); + })} + + ))} + + + {table.getRowModel().rows.map((row) => { + return ( + + ); + })} + + + + ); }; export default Table; -export type { ITable, ITableRow, TPlainObject } - -const Th: FC = ({ children = <>, className = "", style = {} }) => { - - return ( - - {children} - - ) -} - -export const Td: FC = ({ children, className = "", style = {} }) => { - return ( - - {children} - - ) -} - -type TPlainObject = { [K: string]: any } +export type { ITable, ITableRow, TPlainObject }; + +const Th: FC = ({ children = <>, className = '', style = {} }) => { + return ( + + {children} + + ); +}; + +export const Td: FC = ({ children, className = '', style = {} }) => { + return ( + + {children} + + ); +}; + +type TPlainObject = { [K: string]: any }; type ITable = { - /** - * Provide a unique id for the table - */ - name: string, - /** - * Array of data to be rendered in table - */ - data: Array, - /** - * Allow table columns to resize - */ - tableResizable: boolean, - /** - * Array of columns to be rendered, column should follow IColumn type - */ - columns: Array, - /** - * Component to format the column headings - */ - columnRenderer: (column: object | string) => string | JSX.Element, - /** - * Component to format the table cell - */ - cellRenderer: (cell: object) => string | JSX.Element, - /** - * Minimum width for the table component - */ - tableWidth: number, - /** - * Optional functionality for table
- * containerClassName : classname for table wrapper div - * minColumnSize : minimum column width (if not defined in columns object) - */ - options: ITableOptions -} + /** provide a unique id for the table */ + name: string; + + /** array of columns to be rendered, column should follow IColumn type */ + columns: Array; + + /** array of data to be rendered in table */ + data: Array; + + /** allow table columns to resize*/ + resizable: boolean; + + /** Component to format the column headings*/ + columnRenderer: (column: object | string) => string | JSX.Element; + + /** Component to format the table cell */ + cellRenderer: (cell: object) => string | JSX.Element; + + /** Minimum width for the table component*/ + width: number; + + /** table options */ + options: ITableOptions; +}; type ITableOptions = { - containerClassName?: string, - minColumnSize?: number -} + /** class name for table wrapper div */ + containerClassName?: string; + + /** minimum column width (if not defined in columns object) */ + minColumnSize?: number; +}; type IColumn = { - name: string, - displayName?: string, - width?: number, - minSize?:number, - maxSize?:number, - enableResizing?: boolean -} + name: string; + displayName?: string; + width?: number; + minSize?: number; + maxSize?: number; + enableResizing?: boolean; +}; type ITableRow = { - row: TPlainObject, - index?: number, - handleDrop: Function, - handleDrag: Function -} -type ITh = { children: ReactNode, className?: string, style?: TPlainObject } -type ITd = { children: ReactNode, className?: string, style?: TPlainObject } \ No newline at end of file + row: TPlainObject; + index?: number; + handleDrop: Function; + handleDrag: Function; +}; +type ITh = { children: ReactNode; className?: string; style?: TPlainObject }; +type ITd = { children: ReactNode; className?: string; style?: TPlainObject }; diff --git a/packages/ui-kit/src/components/table/table/TableData.tsx b/packages/ui-kit/src/components/table/table/TableData.tsx index beaedf1e4..aca20b63b 100644 --- a/packages/ui-kit/src/components/table/table/TableData.tsx +++ b/packages/ui-kit/src/components/table/table/TableData.tsx @@ -1,133 +1,143 @@ -import { Td, TPlainObject } from "./Table"; +import { Td, TPlainObject } from './Table'; import { useEffect, useState } from 'react'; export type Person = { - key: string, - value: string, - description: string, - popularPlace: string, - pincode: number -} + key: string; + value: string; + description: string; + popularPlace: string; + pincode: number; +}; export const defaultData: Person[] = [ { - key: "City 1", - value: "Ahmedabad", - description: "Ahmedabad, in western India, is the largest city in the state of Gujarat. ", - popularPlace: "Kankaria Lake", - pincode: 380001 + key: 'City 1', + value: 'Ahmedabad', + description: + 'Ahmedabad, in western India, is the largest city in the state of Gujarat. ', + popularPlace: 'Kankaria Lake', + pincode: 380001, }, { - key: "City 2", - value: "Surat", - description: "Surat is a large city beside the Tapi River in the west Indian state of Gujarat", - popularPlace: "Dumas Beach", - pincode: 395003 + key: 'City 2', + value: 'Surat', + description: + 'Surat is a large city beside the Tapi River in the west Indian state of Gujarat', + popularPlace: 'Dumas Beach', + pincode: 395003, }, { - key: "City 3", - value: "Mahemdavad", - description: "Mahemdavad is a town with municipality in the Kheda district in the Indian state of Gujarat", - popularPlace: "Siddhivinayak Temple", - pincode: 387130 + key: 'City 3', + value: 'Mahemdavad', + description: + 'Mahemdavad is a town with municipality in the Kheda district in the Indian state of Gujarat', + popularPlace: 'Siddhivinayak Temple', + pincode: 387130, }, ]; export function getData() { - return defaultData -}; + return defaultData; +} //For keeping column as static - provide minSize & width without resizing param export const columnDataForDisplay = [ { - name: "action", - displayName: " ", + name: 'action', + displayName: ' ', minSize: 64, - width: 64 + width: 64, }, { - name: "value", - displayName: "City", + name: 'value', + displayName: 'City', minSize: 145, enableResizing: true, }, { - name: "description", - displayName: "Description", + name: 'description', + displayName: 'Description', minSize: 145, enableResizing: true, }, { - name: "popularPlace", - displayName: "Location", + name: 'popularPlace', + displayName: 'Location', enableResizing: true, }, { - name: "pincode", + name: 'pincode', minSize: 60, - displayName: "Area Code", + displayName: 'Area Code', }, -] - +]; export const headerRow = { - description: "Description", + description: 'Description', disable: false, - key: "test", - type: "text", - value: "Value here" -} + key: 'test', + type: 'text', + value: 'Value here', +}; export const headerColumnDataForDisplay = [ { - name: "action", - displayName: " ", + name: 'action', + displayName: ' ', minSize: 64, - width: 64 + width: 64, }, { - name: "key", - displayName: "Key", + name: 'key', + displayName: 'Key', minSize: 145, enableResizing: true, }, { - name: "value", - displayName: "Value", + name: 'value', + displayName: 'Value', minSize: 145, enableResizing: true, }, { - name: "description", - displayName: "Description", - minSize: 145 - } -] + name: 'description', + displayName: 'Description', + minSize: 145, + }, +]; -export const TableColumnHeading = ({heading}: TPlainObject) => { - return <>{heading} -} +export const TableColumnHeading = ({ heading }: TPlainObject) => { + return <>{heading}; +}; export const TableInput = (props: any) => { - let { onChange, autoFocus, cell, rows } = props + let { onChange, autoFocus, cell, rows } = props; const [inputValue, setInputValue] = useState(cell.cellValue); - return - + className={ + ' h-[30px] relative overflow-hidden overflow-ellipsis whitespace-nowrap align-baseline' + } + > { - setInputValue(e.target.value);}} - onBlur={(e) => { - let updatedRow = Object.assign([],rows); - updatedRow[cell.rowIndex] = {...updatedRow[cell.rowIndex], [cell.columnId]: e.target.value} - onChange(updatedRow) + setInputValue(e.target.value); + }} + onBlur={(e) => { + let updatedRow = Object.assign([], rows); + updatedRow[cell.rowIndex] = { + ...updatedRow[cell.rowIndex], + [cell.columnId]: e.target.value, + }; + onChange(updatedRow); }} className="text-appForeground bg-appBackground h-[29px] w-full absolute top-0 left-0 !border-0 p-1 text-base overflow-ellipsis focus:!border-0" /> -} + ); +}; diff --git a/packages/ui-kit/src/components/table/table/TableDraggableRow.tsx b/packages/ui-kit/src/components/table/table/TableDraggableRow.tsx index d3d441878..c3ac90439 100644 --- a/packages/ui-kit/src/components/table/table/TableDraggableRow.tsx +++ b/packages/ui-kit/src/components/table/table/TableDraggableRow.tsx @@ -1,6 +1,6 @@ import { flexRender, Row } from '@tanstack/react-table'; import { FC, Fragment } from 'react'; -import { GrDrag } from "@react-icons/all-files/gr/GrDrag" +import { GrDrag } from '@react-icons/all-files/gr/GrDrag'; import { ITableRow, TPlainObject } from './Table'; const TableDraggableRow: FC = (props) => { @@ -23,7 +23,7 @@ const TableDraggableRow: FC = (props) => { onDrop={(e) => (e.preventDefault(), handleDrop(row.index))} onDragOver={(e) => e.preventDefault()} > - + ) : ( flexRender(cell.column.columnDef.cell, cell.getContext())