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 (g)</StyledTableCell>
<StyledTableCell align="right">Carbs (g)</StyledTableCell>
<StyledTableCell align="right">Protein (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>