from typing import Optional from typing_extensions import Self from ...events import Handler, MermaidNodeClickEventArguments, handle_event from ..mixins.content_element import ContentElement class Mermaid(ContentElement, component='mermaid.js', esm={'nicegui-mermaid': 'dist'}): CONTENT_PROP = 'content' def __init__(self, content: str, config: Optional[dict] = None, *, on_node_click: Optional[Handler[MermaidNodeClickEventArguments]] = None, ) -> None: """Mermaid Diagrams Renders diagrams and charts written in the Markdown-inspired `Mermaid `_ language. The mermaid syntax can also be used inside Markdown elements by providing the extension string 'mermaid' to the ``ui.markdown`` element. The optional configuration dictionary is passed directly to mermaid before the first diagram is rendered. This can be used to set such options as ``{'securityLevel': 'loose', ...}`` - allow running JavaScript when a node is clicked ``{'logLevel': 'info', ...}`` - log debug info to the console Refer to the Mermaid documentation for the ``mermaid.initialize()`` method for a full list of options. **Note:** When using click handlers with ``securityLevel: 'loose'``, make sure to use unique node IDs across diagrams to avoid click events being bound to the wrong elements. :param content: the Mermaid content to be displayed :param config: configuration dictionary to be passed to ``mermaid.initialize()`` :param on_node_click: callback that is invoked when a node is clicked (*added in version 3.3.0*) """ super().__init__(content=content) self._props['config'] = config if on_node_click is not None: self.on_node_click(on_node_click) def on_node_click(self, callback: Handler[MermaidNodeClickEventArguments]) -> Self: """Add a callback to be invoked when a node is clicked.""" self.on('node_click', lambda e: handle_event(callback, MermaidNodeClickEventArguments( sender=self, client=self.client, node_id='-'.join(e.args.split('-')[1:-1]) # extract Node ID from HTML ID (--) ))) self._props['clickable'] = True return self def _handle_content_change(self, content: str) -> None: self._props[self.CONTENT_PROP] = content.strip() self.run_method('update', content.strip())