Wrapping Material UI components#
Note
The MaterialBase
component is defined before the call to pn.extension
to allow us to load the _extension_name
and thereby initialize the required JS and CSS resources. Ordinarily the component would be defined in an external module.
import param
import panel as pn
from panel.custom import ReactComponent
class MaterialComponent(ReactComponent):
_importmap = {
"imports": {
"@mui/material/": "https://esm.sh/@mui/material@5.16.7/",
}
}
pn.extension(template='material')
This example demonstrates how to wrap Material UI components using ReactComponent
.
class Button(MaterialComponent):
disabled = param.Boolean(default=False)
label = param.String(default='')
variant = param.Selector(objects=["contained", "outlined", "text"])
_esm = """
import Button from '@mui/material/Button';
export function render({ model }) {
const [label] = model.useState("label")
const [variant] = model.useState("variant")
const [disabled] = model.useState("disabled")
return (
<Button disabled={disabled} variant={variant}>{label || 'Click me!'}</Button>
)
}
"""
class Rating(MaterialComponent):
value = param.Number(default=0, bounds=(0, 5))
_esm = """
import Rating from '@mui/material/Rating'
export function render({model}) {
const [value, setValue] = model.useState("value")
return (
<Rating
value={value}
onChange={(event, newValue) => setValue(newValue) }
/>
)
}
"""
class DiscreteSlider(MaterialComponent):
marks = param.List(default=[
{'value': 0, 'label': '0°C'},
{'value': 20, 'label': '20°C'},
{'value': 37, 'label': '37°C'},
{'value': 100, 'label': '100°C'},
])
value = param.Number(default=20)
_esm = """
import Box from '@mui/material/Box';
import Slider from '@mui/material/Slider';
export function render({ model }) {
const [value, setValue] = model.useState("value")
const [marks] = model.useState("marks")
return (
<Box sx={{ width: 300 }}>
<Slider
aria-label="Restricted values"
defaultValue={value}
marks={marks}
onChange={(e) => setValue(e.target.value)}
step={null}
valueLabelDisplay="auto"
/>
</Box>
);
}
"""
button = Button()
rating = Rating(value=3)
slider = DiscreteSlider()
pn.Row(
pn.Column(button.controls(['disabled', 'label', 'variant']), button),
pn.Column(rating.controls(['value']), rating),
pn.Column(slider.controls(['value']), slider),
).servable()