浏览代码

Merge pull request #1653 from zauberzeug/code

Introduce ui.code
Rodja Trappe 1 年之前
父节点
当前提交
a7f4ad4658

+ 35 - 0
nicegui/elements/code.py

@@ -0,0 +1,35 @@
+import asyncio
+from typing import Optional
+
+from ..element import Element
+from ..elements.button import Button as button
+from ..elements.markdown import Markdown as markdown
+from ..elements.markdown import remove_indentation
+from ..functions.javascript import run_javascript
+
+
+class Code(Element):
+
+    def __init__(self, content: str, *, language: Optional[str] = 'python') -> None:
+        """Code
+
+        This element displays a code block with syntax highlighting.
+
+        :param content: code to display
+        :param language: language of the code (default: "python")
+        """
+        super().__init__()
+        self._classes.append('nicegui-code')
+
+        self.content = remove_indentation(content)
+
+        with self:
+            self.markdown = markdown(f'```{language}\n{self.content}\n```').classes('overflow-auto')
+            self.copy_button = button(icon='content_copy', on_click=self.copy_to_clipboard) \
+                .props('round flat size=sm').classes('absolute right-2 top-2 opacity-20 hover:opacity-80')
+
+    async def copy_to_clipboard(self) -> None:
+        await run_javascript('navigator.clipboard.writeText(`' + self.content + '`)', respond=False)
+        self.copy_button.props('icon=check')
+        await asyncio.sleep(3.0)
+        self.copy_button.props('icon=content_copy')

+ 6 - 0
nicegui/static/nicegui.css

@@ -97,6 +97,12 @@ h6.q-timeline__title {
   font-size: 1.25rem;
   font-weight: 500;
 }
+.nicegui-code {
+  position: relative;
+  background-color: rgba(127, 127, 127, 0.1);
+  box-shadow: 0 0 0.5em rgba(127, 127, 127, 0.05);
+  border-radius: 0.25rem;
+}
 
 #popup {
   position: fixed;

+ 2 - 0
nicegui/ui.py

@@ -13,6 +13,7 @@ __all__ = [
     'chart',
     'chat_message',
     'checkbox',
+    'code',
     'color_input',
     'color_picker',
     'colors',
@@ -108,6 +109,7 @@ from .elements.carousel import CarouselSlide as carousel_slide
 from .elements.chart import Chart as chart
 from .elements.chat_message import ChatMessage as chat_message
 from .elements.checkbox import Checkbox as checkbox
+from .elements.code import Code as code
 from .elements.color_input import ColorInput as color_input
 from .elements.color_picker import ColorPicker as color_picker
 from .elements.colors import Colors as colors

+ 12 - 0
tests/test_code.py

@@ -0,0 +1,12 @@
+from nicegui import ui
+
+from .screen import Screen
+
+
+def test_code(screen: Screen):
+    ui.code('x = 42')
+
+    screen.open('/')
+    assert screen.find_by_class('n').text == 'x'
+    assert screen.find_by_class('o').text == '='
+    assert screen.find_by_class('mi').text == '42'

+ 1 - 0
website/documentation.py

@@ -143,6 +143,7 @@ def create_full() -> None:
     load_demo(ui.scene)
     load_demo(ui.tree)
     load_demo(ui.log)
+    load_demo(ui.code)
     load_demo(ui.json_editor)
 
     heading('Layout')

+ 11 - 0
website/more_documentation/code_documentation.py

@@ -0,0 +1,11 @@
+from nicegui import ui
+
+
+def main_demo() -> None:
+    ui.code('''
+        from nicegui import ui
+        
+        ui.label('Code inception!')
+            
+        ui.run()
+    ''').classes('w-full')