Files
pyscript/pyscript.core/test/ui/demo.py

250 lines
7.1 KiB
Python

try:
from textwrap import dedent
except ImportError:
dedent = lambda x: x
import examples
import styles
from pyweb import pydom
from pyweb.ui import elements as el
from pyweb.ui import shoelace
from pyweb.ui.elements import a, button, div, grid, h1, h2, h3, input_
from pyweb.ui.markdown import markdown
from pyscript import when, window
MAIN_PAGE_MARKDOWN = dedent(
"""
## What is pyweb.ui?
Pyweb UI is a totally immagnary exercise atm but..... imagine it is a Python library that allows you to create
web applications using Python only.
It is based on base HTML/JS components but is extensible, for instance, it can have a [Shoelace](https://shoelace.style/) backend...
PyWeb is a Python library that allows you to create web applications using Python only.
## What can I do with Pyweb.ui?
You can create web applications using Python only.
"""
)
# First thing we do is to load all the external resources we need
shoelace.load_resources()
# Let's define some convenience functions first
def create_component_details(component_label, component):
"""Create a component details card.
Args:
component (str): The name of the component to create.
Returns:
the component created
"""
# Get the example from the examples catalog
example = component["instance"]
details = example.__doc__ or f"Details missing for component {component_label}"
return div(
[
# Title and description (description is picked from the class docstring)
h1(component_label),
markdown(details),
# Example section
h2("Example:"),
create_component_example(component["instance"], component["code"]),
],
style={"margin": "20px"},
)
def add_component_section(component_label, component, parent_div):
"""Create a link to a component and add it to the left panel.
Args:
component (str): The name of the component to add.
Returns:
the component created
"""
# Create the component link element
div_ = div(
a(component_label, href="#"),
style={"display": "block", "text-align": "center", "margin": "auto"},
)
# Create a handler that opens the component details when the link is clicked
@when("click", div_)
def _change():
new_main = create_component_details(component_label, component)
main_area.html = ""
main_area.append(new_main)
# Add the new link element to the parent div (left panel)
parent_div.append(div_)
return div_
def create_component_example(widget, code):
"""Create a grid div with the widget on the left side and the relate code
on the right side.
Args:
widget (ElementBase): The widget to add to the grid.
code (str): The code to add to the grid.
Returns:
the grid created
"""
# Create the grid that splits the window in two columns (25% and 75%)
grid_ = grid("29% 2% 74%")
# Add the widget
grid_.append(div(widget, style=styles.STYLE_EXAMPLE_INSTANCE))
# Add the code div
widget_code = markdown(dedent(f"""```python\n{code}\n```"""))
grid_.append(shoelace.Divider(vertical=True))
grid_.append(div(widget_code, style=styles.STYLE_CODE_BLOCK))
return grid_
def create_main_area():
"""Create the main area of the right side of page, with the description of the
demo itself and how to use it.
Returns:
the main area
"""
div_ = div(
[
h1("Welcome to PyWeb UI!", style={"text-align": "center"}),
markdown(MAIN_PAGE_MARKDOWN),
]
)
main = el.main(
style={
"padding-top": "4rem",
"padding-bottom": "7rem",
"max-width": "52rem",
"margin-left": "auto",
"margin-right": "auto",
"padding-left": "1.5rem",
"padding-right": "1.5rem",
"width": "100%",
}
)
main.append(div_)
return main
def create_basic_components_page(label, kit_name):
"""Create the basic components page.
Returns:
the main area
"""
div_ = div(h2(label))
for component_label, component in examples.kits[kit_name].items():
div_.append(h3(component_label))
div_.append(create_component_example(component["instance"], component["code"]))
return div_
# ********** CREATE ALL THE LAYOUT **********
main_grid = grid("140px 20px auto", style={"min-height": "100%"})
# ********** MAIN PANEL **********
main_area = create_main_area()
def write_to_main(content):
main_area.html = ""
main_area.append(content)
def restore_home():
write_to_main(create_main_area())
def basic_components():
write_to_main(
create_basic_components_page(label="Basic Components", kit_name="elements")
)
# Make sure we highlight the code
window.hljs.highlightAll()
def markdown_components():
write_to_main(create_basic_components_page(label="", kit_name="markdown"))
def create_new_section(title, parent_div):
basic_components_text = h3(
title, style={"text-align": "left", "margin": "20px auto 0"}
)
parent_div.append(basic_components_text)
parent_div.append(
shoelace.Divider(style={"margin-top": "5px", "margin-bottom": "30px"})
)
return basic_components_text
# ********** LEFT PANEL **********
left_div = div()
left_panel_title = h1(
"PyWeb.UI", style={"text-align": "center", "margin": "20px auto 30px"}
)
left_div.append(left_panel_title)
left_div.append(shoelace.Divider(style={"margin-bottom": "30px"}))
# Let's map the creation of the main area to when the user clocks on "Components"
when("click", left_panel_title)(restore_home)
# BASIC COMPONENTS
basic_components_text = h3(
"Basic Components",
style={"text-align": "left", "margin": "20px auto 0", "cursor": "pointer"},
)
left_div.append(basic_components_text)
left_div.append(shoelace.Divider(style={"margin-top": "5px", "margin-bottom": "30px"}))
# Let's map the creation of the main area to when the user clocks on "Components"
when("click", basic_components_text)(basic_components)
# MARKDOWN COMPONENTS
markdown_title = create_new_section("Markdown", left_div)
when("click", markdown_title)(markdown_components)
# SHOELACE COMPONENTS
shoe_components_text = h3(
"Shoe Components", style={"text-align": "left", "margin": "20px auto 0"}
)
left_div.append(shoe_components_text)
left_div.append(shoelace.Divider(style={"margin-top": "5px", "margin-bottom": "30px"}))
# Create the links to the components on th left panel
print("SHOELACE EXAMPLES", examples.kits["shoelace"])
for component_label, component in examples.kits["shoelace"].items():
add_component_section(component_label, component, left_div)
left_div.append(shoelace.Divider(style={"margin-top": "5px", "margin-bottom": "30px"}))
left_div.append(a("Gallery", href="gallery.html", style={"text-align": "left"}))
# ********** ADD LEFT AND MAIN PANEL TO MAIN **********
main_grid.append(left_div)
main_grid.append(shoelace.Divider(vertical=True))
main_grid.append(main_area)
pydom.body.append(main_grid)