From a9637bbaa7f6aa97e87ec6eecd7cd46217927c58 Mon Sep 17 00:00:00 2001 From: Fabio Pliger Date: Thu, 1 Feb 2024 10:11:28 -0600 Subject: [PATCH] add gallery files --- pyscript.core/test/ui/gallery.html | 21 ++ pyscript.core/test/ui/gallery.py | 295 +++++++++++++++++++++++++++++ 2 files changed, 316 insertions(+) create mode 100644 pyscript.core/test/ui/gallery.html create mode 100644 pyscript.core/test/ui/gallery.py diff --git a/pyscript.core/test/ui/gallery.html b/pyscript.core/test/ui/gallery.html new file mode 100644 index 00000000..a7cc0a74 --- /dev/null +++ b/pyscript.core/test/ui/gallery.html @@ -0,0 +1,21 @@ + + + + PyDom UI + + + + + + + + + + + + + \ No newline at end of file diff --git a/pyscript.core/test/ui/gallery.py b/pyscript.core/test/ui/gallery.py new file mode 100644 index 00000000..06cf58a2 --- /dev/null +++ b/pyscript.core/test/ui/gallery.py @@ -0,0 +1,295 @@ +from pyweb import pydom +from pyscript import when, window +from textwrap import dedent +# from marked import Markdown +# import element as el + +from pyweb.ui import elements as el +from pyweb.ui import shoelace + +# Style dictionary for code blocks +STYLE_CODE_BLOCK = {"text-align": "left", "background-color": "#eee", "padding": "20px"} + +# First thing we do is to load all the external resources we need +shoelace.load_resources() + +def Markdown(txt): + # TODO: placeholder until we have a proper Markdown component + return el.div(txt) + +# Let's define some convenience functions first + +def create_component_details(component): + """Create a component details card. + + Args: + component (str): The name of the component to create. + + Returns: + the component created + + """ + # Outer div container + div = el.div(style={"margin": "20px"}) + + # Get the example from the examples catalog + example = shoelace.examples[component]['instance'] + + # Title and description (description is picked from the class docstring) + div.append(el.h1(component)) + details = example.__doc__ or f"Details missing for component {component}" + + div.append(Markdown(details)) + + # Create the example and code block + div.append(el.h2("Example:")) + + example_div = el.div(example, + style={"border-radius": "3px", "background-color": "var(--sl-color-neutral-50)", + "margin-bottom": "1.5rem"}) + example_div.append(example) + example_div.append( + shoelace.Details( + el.div(shoelace.examples[component]['code'], style=STYLE_CODE_BLOCK), + summary="View Code", + style={'background-color': 'gainsboro'} + ) + ) + div.append(example_div) + return div + + +def add_component_section(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 + + """ + div = el.div(el.a(component, href="#"), style={'display': 'block', 'text-align': 'center', 'margin': 'auto'}) + def _change(): + new_main = create_component_details(component) + main_area.html = "" + main_area.append(new_main) + + when('click', div)(_change) + print("adding component", component) + parent_div.append(div) + return div + + +def create_example_grid(widget, code): + """Create a grid with the widget and the code. + + 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 + grid = el.Grid("25% 75%") + # Add the widget + grid.append(el.div(widget)) + # Add the code div + widget_code = Markdown(dedent(f""" +```python +{code} +``` +""")) + grid.append(el.div(widget_code, style=STYLE_CODE_BLOCK)) + + return grid + + +def create_main_area(): + """Create the main area of the page. + + Returns: + the main area + + """ + div = el.div() + div.append(el.h1("Welcome to PyDom UI!", style={'text-align': 'center', 'margin': '20px auto 30px'})) + + div.append(el.h2("What is PyShoes?")) + div.append(Markdown(dedent("""\ + PyDom 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. + """ ))) + div.append(el.h2("What can I do with PyShoes?")) + + div.append(Markdown(dedent("""\ + You can create web applications using Python only. + """ ))) + + return div + +def create_markdown_components_page(): + """Create the basic components page. + + Returns: + the main area + + """ + div = el.div() + div.append(el.h2("Markdown")) + + # Buttons + markdown_txt_area = shoelace.TextArea(label="Markdown", help_text="Write your Mardown here and press convert to see the result") + translate_button = shoelace.Button("Convert", variant="primary") + result_div = el.div(style={'margin-top': '20px', 'min-height': '200px', 'background-color': 'cornsilk'}) + + @when('click', translate_button) + def translate_markdown(): + result_div.html = Markdown(markdown_txt_area.value).html + print("TOOOO", markdown_txt_area.value) + print("Translated", Markdown(markdown_txt_area.value)) + + main_section = el.div([ + markdown_txt_area, + translate_button, + result_div, + ]) + div.append(main_section) + # div.append(el.h3("Buttons")) + # btn = el.button("Click me!") + # when('click', btn)(lambda: window.alert("Clicked!")) + +# btn_code = dedent("""btn = button("Click me!"}) +# when('click', btn)(lambda: window.alert("Clicked!"))""") + +# div.append(create_example_grid(btn, btn_code)) + +# # Inputs +# inputs_div = el.div() +# div.append(el.h3("Inputs")) +# inputs_code = [] +# for input_type in ['text', 'password', 'email', 'number', 'date', 'time', 'color', 'range']: +# inputs_div.append(el.input(type=input_type, style={'display': 'block'})) +# inputs_code.append(f"input(type='{input_type}')") +# inputs_code = '\n'.join(inputs_code) + +# div.append(create_example_grid(inputs_div, inputs_code)) + +# # DIV +# div.append(el.h3("Div")) +# _div = el.div("This is a div", style={'text-align': 'center', 'width': '100%', 'margin': '0 auto 0', 'background-color': 'cornsilk'}) +# code = "div = div('This is a div', style={'text-align': 'center', 'margin': '0 auto 0', 'background-color': 'cornsilk'})" +# div.append(create_example_grid(_div, code)) + + return div + + +def create_basic_components_page(): + """Create the basic components page. + + Returns: + the main area + + """ + div = el.div() + div.append(el.h2("Base components:")) + + # Buttons + div.append(el.h3("Buttons")) + btn = el.button("Click me!") + when('click', btn)(lambda: window.alert("Clicked!")) + + btn_code = dedent("""btn = button("Click me!"}) +when('click', btn)(lambda: window.alert("Clicked!"))""") + + div.append(create_example_grid(btn, btn_code)) + + # Inputs + inputs_div = el.div() + div.append(el.h3("Inputs")) + inputs_code = [] + for input_type in ['text', 'password', 'email', 'number', 'date', 'time', 'color', 'range']: + inputs_div.append(el.input(type=input_type, style={'display': 'block'})) + inputs_code.append(f"input(type='{input_type}')") + inputs_code = '\n'.join(inputs_code) + + div.append(create_example_grid(inputs_div, inputs_code)) + + # DIV + div.append(el.h3("Div")) + _div = el.div("This is a div", style={'text-align': 'center', 'width': '100%', 'margin': '0 auto 0', 'background-color': 'cornsilk'}) + code = "div = div('This is a div', style={'text-align': 'center', 'margin': '0 auto 0', 'background-color': 'cornsilk'})" + div.append(create_example_grid(_div, code)) + + return div + +# ********** CREATE ALL THE LAYOUT ********** + +grid = el.Grid("minmax(100px, 200px) 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()) + +def markdown_components(): + write_to_main(create_markdown_components_page()) + +def create_new_section(title, parent_div): + basic_components_text = el.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 = el.div() +left_panel_title = el.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 = el.h3("Basic Components", style={'text-align': 'left', 'margin': '20px auto 0'}) +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 = el.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", shoelace.examples) +for component in shoelace.examples: + add_component_section(component, left_div) + + +# ********** ADD LEFT AND MAIN PANEL TO MAIN ********** +grid.append(left_div) +grid.append(shoelace.Divider(vertical=True)) +grid.append(main_area) + + +pydom.body.append(grid)