This ought to be improvable: I struggled with including libraries and getting this to display.
Here is the current code:
class ExcalidrawPane(pn.viewable.Viewer):
def __init__(self, width=850, height=600, url=None):
"""
Initialize the ExcalidrawPane instance.
Args:
width (int): Width of the iframe pane.
height (int): Height of the iframe pane.
url (str): URL for the Excalidraw instance. Defaults to an example URL.
"""
self.width = width
self.height = height
self.url = url or "https://excalidraw.com/#room=example,viewModeEnabled=true,zoom=100%,undo=true,redo=true"
def generate_iframe(self):
return f"""
<iframe src="{self.url}"
style="width: {self.width}px; height: {self.height}px; border: none;"
sandbox="allow-scripts allow-same-origin allow-popups allow-top-navigation">
</iframe>
"""
def __panel__(self):
"""
The method used by Viewer to render the object as a Panel layout.
Returns:
pn.Column: The viewable layout containing the iframe.
"""
excalidraw_pane = pn.pane.HTML(self.generate_iframe(), width=self.width, height=self.height)
return pn.Column( excalidraw_pane, width=self.width, height=self.height, )
excalidraw_view = ExcalidrawPane(width=750, height=500)
layout = pn.Row(
excalidraw_view,
width=excalidraw_view.width+5, height=excalidraw_view.height+5,
sizing_mode="fixed",
)
layout.servable()