main_page.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import json
  2. from pathlib import Path
  3. from nicegui import ui
  4. from . import documentation, example_card, svg
  5. from .examples import examples
  6. from .header import add_head_html, add_header
  7. from .style import example_link, features, heading, link_target, section_heading, subtitle, title
  8. SPONSORS = json.loads((Path(__file__).parent / 'sponsors.json').read_text())
  9. def create() -> None:
  10. """Create the content of the main page."""
  11. ui.context.client.content.classes('p-0 gap-0')
  12. add_head_html()
  13. add_header()
  14. with ui.row().classes('w-full h-screen items-center gap-8 pr-4 no-wrap into-section'):
  15. svg.face(half=True).classes('stroke-black dark:stroke-white w-[200px] md:w-[230px] lg:w-[300px]')
  16. with ui.column().classes('gap-4 md:gap-8 pt-32'):
  17. title('Meet the *NiceGUI*.')
  18. subtitle('And let any browser be the frontend of your Python code.') \
  19. .classes('max-w-[20rem] sm:max-w-[24rem] md:max-w-[30rem]')
  20. ui.link(target='#about').classes('scroll-indicator')
  21. with ui.row().classes('''
  22. dark-box min-h-screen no-wrap
  23. justify-center items-center flex-col md:flex-row
  24. py-20 px-8 lg:px-16
  25. gap-8 sm:gap-16 md:gap-8 lg:gap-16
  26. '''):
  27. link_target('about')
  28. with ui.column().classes('text-white max-w-4xl'):
  29. heading('Interact with Python through buttons, dialogs, 3D scenes, plots and much more.')
  30. with ui.column().classes('gap-2 bold-links arrow-links text-lg'):
  31. ui.markdown('''
  32. NiceGUI manages web development details, letting you focus on Python code for diverse applications,
  33. including robotics, IoT solutions, smart home automation, and machine learning.
  34. Designed to work smoothly with connected peripherals like webcams and GPIO pins in IoT setups,
  35. NiceGUI streamlines the management of all your code in one place.
  36. <br><br>
  37. With a gentle learning curve, NiceGUI is user-friendly for beginners
  38. and offers advanced customization for experienced users,
  39. ensuring simplicity for basic tasks and feasibility for complex projects.
  40. <br><br><br>
  41. Available as
  42. [PyPI package](https://pypi.org/project/nicegui/),
  43. [Docker image](https://hub.docker.com/r/zauberzeug/nicegui) and on
  44. [GitHub](https://github.com/zauberzeug/nicegui).
  45. ''')
  46. example_card.create()
  47. with ui.column().classes('w-full text-lg p-8 lg:p-16 max-w-[1600px] mx-auto'):
  48. link_target('installation', '-50px')
  49. section_heading('Installation', 'Get *started*')
  50. with ui.row().classes('w-full text-lg leading-tight grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-8'):
  51. with ui.column().classes('w-full max-w-md gap-2'):
  52. ui.html('<em>1.</em>').classes('text-3xl font-bold fancy-em')
  53. ui.markdown('Create __main.py__').classes('text-lg')
  54. with documentation.python_window(classes='w-full h-52'):
  55. ui.markdown('''
  56. ```python\n
  57. from nicegui import ui
  58. ui.label('Hello NiceGUI!')
  59. ui.run()
  60. ```
  61. ''')
  62. with ui.column().classes('w-full max-w-md gap-2'):
  63. ui.html('<em>2.</em>').classes('text-3xl font-bold fancy-em')
  64. ui.markdown('Install and launch').classes('text-lg')
  65. with documentation.bash_window(classes='w-full h-52'):
  66. ui.markdown('''
  67. ```bash
  68. pip3 install nicegui
  69. python3 main.py
  70. ```
  71. ''')
  72. with ui.column().classes('w-full max-w-md gap-2'):
  73. ui.html('<em>3.</em>').classes('text-3xl font-bold fancy-em')
  74. ui.markdown('Enjoy!').classes('text-lg')
  75. with documentation.browser_window(classes='w-full h-52'):
  76. ui.label('Hello NiceGUI!')
  77. with ui.expansion('...or use Docker to run your main.py').classes('w-full gap-2 bold-links arrow-links'):
  78. with ui.row().classes('mt-8 w-full justify-center items-center gap-8'):
  79. ui.markdown('''
  80. With our [multi-arch Docker image](https://hub.docker.com/repository/docker/zauberzeug/nicegui)
  81. you can start the server without installing any packages.
  82. The command searches for `main.py` in in your current directory and makes the app available at http://localhost:8888.
  83. ''').classes('max-w-xl')
  84. with documentation.bash_window(classes='max-w-lg w-full h-52'):
  85. ui.markdown('''
  86. ```bash
  87. docker run -it --rm -p 8888:8080 \\
  88. -v "$PWD":/app zauberzeug/nicegui
  89. ```
  90. ''')
  91. with ui.column().classes('w-full p-8 lg:p-16 bold-links arrow-links max-w-[1600px] mx-auto'):
  92. link_target('features', '-50px')
  93. section_heading('Features', 'Code *nicely*')
  94. with ui.row().classes('w-full text-lg leading-tight grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-8'):
  95. features('swap_horiz', 'Interaction', [
  96. '[buttons, switches, sliders, inputs, ...](/documentation/section_controls)',
  97. '[notifications, dialogs and menus](/documentation/section_page_layout)',
  98. '[interactive images](/documentation/interactive_image) with SVG overlays',
  99. 'web pages and [native window apps](/documentation/section_configuration_deployment#native_mode)',
  100. ])
  101. features('space_dashboard', 'Layout', [
  102. '[navigation bars, tabs, panels, ...](/documentation/section_page_layout)',
  103. 'grouping with rows, columns, grids and cards',
  104. '[HTML](/documentation/html) and [Markdown](/documentation/markdown) elements',
  105. 'flex layout by default',
  106. ])
  107. features('insights', 'Visualization', [
  108. '[charts, diagrams, tables](/documentation/section_data_elements), [audio/video](/documentation/section_audiovisual_elements)',
  109. '[3D scenes](/documentation/scene)',
  110. 'straight-forward [data binding](/documentation/section_binding_properties)',
  111. 'built-in [timer for data refresh](/documentation/timer)',
  112. ])
  113. features('brush', 'Styling', [
  114. 'customizable [color themes](/documentation/section_styling_appearance#color_theming)',
  115. 'custom CSS and classes',
  116. 'modern look with material design',
  117. '[Tailwind CSS](https://tailwindcss.com/) auto-completion',
  118. ])
  119. features('source', 'Coding', [
  120. 'routing for multiple [pages](/documentation/page)',
  121. 'auto-reload on code change',
  122. 'persistent [user sessions](/documentation/storage)',
  123. 'super nice [testing framework](/documentation/section_testing)',
  124. ])
  125. features('anchor', 'Foundation', [
  126. 'generic [Vue](https://vuejs.org/) to Python bridge',
  127. 'dynamic GUI through [Quasar](https://quasar.dev/)',
  128. 'content is served with [FastAPI](https://fastapi.tiangolo.com/)',
  129. 'Python 3.8+',
  130. ])
  131. with ui.column().classes('w-full p-8 lg:p-16 max-w-[1600px] mx-auto'):
  132. link_target('demos', '-50px')
  133. section_heading('Demos', 'Try *this*')
  134. with ui.column().classes('w-full'):
  135. documentation.create_intro()
  136. with ui.column().classes('dark-box p-8 lg:p-16 my-16'):
  137. with ui.column().classes('mx-auto items-center gap-y-8 gap-x-32 lg:flex-row'):
  138. with ui.column().classes('gap-1 max-lg:items-center max-lg:text-center'):
  139. ui.markdown('Browse through plenty of live demos.') \
  140. .classes('text-white text-2xl md:text-3xl font-medium')
  141. ui.html('Fun-Fact: This whole website is also coded with NiceGUI.') \
  142. .classes('text-white text-lg md:text-xl')
  143. ui.link('Documentation', '/documentation').style('color: black !important') \
  144. .classes('rounded-full mx-auto px-12 py-2 bg-white font-medium text-lg md:text-xl')
  145. with ui.column().classes('w-full p-8 lg:p-16 max-w-[1600px] mx-auto'):
  146. link_target('examples', '-50px')
  147. section_heading('In-depth examples', 'Pick your *solution*')
  148. with ui.row().classes('w-full text-lg leading-tight grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-4'):
  149. for example in examples:
  150. example_link(example)
  151. with ui.column().classes('dark-box p-8 lg:p-16 my-16 bg-transparent border-y-2'):
  152. with ui.column().classes('mx-auto items-center gap-y-8 gap-x-32 lg:flex-row'):
  153. with ui.column().classes('max-lg:items-center max-lg:text-center'):
  154. link_target('sponsors')
  155. ui.markdown('NiceGUI is supported by') \
  156. .classes('text-2xl md:text-3xl font-medium')
  157. if SPONSORS['top']:
  158. with ui.row(align_items='center'):
  159. assert SPONSORS['total'] > 0
  160. ui.markdown(f'''
  161. our top {'sponsor' if len(SPONSORS['top']) == 1 else 'sponsors'}
  162. ''')
  163. for sponsor in SPONSORS['top']:
  164. with ui.link(target=f'https://github.com/{sponsor}').classes('row items-center gap-2'):
  165. ui.image(f'https://github.com/{sponsor}.png').classes('w-12 h-12 border')
  166. ui.label(f'@{sponsor}')
  167. ui.markdown(f'''
  168. as well as {SPONSORS['total'] - len(SPONSORS['top'])} other [sponsors](https://github.com/sponsors/zauberzeug)
  169. and {SPONSORS['contributors']} [contributors](https://github.com/zauberzeug/nicegui/graphs/contributors).
  170. ''').classes('bold-links arrow-links')
  171. else:
  172. ui.markdown(f'''
  173. {SPONSORS['total']} [sponsors](https://github.com/sponsors/zauberzeug)
  174. and {SPONSORS['contributors']} [contributors](https://github.com/zauberzeug/nicegui/graphs/contributors).
  175. ''').classes('bold-links arrow-links')
  176. with ui.link(target='https://github.com/sponsors/zauberzeug').style('color: black !important') \
  177. .classes('rounded-full mx-auto px-12 py-2 border-2 border-[#3e6a94] font-medium text-lg md:text-xl'):
  178. with ui.row().classes('items-center gap-4'):
  179. ui.icon('sym_o_favorite', color='#3e6a94')
  180. ui.label('Become a sponsor').classes('text-[#3e6a94]')
  181. with ui.row().classes('dark-box min-h-screen mt-16'):
  182. link_target('why')
  183. with ui.column().classes('''
  184. max-w-[1600px] m-auto
  185. py-20 px-8 lg:px-16
  186. items-center justify-center no-wrap flex-col md:flex-row gap-16
  187. '''):
  188. with ui.column().classes('gap-8'):
  189. heading('Why?')
  190. with ui.column().classes('gap-2 text-xl text-white bold-links arrow-links'):
  191. ui.markdown('''
  192. We at
  193. [Zauberzeug](https://zauberzeug.com)
  194. like
  195. [Streamlit](https://streamlit.io/)
  196. but find it does
  197. [too much magic](https://github.com/zauberzeug/nicegui/issues/1#issuecomment-847413651)
  198. when it comes to state handling.
  199. In search for an alternative nice library to write simple graphical user interfaces in Python we discovered
  200. [JustPy](https://justpy.io/).
  201. Although we liked the approach, it is too "low-level HTML" for our daily usage.
  202. But it inspired us to use
  203. [Vue](https://vuejs.org/)
  204. and
  205. [Quasar](https://quasar.dev/)
  206. for the frontend.
  207. ''')
  208. ui.markdown('''
  209. We have built on top of
  210. [FastAPI](https://fastapi.tiangolo.com/),
  211. which itself is based on the ASGI framework
  212. [Starlette](https://www.starlette.io/)
  213. and the ASGI webserver
  214. [Uvicorn](https://www.uvicorn.org/)
  215. because of their great performance and ease of use.
  216. ''')
  217. svg.face().classes('stroke-white shrink-0 w-[200px] md:w-[300px] lg:w-[450px]')