Created
February 23, 2021 15:15
-
-
Save andyshora/d82f9e832ce071afaf04903603ba1981 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react" | |
import styled from "styled-components" | |
import { makeStyles } from "@material-ui/core/styles" | |
import { Table, TableBody, TablePagination } from "@material-ui/core" | |
import { animated, interpolate, Trail } from "react-spring/renderprops" | |
import Stars from "../Stars" | |
import { | |
StyledTableCell, | |
StyledTableRow, | |
SortableTableHead | |
} from "./TableParts" | |
const NumericValue = styled.span` | |
font-family: "Courier New", Courier, "Lucida Sans Typewriter"; | |
` | |
function descendingComparator<T>(a: T, b: T, orderBy: keyof T) { | |
if (b[orderBy] < a[orderBy]) { | |
return -1 | |
} | |
if (b[orderBy] > a[orderBy]) { | |
return 1 | |
} | |
return 0 | |
} | |
type Order = "asc" | "desc" | |
function getComparator<Key extends keyof any>( | |
order: Order, | |
orderBy: Key | |
): ( | |
a: { [key in Key]: number | string }, | |
b: { [key in Key]: number | string } | |
) => number { | |
return order === "desc" | |
? (a, b) => descendingComparator(a, b, orderBy) | |
: (a, b) => -descendingComparator(a, b, orderBy) | |
} | |
function stableSort<T>(array: T[], comparator: (a: T, b: T) => number) { | |
const stabilizedThis = array.map((el, index) => [el, index] as [T, number]) | |
stabilizedThis.sort((a, b) => { | |
const order = comparator(a[0], b[0]) | |
if (order !== 0) return order | |
return a[1] - b[1] | |
}) | |
return stabilizedThis.map(el => el[0]) | |
} | |
function createData( | |
name: string, | |
rating: number, | |
fat: number, | |
carbs: number, | |
protein: number | |
) { | |
return { name, rating, fat, carbs, protein } | |
} | |
const rows = [ | |
createData("Frozen yoghurt", 2, 6.0, 24, 4.0), | |
createData("Ice cream sandwich", 4, 9.0, 37, 4.3), | |
createData("Eclair", 5, 16.0, 24, 6.0), | |
createData("Cupcake", 1, 3.7, 67, 4.3), | |
createData("Gingerbread", 5, 16.0, 49, 3.9), | |
createData("Jam Tart", 3, 16.0, 49, 3.9) | |
] | |
const useStyles = makeStyles({ | |
table: { | |
minWidth: 700 | |
} | |
}) | |
const headCells = [ | |
{ | |
id: "name", | |
numeric: false, | |
label: "Dessert (100g serving)" | |
}, | |
{ id: "rating", numeric: true, align: "left", label: "Rating" }, | |
{ id: "fat", numeric: true, label: "Fat (g)" }, | |
{ id: "carbs", numeric: true, label: "Carbs (g)" }, | |
{ id: "protein", numeric: true, label: "Protein (g)" } | |
] | |
const AnimatedRow = animated(StyledTableRow) | |
export default function SortableTableExample() { | |
const classes = useStyles() | |
const [order, setOrder] = React.useState<Order>("asc") | |
const [orderBy, setOrderBy] = React.useState<string>("rating") | |
const [page, setPage] = React.useState(0) | |
const [dense, setDense] = React.useState(false) | |
const [rowsPerPage, setRowsPerPage] = React.useState(50) | |
const handleRequestSort = ( | |
event: React.MouseEvent<unknown>, | |
property: string | |
) => { | |
const isAsc = orderBy === property && order === "asc" | |
setOrder(isAsc ? "desc" : "asc") | |
setOrderBy(property) | |
} | |
const handleChangePage = (event: unknown, newPage: number) => { | |
setPage(newPage) | |
} | |
return ( | |
<div> | |
<Table className={classes.table} aria-label="customized table"> | |
<SortableTableHead | |
classes={classes} | |
headCells={headCells} | |
order={order} | |
orderBy={orderBy} | |
onRequestSort={handleRequestSort} | |
rowCount={rows.length} | |
/> | |
<TableBody> | |
<Trail | |
native | |
items={stableSort(rows, getComparator(order, orderBy)).slice( | |
page * rowsPerPage, | |
page * rowsPerPage + rowsPerPage | |
)} | |
keys={item => item.name} | |
from={{ opacity: 0, y: -40 }} | |
to={{ opacity: 1, y: 0 }} | |
> | |
{row => ({ opacity, y }) => ( | |
<AnimatedRow | |
style={{ | |
transform: interpolate([y], y => `translate3d(0, ${y}%, 0)`), | |
opacity | |
}} | |
hover | |
role="checkbox" | |
tabIndex={-1} | |
key={row.name} | |
> | |
<StyledTableCell component="th" scope="row"> | |
{row.name} | |
</StyledTableCell> | |
<StyledTableCell> | |
<Stars max={5} value={row.rating} /> | |
</StyledTableCell> | |
<StyledTableCell align="right"> | |
<NumericValue>{row.fat}</NumericValue> | |
</StyledTableCell> | |
<StyledTableCell align="right"> | |
<NumericValue>{row.carbs}</NumericValue> | |
</StyledTableCell> | |
<StyledTableCell align="right"> | |
<NumericValue>{row.protein}</NumericValue> | |
</StyledTableCell> | |
</AnimatedRow> | |
)} | |
</Trail> | |
</TableBody> | |
</Table> | |
<TablePagination | |
rowsPerPageOptions={[25, 50, 100, 200]} | |
component="div" | |
count={rows.length} | |
rowsPerPage={rowsPerPage} | |
page={page} | |
onChangePage={handleChangePage} | |
onChangeRowsPerPage={handleChangeRowsPerPage} | |
/> | |
</div> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment