Custom Component: Material UI React Table

If you’re only doing static rendering (that is no interaction with the table and get back selected rows back to Streamlit) you can use components.html to run any HTML/JS code, so something like this is a good first start, maybe I’d use something like jinja2 or some string interpol to inject Python data into the HTML file :

This is a straight very rough copy of the CDN example project edited to include the Customized Table you mention in your OP. Not optimized for production !

app.py
import streamlit.components.v1 as components
import streamlit as st 

st.title("Hello Custom React Table")

with open('app.html') as f:
    data = f.read()
    components.html(data, height=800)
app.html
<!DOCTYPE html>
<html lang="en">

<head>
    <title>My page</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
    <script src="https://unpkg.com/react@latest/umd/react.development.js" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/react-dom@latest/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js"
        crossorigin="anonymous"></script>
    <script src="https://unpkg.com/babel-standalone@latest/babel.min.js" crossorigin="anonymous"></script>
    <!-- Fonts to support Material Design -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
    <!-- Icons to support Material Design -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
</head>

<body>
    <div id="root"></div>
    <script type="text/babel">
        const {
            Button,
            CssBaseline,
            makeStyles,
            Paper,
            Table,
            TableBody,
            TableCell,
            TableContainer,
            TableHead,
            TableRow,
            withStyles
        } = MaterialUI;


        const StyledTableCell = withStyles((theme) => ({
            head: {
                backgroundColor: theme.palette.common.black,
                color: theme.palette.common.white,
            },
            body: {
                fontSize: 14,
            },
        }))(TableCell);

        const StyledTableRow = withStyles((theme) => ({
            root: {
                '&:nth-of-type(odd)': {
                    backgroundColor: theme.palette.action.hover,
                },
            },
        }))(TableRow);

        function createData(name, calories, fat, carbs, protein) {
            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),
        ];

        const useStyles = makeStyles({
            table: {
                minWidth: 700,
            },
        });

        const CustomTable = () => {
            const classes = useStyles();

            return (
                <TableContainer component={Paper}>
                    <Table className={classes.table} aria-label="customized table">
                        <TableHead>
                            <TableRow>
                                <StyledTableCell>Dessert (100g serving)</StyledTableCell>
                                <StyledTableCell align="right">Calories</StyledTableCell>
                                <StyledTableCell align="right">Fat&nbsp;(g)</StyledTableCell>
                                <StyledTableCell align="right">Carbs&nbsp;(g)</StyledTableCell>
                                <StyledTableCell align="right">Protein&nbsp;(g)</StyledTableCell>
                            </TableRow>
                        </TableHead>
                        <TableBody>
                            {rows.map((row) => (
                                <StyledTableRow key={row.name}>
                                    <StyledTableCell component="th" scope="row">
                                        {row.name}
                                    </StyledTableCell>
                                    <StyledTableCell align="right">{row.calories}</StyledTableCell>
                                    <StyledTableCell align="right">{row.fat}</StyledTableCell>
                                    <StyledTableCell align="right">{row.carbs}</StyledTableCell>
                                    <StyledTableCell align="right">{row.protein}</StyledTableCell>
                                </StyledTableRow>
                            ))}
                        </TableBody>
                    </Table>
                </TableContainer>
            );
        }

        const App = () => {
            return (
                <CustomTable />
            );
        }

        ReactDOM.render(
            <div>
                <CssBaseline />
                <App />
            </div>,
            document.querySelector('#root'),
        );
    </script>
</body>

</html>

5 Likes