HomeDashboard/.venv/lib/python3.12/site-packages/nicegui/elements/code.py
2026-01-03 14:54:18 +01:00

53 lines
2.0 KiB
Python

import asyncio
import time
from typing import Optional
from .button import Button as button
from .markdown import Markdown as markdown
from .markdown import remove_indentation
from .mixins.content_element import ContentElement
from .timer import Timer as timer
class Code(ContentElement, component='code.js', default_classes='nicegui-code'):
def __init__(self, content: str = '', *, language: Optional[str] = 'python') -> None:
"""Code
This element displays a code block with syntax highlighting.
In secure environments (HTTPS or localhost), a copy button is displayed to copy the code to the clipboard.
:param content: code to display
:param language: language of the code (default: "python")
"""
super().__init__(content=remove_indentation(content))
with self:
self.markdown = markdown().classes('overflow-auto h-full') \
.bind_content_from(self, 'content', lambda content: f'```{language}\n{content}\n```')
self.copy_button = button(icon='content_copy', on_click=self.show_checkmark) \
.props('round flat size=sm').classes('absolute right-2 top-2 opacity-20 hover:opacity-80') \
.on('click', js_handler=f'() => navigator.clipboard.writeText(getElement("{self.id}").content)')
self._props['content'] = self.content
self._last_scroll: float = 0.0
self.markdown.on('scroll', self._handle_scroll)
with self:
timer(0.1, self._update_copy_button)
async def show_checkmark(self) -> None:
"""Show a checkmark icon for 3 seconds."""
self.copy_button.props('icon=check')
await asyncio.sleep(3.0)
self.copy_button.props('icon=content_copy')
def _handle_scroll(self) -> None:
self._last_scroll = time.time()
def _update_copy_button(self) -> None:
self.copy_button.set_visibility(time.time() > self._last_scroll + 1.0)
def _handle_content_change(self, content: str) -> None:
self._props['content'] = content