|
@@ -7,7 +7,7 @@ from pygments.formatters import HtmlFormatter
|
|
|
from nicegui import Client, ui
|
|
|
from website import demo_card, reference
|
|
|
from website.constants import ACCENT_COLOR, HEADER_HEIGHT, STATIC
|
|
|
-from website.example import bash_window, python_window
|
|
|
+from website.example import bash_window, browser_window, python_window
|
|
|
|
|
|
ui.add_static_files('/favicon', Path(__file__).parent / 'website' / 'favicon')
|
|
|
|
|
@@ -72,14 +72,16 @@ def add_header() -> None:
|
|
|
with ui.header() \
|
|
|
.classes('items-center duration-200 px-4', remove='q-pa-md') \
|
|
|
.style('box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1)'):
|
|
|
- ui.html((STATIC / 'happy_face.svg').read_text()).classes('w-8 stroke-white')
|
|
|
- with ui.link(target=index_page):
|
|
|
+ with ui.link(target=index_page).classes('row gap-4 items-center'):
|
|
|
+ ui.html((STATIC / 'happy_face.svg').read_text()).classes('w-8 stroke-white')
|
|
|
ui.html((STATIC / 'nicegui_word.svg').read_text()).classes('w-24')
|
|
|
with ui.row().classes('items-center ml-auto'):
|
|
|
ui.link('Features', '/#features').classes(replace='text-lg text-white')
|
|
|
ui.link('Installation', '/#installation').classes(replace='text-lg text-white')
|
|
|
ui.link('Examples', '/#examples').classes(replace='text-lg text-white')
|
|
|
ui.link('API Reference', reference_page).classes(replace='text-lg text-white')
|
|
|
+ ui.link('Demos', '/#demos').classes(replace='text-lg text-white')
|
|
|
+ ui.link('Why?', '/#why').classes(replace='text-lg text-white')
|
|
|
with ui.link(target='https://github.com/zauberzeug/nicegui/'):
|
|
|
ui.html((STATIC / 'github.svg').read_text()).classes('fill-white scale-125 m-1')
|
|
|
|
|
@@ -97,23 +99,29 @@ async def index_page(client: Client):
|
|
|
with ui.column().classes('gap-8'):
|
|
|
ui.html('Meet the <em>NiceGUI</em>.') \
|
|
|
.style('font-size: 400%; line-height: 0.9; font-weight: 500')
|
|
|
- ui.markdown('Your easy-to-use Python framework to create\n\nuser interfaces which show up in the browser.') \
|
|
|
+ ui.markdown('And let any browser be the frontend\n\nof your Python code.') \
|
|
|
.style('font-size: 200%; line-height: 0.9')
|
|
|
+ with ui.column().classes('q-mt-md'):
|
|
|
+ ui.icon('keyboard_arrow_down').classes('text-4xl text-grey-5').style('margin: 0 0 -1.4em 0.32em')
|
|
|
+ ui.icon('keyboard_arrow_down').classes('text-6xl text-black')
|
|
|
+ ui.icon('keyboard_arrow_down').classes('text-4xl text-grey-5').style('margin: -1.3em 0 0 0.32em')
|
|
|
|
|
|
with ui.row() \
|
|
|
.classes('w-full h-screen q-pa-md items-center gap-28 p-32 no-wrap') \
|
|
|
.style(f'background: {ACCENT_COLOR}'):
|
|
|
with ui.column().classes('gap-6'):
|
|
|
- ui.markdown('Create buttons, dialogs, markdown,\n\n3D scenes, plots and much more at ease.') \
|
|
|
+ ui.markdown('Interact with Python through buttons, dialogs, 3D scenes, plots and much more.') \
|
|
|
.style('font-size: 300%; color: white; line-height: 0.9; font-weight: 500').classes('mb-4')
|
|
|
ui.label('''
|
|
|
- It is great for micro web apps, dashboards, robotics projects, smart home solutions
|
|
|
- and similar use cases. You can also use it in development, for example when
|
|
|
- tweaking/configuring a machine learning algorithm or tuning motor controllers.
|
|
|
+ NiceGUI handles all the web development details for you.
|
|
|
+ So you can focus on writing Python code.
|
|
|
+ Anything from short scripts and dashboards to full robotics projects, IoT solutions,
|
|
|
+ smart home automations and machine learning projects can benefit from having all code in one place.
|
|
|
+
|
|
|
''').style('font-size: 150%; color: white').classes('leading-tight')
|
|
|
with ui.row().style('font-size: 150%; color: white').classes('leading-tight gap-2'):
|
|
|
ui.html('''
|
|
|
- NiceGUI is available as
|
|
|
+ Available as
|
|
|
<a href="https://pypi.org/project/nicegui/"><strong>PyPI package</strong><span class="material-icons">north_east</span></a>,
|
|
|
<a href="https://hub.docker.com/r/zauberzeug/nicegui"><strong>Docker image</strong><span class="material-icons">north_east</span></a> and on
|
|
|
<a href="https://github.com/zauberzeug/nicegui"><strong>GitHub</strong><span class="material-icons">north_east</span></a>.
|
|
@@ -122,46 +130,63 @@ async def index_page(client: Client):
|
|
|
demo_card.create()
|
|
|
|
|
|
ui.link_target('features').style(f'position: relative; top: -{HEADER_HEIGHT}')
|
|
|
- with ui.column().classes('w-full q-pa-xl'):
|
|
|
+ with ui.column().classes('w-full q-pa-xl q-mb-xl'):
|
|
|
ui.label('Features').classes('text-bold text-lg')
|
|
|
- ui.html('What has <em>NiceGUI</em> to offer?') \
|
|
|
+ ui.html('Code <em>nicely</em>') \
|
|
|
.style('font-size: 300%; font-weight: 500; margin-top: -20px')
|
|
|
- with ui.row().classes('w-full no-wrap text-lg leading-tight justify-between'):
|
|
|
- with ui.column().classes('gap-1'):
|
|
|
- ui.label('User Interface').classes('text-bold mb-4')
|
|
|
- ui.markdown('- common elements like label, button, checkbox, switch, slider, input, ...')
|
|
|
- ui.markdown('- page layout with navigation bars, tabs, panels, ...')
|
|
|
- ui.markdown('- grouping with rows, columns, cards and dialogs')
|
|
|
- ui.markdown('- HTML and markdown elements')
|
|
|
- ui.markdown('- high-level elements like charts, tables, trees, 3D scenes, joystick, ...')
|
|
|
- ui.markdown('- built-in timer to refresh data in intervals')
|
|
|
+ with ui.row().classes('w-full no-wrap text-lg leading-tight justify-between q-mb-xl'):
|
|
|
+ with ui.column().classes('gap-1 col-3'):
|
|
|
+ ui.icon('swap_horiz').classes('text-5xl q-mb-md text-primary opacity-80')
|
|
|
+ ui.label('Interaction').classes('text-bold mb-4')
|
|
|
+ ui.markdown('- buttons, switches, slider, input, ...')
|
|
|
ui.markdown('- notifications, dialogs and menus')
|
|
|
ui.markdown('- keyboard input')
|
|
|
- with ui.column().classes('gap-1'):
|
|
|
- ui.label('Under the hood').classes('text-bold mb-4')
|
|
|
- ui.markdown('- browser-based graphical user interface')
|
|
|
- ui.markdown('- based on FastAPI and Uvicorn')
|
|
|
- ui.markdown('- live-cycle events and session data')
|
|
|
- ui.markdown('- customizable page layout and colors')
|
|
|
- with ui.column().classes('gap-1'):
|
|
|
- ui.label('Development').classes('text-bold mb-4')
|
|
|
+ ui.markdown('- on-screen joystick')
|
|
|
+ with ui.column().classes('gap-1 col-3'):
|
|
|
+ ui.icon('space_dashboard').classes('text-5xl q-mb-md text-primary opacity-80')
|
|
|
+ ui.label('Layout').classes('text-bold mb-4')
|
|
|
+ ui.markdown('- navigation bars, tabs, panels, ...')
|
|
|
+ ui.markdown('- grouping with rows, columns and cards')
|
|
|
+ ui.markdown('- HTML and markdown elements')
|
|
|
+ ui.markdown('- flex layout by default')
|
|
|
+ with ui.column().classes('gap-1 col-3'):
|
|
|
+ ui.icon('insights').classes('text-5xl q-mb-md text-primary')
|
|
|
+ ui.label('Visualization').classes('text-bold mb-4')
|
|
|
+ ui.markdown('- charts, diagrams and tables')
|
|
|
+ ui.markdown('- 3D scenes')
|
|
|
+ ui.markdown('- progress bars')
|
|
|
+ ui.markdown('- built-in timer for data refresh')
|
|
|
+ with ui.row().classes('w-full no-wrap text-lg leading-tight justify-between'):
|
|
|
+ with ui.column().classes('gap-1 col-3'):
|
|
|
+ ui.icon('brush').classes('text-5xl q-mb-xs text-primary opacity-80')
|
|
|
+ ui.label('Styling').classes('text-bold mb-4')
|
|
|
+ ui.markdown('- customizable color themes')
|
|
|
+ ui.markdown('- add custom css and classes')
|
|
|
+ ui.markdown('- modern look with material design')
|
|
|
+ with ui.column().classes('gap-1 col-3'):
|
|
|
+ ui.icon('source').classes('text-5xl q-mb-md text-primary opacity-80')
|
|
|
+ ui.label('Coding').classes('text-bold mb-4')
|
|
|
+ ui.markdown('- live-cycle events')
|
|
|
ui.markdown('- implicit reload on code change')
|
|
|
ui.markdown('- straight-forward data binding')
|
|
|
+ ui.markdown('- execute javascript from Python')
|
|
|
+ with ui.column().classes('gap-1 col-3'):
|
|
|
+ ui.icon('anchor').classes('text-5xl q-mb-md text-primary opacity-80')
|
|
|
+ ui.label('Foundation').classes('text-bold mb-4')
|
|
|
+ ui.markdown('- generic Vue to Python bridge')
|
|
|
+ ui.markdown('- dynamic GUI through Quasar')
|
|
|
+ ui.markdown('- content is served with FastAPI')
|
|
|
+ ui.markdown('- Python 3.7 - 3.11')
|
|
|
|
|
|
ui.link_target('installation').style(f'position: relative; top: -{HEADER_HEIGHT}')
|
|
|
- with ui.column().classes('w-full q-pa-xl'):
|
|
|
+ with ui.column().classes('w-full q-pa-xl q-mb-xl'):
|
|
|
ui.label('Installation').classes('text-bold text-lg')
|
|
|
- ui.html('Getting <em>started</em>') \
|
|
|
+ ui.html('Get <em>started</em>') \
|
|
|
.style('font-size: 300%; font-weight: 500; margin-top: -20px')
|
|
|
with ui.row().classes('w-full no-wrap text-lg leading-tight'):
|
|
|
with ui.column().classes('w-1/3 gap-2'):
|
|
|
ui.html('<em>1.</em>').classes('text-3xl text-bold')
|
|
|
- ui.markdown('Install').classes('text-lg')
|
|
|
- with bash_window().classes('w-full h-52'):
|
|
|
- ui.markdown('```bash\npython3 -m pip install nicegui\n```')
|
|
|
- with ui.column().classes('w-1/3 gap-2'):
|
|
|
- ui.html('<em>2.</em>').classes('text-3xl text-bold')
|
|
|
- ui.markdown('Write file __main.py__').classes('text-lg')
|
|
|
+ ui.markdown('Create __main.py__').classes('text-lg')
|
|
|
with python_window().classes('w-full h-52'):
|
|
|
ui.markdown('''```python\n
|
|
|
from nicegui import ui
|
|
@@ -171,15 +196,20 @@ ui.label('Hello NiceGUI!')
|
|
|
ui.run()
|
|
|
```''')
|
|
|
with ui.column().classes('w-1/3 gap-2'):
|
|
|
- ui.html('<em>3.</em>').classes('text-3xl text-bold')
|
|
|
- ui.markdown('Launch it with').classes('text-lg')
|
|
|
+ ui.html('<em>2.</em>').classes('text-3xl text-bold')
|
|
|
+ ui.markdown('Install and launch').classes('text-lg')
|
|
|
with bash_window().classes('w-full h-52'):
|
|
|
- ui.markdown('```bash\npython3 main.py\n```')
|
|
|
+ ui.markdown('```bash\npip3 install nicegui\npython3 main.py\n```')
|
|
|
+ with ui.column().classes('w-1/3 gap-2'):
|
|
|
+ ui.html('<em>3.</em>').classes('text-3xl text-bold')
|
|
|
+ ui.markdown('Enjoy').classes('text-lg')
|
|
|
+ with browser_window().classes('w-full h-52'):
|
|
|
+ ui.label('Hello NiceGUI!')
|
|
|
|
|
|
ui.link_target('examples').style(f'position: relative; top: -{HEADER_HEIGHT}')
|
|
|
- with ui.column().classes('w-full q-pa-xl'):
|
|
|
- ui.label('Documentation').classes('text-bold text-lg')
|
|
|
- ui.html('Interactive <em>Examples</em>') \
|
|
|
+ with ui.column().classes('w-full q-pa-xl q-mb-xl'):
|
|
|
+ ui.label('Examples').classes('text-bold text-lg')
|
|
|
+ ui.html('Try <em>this</em>') \
|
|
|
.style('font-size: 300%; font-weight: 500; margin-top: -20px')
|
|
|
reference.create_intro()
|
|
|
|
|
@@ -187,37 +217,42 @@ ui.run()
|
|
|
.classes('w-full items-center gap-28 px-32 py-16 no-wrap') \
|
|
|
.style(f'background: {ACCENT_COLOR}'):
|
|
|
with ui.column().classes('gap-4'):
|
|
|
- ui.markdown('Go to the API reference to see a ton of live examples.') \
|
|
|
+ ui.markdown('Browse through tons of live examples.') \
|
|
|
.style('font-size: 220%; color: white; line-height: 0.9; font-weight: 500')
|
|
|
- ui.html('The whole content of <a href="https://nicegui.io/">nicegui.io</a> is implemented with NiceGUI itself.') \
|
|
|
+ ui.html('Fun-Fact: This whole website is also coded with NiceGUI.') \
|
|
|
.style('font-size: 150%; color: white')
|
|
|
ui.link('API reference', '/reference') \
|
|
|
.classes('rounded-full mx-auto px-12 py-2 text-xl text-bold bg-white')
|
|
|
|
|
|
- with ui.column().classes('w-full q-pa-xl'):
|
|
|
- ui.label('In-depth demonstration').classes('text-bold text-lg')
|
|
|
- ui.html('What else can you do with <em>NiceGUI</em>?') \
|
|
|
+ ui.link_target('demos').style(f'position: relative; top: -{HEADER_HEIGHT}')
|
|
|
+ with ui.column().classes('w-full q-pa-xl q-mb-xl'):
|
|
|
+ ui.label('In-depth demonstrations').classes('text-bold text-lg')
|
|
|
+ ui.html('Pick your <em>solution</em>') \
|
|
|
.style('font-size: 300%; font-weight: 500; margin-top: -20px')
|
|
|
with ui.row().classes('w-full no-wrap text-lg leading-tight'):
|
|
|
with ui.column().classes('w-1/3'):
|
|
|
- ui.markdown(
|
|
|
- 'You may also have a look at the following examples for in-depth demonstrations of what you can do with NiceGUI:')
|
|
|
example_link('Slideshow', 'implements a keyboard-controlled image slideshow')
|
|
|
example_link('Authentication', 'shows how to use sessions to build a login screen')
|
|
|
example_link(
|
|
|
'Modularization',
|
|
|
- 'provides an example of how to modularize your application into multiple files and create a specialized page decorator')
|
|
|
+ 'provides an example of how to modularize your application into multiple files and reuse code')
|
|
|
+ example_link(
|
|
|
+ 'FastAPI',
|
|
|
+ 'illustrates the integration of NiceGUI with an existing FastAPI application')
|
|
|
with ui.column().classes('w-1/3'):
|
|
|
- example_link('Map', 'uses the JavaScript library leaflet to display a map at specific locations')
|
|
|
+ example_link(
|
|
|
+ 'Map',
|
|
|
+ 'demonstrates wrapping the JavaScript library leaflet to display a map at specific locations')
|
|
|
example_link(
|
|
|
'AI Interface',
|
|
|
- 'utilizes the great but non-async API from <https://replicate.com> to perform voice-to-text transcription and generate images from prompts with Stable Diffusion')
|
|
|
- example_link('3D Scene', 'creates a 3D scene and loads an STL mesh illuminated with a spotlight')
|
|
|
+ 'utilizes the great [replicate](https://replicate.com) library to perform voice-to-text transcription and generate images from prompts with Stable Diffusion')
|
|
|
+ example_link('3D Scene', 'creates a webGL view and loads an STL mesh illuminated with a spotlight')
|
|
|
with ui.column().classes('w-1/3'):
|
|
|
example_link('Custom Vue Component', 'shows how to write and integrate a custom vue component')
|
|
|
example_link('Image Mask Overlay', 'shows how to overlay an image with a mask')
|
|
|
- example_link('Infinite Scroll', 'shows an infinitely scrolling image gallery')
|
|
|
+ example_link('Infinite Scroll', 'presents an infinitely scrolling image gallery')
|
|
|
|
|
|
+ ui.link_target('why')
|
|
|
with ui.row() \
|
|
|
.classes('w-full h-screen q-pa-md items-center gap-28 p-32 no-wrap') \
|
|
|
.style(f'background: {ACCENT_COLOR}'):
|
|
@@ -239,12 +274,13 @@ ui.run()
|
|
|
<strong><a href="https://quasar.dev/">Quasar</a></strong>
|
|
|
for the frontend.<br/>
|
|
|
|
|
|
- The backend is build on top of
|
|
|
+ We have build on top of
|
|
|
<strong><a href="https://fastapi.tiangolo.com/">FastAPI</a></strong>,
|
|
|
which itself is based on the ASGI framework
|
|
|
<strong><a href="https://www.starlette.io/">Starlette</a></strong>,
|
|
|
and the ASGI webserver
|
|
|
- <strong><a href="https://www.uvicorn.org/">Uvicorn</a></strong>.
|
|
|
+ <strong><a href="https://www.uvicorn.org/">Uvicorn</a></strong>
|
|
|
+ because of their great performance and ease of use.
|
|
|
''').style('font-size: 150%; color: white').classes('leading-tight')
|
|
|
|
|
|
ui.html((STATIC / 'happy_face.svg').read_text()).classes('stroke-white').style('width: 1500px')
|
|
@@ -253,9 +289,9 @@ ui.run()
|
|
|
def example_link(title: str, description: str) -> None:
|
|
|
name = title.lower().replace(' ', '_')
|
|
|
with ui.column().classes('gap-0'):
|
|
|
- ui.link(title, f'https://github.com/zauberzeug/nicegui/tree/main/examples/{name}/main.py') \
|
|
|
- .classes(replace='text-black text-bold')
|
|
|
- ui.markdown(description)
|
|
|
+ with ui.link(target=f'https://github.com/zauberzeug/nicegui/tree/main/examples/{name}/main.py'):
|
|
|
+ ui.label(title).classes(replace='text-black text-bold')
|
|
|
+ ui.markdown(description).classes(replace='text-black')
|
|
|
|
|
|
|
|
|
@ui.page('/reference')
|