Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docs] Add TypeScript demos for Simple and Spanning Table #14985

Merged
merged 7 commits into from
Mar 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions docs/src/pages/demos/tables/SimpleTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ const styles = theme => ({
},
});

let id = 0;
function createData(name, calories, fat, carbs, protein) {
id += 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good change. The previous approach resulted in re-mounting of the TableRow on every render call of SimpleTable.

return { id, name, calories, fat, carbs, protein };
return { name, calories, fat, carbs, protein };
}

const rows = [
Expand Down Expand Up @@ -50,7 +48,7 @@ function SimpleTable(props) {
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow key={row.id}>
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
Expand Down
74 changes: 74 additions & 0 deletions docs/src/pages/demos/tables/SimpleTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';
import PropTypes from 'prop-types';
import { createStyles, Theme, withStyles, WithStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';

const styles = (theme: Theme) =>
createStyles({
root: {
width: '100%',
marginTop: theme.spacing(3),
overflowX: 'auto',
},
table: {
minWidth: 650,
},
});

function createData(name: string, calories: number, fat: number, carbs: number, protein: number) {
return { name, calories, fat, carbs, protein };
}

const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
];

export interface SimpleTableProps extends WithStyles<typeof styles> {}

function SimpleTable(props: SimpleTableProps) {
const { classes } = props;

return (
<Paper className={classes.root}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
);
}

SimpleTable.propTypes = {
classes: PropTypes.object.isRequired,
} as any;

export default withStyles(styles)(SimpleTable);
15 changes: 8 additions & 7 deletions docs/src/pages/demos/tables/SpanningTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ function priceRow(qty, unit) {
return qty * unit;
}

function createRow(id, desc, qty, unit) {
function createRow(desc, qty, unit) {
const price = priceRow(qty, unit);
return { id, desc, qty, unit, price };
return { desc, qty, unit, price };
}

function subtotal(items) {
return items.map(({ price }) => price).reduce((sum, i) => sum + i, 0);
}

const rows = [
['Paperclips (Box)', 100, 1.15],
['Paper (Case)', 10, 45.99],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what to do with spread operator in SpanningTable.tsx because TypeScript considers the spread operator incompatible with the function signature of createRow.

Source:
Microsoft/TypeScript#4130

This was an issue with type widening. TypeScript inferred a nested array (string | number)[][] instead of an array of tuples [string, number, number][]. With TypeScript 3.4 we could've written ['Paper (Case)', 10, 45.99] as const to fix this issue.

['Waste Basket', 2, 17.99],
].map((row, id) => createRow(id, ...row));
createRow('Paperclips (Box)', 100, 1.15),
createRow('Paper (Case)', 10, 45.99),
createRow('Waste Basket', 2, 17.99),
];

const invoiceSubtotal = subtotal(rows);
const invoiceTaxes = TAX_RATE * invoiceSubtotal;
Expand All @@ -63,13 +63,14 @@ function SpanningTable(props) {
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow key={row.id}>
<TableRow key={row.desc}>
<TableCell>{row.desc}</TableCell>
<TableCell align="right">{row.qty}</TableCell>
<TableCell align="right">{row.unit}</TableCell>
<TableCell align="right">{ccyFormat(row.price)}</TableCell>
</TableRow>
))}

<TableRow>
<TableCell rowSpan={3} />
<TableCell colSpan={2}>Subtotal</TableCell>
Expand Down
107 changes: 107 additions & 0 deletions docs/src/pages/demos/tables/SpanningTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react';
import PropTypes from 'prop-types';
import { createStyles, Theme, withStyles, WithStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';

const TAX_RATE = 0.07;

const styles = (theme: Theme) =>
createStyles({
root: {
width: '100%',
marginTop: theme.spacing(3),
overflowX: 'auto',
},
table: {
minWidth: 700,
},
});

function ccyFormat(num: number) {
return `${num.toFixed(2)}`;
}

function priceRow(qty: number, unit: number) {
return qty * unit;
}

function createRow(desc: string, qty: number, unit: number) {
const price = priceRow(qty, unit);
return { desc, qty, unit, price };
}

interface Row {
desc: string;
qty: number;
unit: number;
price: number;
}

function subtotal(items: Row[]) {
return items.map(({ price }) => price).reduce((sum, i) => sum + i, 0);
}

const rows = [
createRow('Paperclips (Box)', 100, 1.15),
createRow('Paper (Case)', 10, 45.99),
createRow('Waste Basket', 2, 17.99),
];

const invoiceSubtotal = subtotal(rows);
const invoiceTaxes = TAX_RATE * invoiceSubtotal;
const invoiceTotal = invoiceTaxes + invoiceSubtotal;

export interface SpanningTableProps extends WithStyles<typeof styles> {}

function SpanningTable(props: SpanningTableProps) {
const { classes } = props;
return (
<Paper className={classes.root}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>Desc</TableCell>
<TableCell align="right">Qty.</TableCell>
<TableCell align="right">@</TableCell>
<TableCell align="right">Price</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow key={row.desc}>
<TableCell>{row.desc}</TableCell>
<TableCell align="right">{row.qty}</TableCell>
<TableCell align="right">{row.unit}</TableCell>
<TableCell align="right">{ccyFormat(row.price)}</TableCell>
</TableRow>
))}
<TableRow>
<TableCell rowSpan={3} />
<TableCell colSpan={2}>Subtotal</TableCell>
<TableCell align="right">{ccyFormat(invoiceSubtotal)}</TableCell>
</TableRow>
<TableRow>
<TableCell>Tax</TableCell>
<TableCell align="right">{`${(TAX_RATE * 100).toFixed(0)} %`}</TableCell>
<TableCell align="right">{ccyFormat(invoiceTaxes)}</TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={2}>Total</TableCell>
<TableCell align="right">{ccyFormat(invoiceTotal)}</TableCell>
</TableRow>
</TableBody>
</Table>
</Paper>
);
}

SpanningTable.propTypes = {
classes: PropTypes.object.isRequired,
} as any;

export default withStyles(styles)(SpanningTable);