Converting from AnyWidget to Panel
This guide addresses how to convert AnyWidget widgets to custom JSComponent or ReactComponent widgets.
Please note that AnyWidget widgets are ipywidgets and can be used directly in Panel via the IPyWidgets pane and the Traitlets @observe API without a conversion. We recommend trying this option first. If it does not work for your use case, please consider contributing to the existing AnyWidget before converting it to a Panel widget.
Some reasons you might still want to convert an AnyWidget to a custom Panel widget are:
Familiar and Optimized API: This enables you and your users to use the familiar
Paramparameter API for which Panel is optimized.Customization: You might want to use the
AnyWidgetas a starting point and customize it to your exact needs.Efficiency: You avoid loading
AnyWidget/ipywidgetsJavaScript libraries can add significant overhead.
Conversion Steps
The high-level steps needed for converting AnyWidgets components to Panel components are described in the section below.
Convert Python Code
Step 1: Base Class Conversion
Convert from the AnyWidget base class to the Panel JSComponent base class. If the _esm script is based on React, use the ReactComponent.
Step 2: Attribute Conversion
Convert from AnyWidget's Traitlets based attributes to Panel's Param based parameters.
Convert the attributes below:
AnyWidget | Comment | Panel | Comment |
|---|---|---|---|
_esm | JavaScript string or Path | _esm | JavaScript string or Path |
_css | CSS string or Path | _stylesheets | List of CSS strings or Paths |
| NA | Not Available | _importmap | import map |
Convert JavaScript Code
Step 3: Export Conversion
Convert the functions below:
AnyWidget | Comment | JSComponent | Comment |
|---|---|---|---|
initialize | Has access to model.Can return end of life callback. | NA | Not Available |
render | Has access to model and el.Can return end of life callback. | render | Has access to model, children, el, and view.Can return an html element to be appended to el or append to el manually. |
In the _esm script, either use the default export or named exports.
Their methods are also different reflecting differences between Traitlets and Panel/ Bokeh JavaScript models:
| AnyWidget | Panel/ Bokeh |
|---|---|
model.get('some_value') | model.some_value |
model.save('some_value', 1)model.save_changes() | model.some_value = 1 |
model.on("change:some_value", () => {...}) | model.on('change: some_value', () => {...})) |
Convert React Code
Step 4: Drop JavaScript Tooling
Drop the local JavaScript tooling required by AnyWidget. Panel replaces this with automatic transpiling in the browser by Sucrase.
Step 5: Convert useModelState to state
The ReactComponent _esm script works similarly to the JSComponent _esm script with the following differences:
AnyWidget | Comment | ReactComponent | Comment |
|---|---|---|---|
render | Can use imports from react and @anywidget/react modules like useState and useModelState | render | Can use hooks like useState from the React objectHas access to model state. |
Examples
Basic CounterWidget
AnyWidget CounterWidget
Panel JS CounterWidget
:::{note}
With Panel you may replace the lines export function render({ model }) and return btn with the lines export function render({ model, el }) and el.appendChild(btn), if you want to minimize the number of changes.
:::
Panel React CounterWidget
Mario Button
Check out our Custom Components Tutorial to see a converted version of the ipymario widget.
References
Tutorials
How-To Guides
Reference Guides
With these skills, you are now equipped to pioneer and push the boundaries of what can be achieved with Panel. Happy coding!
