Skip to content

Commit

Permalink
onDisplayedRowsChange, small other type fixes (#44)
Browse files Browse the repository at this point in the history
* onDisplayedRowsChange, small other type fixes

* Update package.json

* Fix prop description
  • Loading branch information
jpfisher72 authored Oct 22, 2024
1 parent d80f5ae commit b85157f
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 34 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@weng-lab/psychscreen-ui-components",
"description": "Typescript and Material UI based components used for psychSCREEN",
"author": "SCREEN Team @ UMass Chan Medical School",
"version": "2.0.4",
"version": "2.0.5",
"license": "MIT",
"type": "module",
"typings": "dist/index.d.ts",
Expand Down Expand Up @@ -75,6 +75,5 @@
"extends": [
"plugin:storybook/recommended"
]
},
"packageManager": "[email protected]+sha512.2dc70be5fce9f66756d25b00a888f3ca66f86b502b76750e72ba54cec89da767b938c54124595e26f868825688e0fe3552c26c76a330673343057acadd5cfcf2"
}
}
59 changes: 47 additions & 12 deletions src/components/DataTable/DataTable.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { Meta, StoryObj } from '@storybook/react';
import { DataTable, DataTableColumn } from '../..';
import { DataTable, DataTableColumn, DataTableProps } from '../..';
import {
Box,
Button,
Expand All @@ -21,22 +21,24 @@ const meta = {
title: 'DataTable',
component: DataTable,
tags: ['autodocs'],
argTypes: {},
argTypes: {
},
parameters: {
controls: { expanded: true },
},
} satisfies Meta<typeof DataTable>;

export default meta;
type Story = StoryObj<typeof meta>;

type Row = {
index: number;
text: string;
color: string;
description: string;
};

export default meta;
type Story = StoryObj<DataTableProps<Row>>;


const FCCOLUMNS: DataTableColumn<Row>[] = [
{
header: 'Functional Column',
Expand Down Expand Up @@ -161,13 +163,13 @@ const ROWS: {index: number, text: string, color: string, description: string}[]

export const Default: Story = {
args: {
rows: ROWS,
columns: COLUMNS,
itemsPerPage: 4,
tableTitle: 'Table Title',
searchable: true,
hideHeader: false,
}
rows: ROWS,
columns: COLUMNS,
itemsPerPage: 4,
tableTitle: 'Table Title',
searchable: true,
hideHeader: false,
}
}

export const EmptyTable: Story = {
Expand Down Expand Up @@ -249,6 +251,39 @@ export const OnRowClick: Story = {
}
}

export const OnDisplayedRowsChange: Story = {
args: {
rows: ROWS,
columns: COLUMNS,
itemsPerPage: 4,
tableTitle: 'Table Title',
searchable: true,
},
render: (args) => {
const [page, setPage] = useState<number>()
const [rows, setRows] = useState<Row[]>()

const handleDisplayedRowsChange = (newPage: number, displayedRows: Row[]) => {
setPage(newPage)
setRows(displayedRows)
}

return (
<div>
<DataTable
{...args}
onDisplayedRowsChange={handleDisplayedRowsChange}
/>
<Typography>Page: {page}</Typography>
<Typography>Rows: </Typography>
{rows?.map(row =>
<Typography>{JSON.stringify(row)}</Typography>
)}
</div>
)
}
}

export const HeaderColored: Story = {
args: {
rows: ROWS,
Expand Down
26 changes: 15 additions & 11 deletions src/components/DataTable/datatable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,16 @@ const boxStyle = {
p: 4,
};

// function DataTable<T>(props: DataTableProps<T>): React.ReactElement<DataTableProps<T>> {
const DataTable: React.FC<DataTableProps<any>> = (
props: DataTableProps<any>
const DataTable = <T,>(
props: DataTableProps<T>
) => {
// Sets default rows to display at 5 if unspecified
const itemsPerPage = props.itemsPerPage || 5;
const [page, setPage] = useState(props.page || 0);
const [rowsPerPage, setRowsPerPage] = useState(itemsPerPage);

const handleChangePage = (_: any, newPage: number) => {
setPage(newPage);
const handleChangePage = (page: number) => {
setPage(page);
};

const handleChangeRowsPerPage = (
Expand All @@ -129,7 +128,7 @@ const DataTable: React.FC<DataTableProps<any>> = (
return cells;
}

function highlightCheck(row: {}): boolean {
function highlightCheck(row: T): boolean {
var found = false;
if (Array.isArray(props.highlighted)) {
props.highlighted.forEach((highlight) => {
Expand All @@ -150,7 +149,7 @@ const DataTable: React.FC<DataTableProps<any>> = (
);

const [state, dispatch] = useReducer<
Reducer<DataTableState<any>, DataTableAction<any>>
Reducer<DataTableState<T>, DataTableAction<T>>
>(reducer, {
sort: {
column: props.sortColumn || 0,
Expand Down Expand Up @@ -189,7 +188,7 @@ const DataTable: React.FC<DataTableProps<any>> = (
);

const sort = useCallback(
(rows: any[]): any[] => {
(rows: T[]): T[] => {
/* look for a user-defined sort function for this column or fall back
to generic string/number sorting */
const sortf =
Expand Down Expand Up @@ -220,6 +219,12 @@ const DataTable: React.FC<DataTableProps<any>> = (
[displayRows, sort, state.filter, props.rows, state.sort, props.search]
);

const rowsOnCurrentPage = useMemo(() => {
const newRowsOnPage = displayedRows.slice(page * rowsPerPage, (page + 1) * rowsPerPage);
props.onDisplayedRowsChange?.(page, newRowsOnPage)
return newRowsOnPage
}, [displayedRows, page, rowsPerPage])

const download = useCallback(() => {
const data =
state.columns.map((col) => col.header).join('\t') +
Expand Down Expand Up @@ -423,8 +428,7 @@ const DataTable: React.FC<DataTableProps<any>> = (
{handleEmptyTable(props.columns.length)}
</TableRow>
) : (
displayedRows
.slice(page * rowsPerPage, (page + 1) * rowsPerPage)
rowsOnCurrentPage
.map((row, i) => (
<TableRow
// Check that there's a row to select, it's the right one, and either none have been highlighted or it's the correct one
Expand Down Expand Up @@ -522,7 +526,7 @@ const DataTable: React.FC<DataTableProps<any>> = (
count={displayedRows.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onPageChange={(_, page) => handleChangePage(page)}
onRowsPerPageChange={handleChangeRowsPerPage}
showFirstButton={props.dense ? false : true}
showLastButton={props.dense ? false : true}
Expand Down
15 changes: 9 additions & 6 deletions src/components/DataTable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ type HEX = `#${string}` | `# ${string}`;

export type DataTableProps<T> = {
columns: DataTableColumn<T>[]
rows: T[]
itemsPerPage?: number
hidePageMenu?: boolean
tableTitle?: string
selectable?: boolean
searchable?: boolean
search?: string
rows: T[]
emptyText?: string
sortColumn?: number
sortDescending?: boolean
Expand Down Expand Up @@ -55,10 +55,13 @@ export type DataTableProps<T> = {
* Importantly, currently this only supports highlighting rows with the same order
* of key/value pairs. Matching but out-of-order row objects will not be highlighted.
*/
highlighted?: {} | {}[]
highlighted?: T | T[]

/**
* Callback triggered whenever the displayed rows are changed. Will trigger on first load of initial rows.
*/
onDisplayedRowsChange?: (newPage: number, displayedRows: T[]) => void

setPage?: (page: number) => void
rowLink?: (row: T, index: number) => string
onRowClick?: (row: T, i: number) => void

/**
Expand All @@ -74,9 +77,9 @@ export type DataTableProps<T> = {
* @param cellColIndex The index of the cell's column as it's currently displayed
*/

onCellMouseEnter?: (cellValue: T, cellRowIndex: number, cellColIndex: number) => void
onCellMouseEnter?: (cellValue: string | number, cellRowIndex: number, cellColIndex: number) => void

onCellMouseLeave?: () => void

}

export type DataTableState<T> = {
Expand Down

0 comments on commit b85157f

Please sign in to comment.