add global JS attributes to elements and improve demos

This commit is contained in:
Fabio Pliger
2024-02-02 09:00:47 -06:00
parent fb584c3984
commit 05a5fb7ff2
5 changed files with 78 additions and 123 deletions

View File

@@ -24,6 +24,7 @@ GLOBAL_ATTRIBUTES = [
"title",
"translate",
"virtualkeyboardpolicy",
"className"
]
# class and style are different ones that are handled by pydom.element directly
@@ -78,7 +79,11 @@ class TextElementBase(ElementBase):
def _add_js_properties(cls, *attrs):
"""Add JSProperties to a class as `js_property` class attributes."""
# First we set all the properties as JSProperties
# First we set all the global properties as JSProperties
for attr in GLOBAL_ATTRIBUTES:
setattr(cls, attr, js_property(attr))
# Now the specific class properties
for attr in attrs:
setattr(cls, attr, js_property(attr))
@@ -257,6 +262,7 @@ class br(ElementBase):
class div(TextElementBase):
tag = "div"
_add_js_properties(div)
class img(ElementBase):
tag = "img"

View File

@@ -1,6 +1,5 @@
from textwrap import dedent
import examples
from pyweb import pydom
from pyweb.ui import elements as el
from pyweb.ui import shoelace
@@ -8,6 +7,9 @@ from pyweb.ui.markdown import markdown
from pyscript import when, window
import styles
import examples
MAIN_PAGE_MARKDOWN = dedent(
"""
## What is pyweb.ui?
@@ -24,10 +26,6 @@ MAIN_PAGE_MARKDOWN = dedent(
"""
)
# 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()
@@ -60,7 +58,7 @@ def create_component_details(component):
example,
shoelace.Details(
el.div(
examples_gallery[component]["code"], style=STYLE_CODE_BLOCK
examples_gallery[component]["code"], style=styles.STYLE_CODE_BLOCK
),
summary="View Code",
style={"background-color": "gainsboro"},
@@ -124,7 +122,7 @@ def create_component_example(widget, code):
grid.append(el.div(widget))
# Add the code div
widget_code = markdown(dedent(f"""```python\n{code}\n```"""))
grid.append(el.div(widget_code, style=STYLE_CODE_BLOCK))
grid.append(el.div(widget_code, style=styles.STYLE_CODE_BLOCK))
return grid
@@ -201,10 +199,8 @@ def create_basic_components_page():
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!"))"""
)
btn_code = dedent("""btn = button("Click me!")
when('click', btn)(lambda: window.alert("Clicked!"))""")
div.append(create_component_example(btn, btn_code))

View File

@@ -10,6 +10,14 @@
<script src="https://cdn.jsdelivr.net/npm/marked@11.1.1/lib/marked.umd.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<!-- and it's easy to individually load additional languages -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/go.min.js"></script>
<script>hljs.highlightAll();</script>
<style>
body {
font-family: -apple-system, "system-ui", "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"

View File

@@ -1,57 +1,31 @@
from textwrap import dedent
import inspect
from pyweb import pydom
from pyweb.ui import elements as el
from pyweb.ui import shoelace
from pyweb.ui.markdown import markdown
from pyscript import when
from pyscript import when, window
import tictactoe
import styles
MAIN_PAGE_MARKDOWN = dedent(
"""
## Welcome to the PyWeb.UI gallery!
This gallery is a collection of demos using the PyWeb.UI library. There are meant
to be examples of how to use the library to create GUI applications using Python
only.
## How to use the gallery
Simply click on the demo you want to see and the details will appear on the right
"""
)
# Style dictionary for code blocks
STYLE_CODE_BLOCK = {"text-align": "left", "background-color": "#eee", "padding": "20px"}
STYLE_LEFT_PANEL_LINKS = {"display": "block", "text-align": "center", "margin": "auto"}
STYLE_MARKDOWN_RESULT = {
"margin-top": "20px",
"min-height": "200px",
"background-color": "cornsilk",
}
STYLE_LEFT_PANEL_TITLE = {"text-align": "center", "margin": "20px auto 30px"}
STYLE_TIC_TAC_TOE = """
.tictactoe-square {
width: 70px;
height: 70px;
border: 1px solid gray;
cursor: pointer;
}
.tictactoe-choice {
font-size: 42px;
font-family: Brush Script MT;
text-align: center;
margin: auto;
}
.tictactoe-inside {
background-color: lightblue;
}
.tictactoe-css {
margin-top: 10px;
width: 400px;
height: 400px;
background-color: rgb(255, 255, 244);
}
"""
# First thing we do is to load all the external resources we need
shoelace.load_resources()
def add_demo(demo_name, demo_creator_cb, parent_div):
def add_demo(demo_name, demo_creator_cb, parent_div, source=None):
"""Create a link to a component and add it to the left panel.
Args:
@@ -62,18 +36,26 @@ def add_demo(demo_name, demo_creator_cb, parent_div):
"""
# Create the component link element
div = el.div(el.a(demo_name, href="#"), style=STYLE_LEFT_PANEL_LINKS)
div = el.div(el.a(demo_name, href="#"), style=styles.STYLE_LEFT_PANEL_LINKS)
# Create a handler that opens the component details when the link is clicked
@when("click", div)
def _change():
write_to_main(demo_creator_cb())
if source:
demo_div = el.Grid("50% 50%")
demo_div.append(demo_creator_cb())
widget_code = markdown(dedent(f"""```python\n{source}\n```"""))
demo_div.append(el.div(widget_code, style=styles.STYLE_CODE_BLOCK))
else:
demo_div = demo_creator_cb()
demo_div.style['margin'] = '20px'
write_to_main(demo_div)
window.hljs.highlightAll()
# Add the new link element to the parent div (left panel)
parent_div.append(div)
return div
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.
@@ -82,12 +64,10 @@ def create_main_area():
the main area
"""
return el.div(
[
el.h1("Welcome to PyDom UI!", style={"text-align": "center"}),
return el.div([
el.h1("PyWeb UI Galler", style={"text-align": "center"}),
markdown(MAIN_PAGE_MARKDOWN),
]
)
])
def create_markdown_app():
@@ -98,71 +78,18 @@ def create_markdown_app():
"""
translate_button = shoelace.Button("Convert", variant="primary")
markdown_txt_area = shoelace.TextArea(
label="Markdown",
help_text="Write your Mardown here and press convert to see the result",
)
result_div = el.div(style=STYLE_MARKDOWN_RESULT)
div = el.div(
[
el.h2("Markdown"),
markdown_txt_area,
translate_button,
result_div,
]
)
markdown_txt_area = shoelace.TextArea(label="Use this to write your Markdown")
result_div = el.div(style=styles.STYLE_MARKDOWN_RESULT)
@when("click", translate_button)
def translate_markdown():
result_div.html = markdown(markdown_txt_area.value).html
return div
clicks = 0
def handle_tic_tac_toe_click(square):
@when("click", square)
def on_click(event):
global clicks
if clicks % 2:
square.html = "X"
else:
square.html = "0"
clicks += 1
square.add_class("tictactoe-choice")
def create_tic_tac_toe():
grid = el.div()
for _ in range(3):
row = el.Grid("1fr 1fr 1fr", style={"width": "100px"})
for __ in range(3):
square = el.div()
square.add_class("tictactoe-square")
handle_tic_tac_toe_click(square)
row.append(square)
grid.append(row)
div = el.div(
[
el.h2("Tic Tac Toe"),
el.p("This is a simple tic tac toe game", style={"margin": "20px"}),
el.Grid("1fr 1fr 1fr", style={"margin-top": "20px"}),
grid,
el.h3("Tip: Click inside the squares to play"),
]
)
# Load the CSS for the tic-tac-toe example
pydom.body.append(el.style(STYLE_TIC_TAC_TOE))
# Return the main app div
return div
return el.div([
el.h2("Markdown"),
markdown_txt_area,
translate_button,
result_div,
], style={"margin": "20px"})
# ********** MAIN PANEL **********
@@ -190,12 +117,12 @@ def create_new_section(title, parent_div):
# ********** LEFT PANEL **********
left_panel_title = el.h1("PyWeb.UI", style=STYLE_LEFT_PANEL_TITLE)
left_panel_title = el.h1("PyWeb.UI", style=styles.STYLE_LEFT_PANEL_TITLE)
left_div = el.div(
[
left_panel_title,
shoelace.Divider(style={"margin-bottom": "30px"}),
el.h3("Demos", style=STYLE_LEFT_PANEL_TITLE),
el.h3("Demos", style=styles.STYLE_LEFT_PANEL_TITLE),
]
)
@@ -203,9 +130,25 @@ left_div = el.div(
when("click", left_panel_title)(restore_home)
# ------ ADD DEMOS ------
markdown_source = """
translate_button = shoelace.Button("Convert", variant="primary")
markdown_txt_area = shoelace.TextArea(label="Markdown",
help_text="Write your Mardown here and press convert to see the result",
)
result_div = el.div(style=styles.STYLE_MARKDOWN_RESULT)
@when("click", translate_button)
def translate_markdown():
result_div.html = markdown(markdown_txt_area.value).html
add_demo("Markdown", create_markdown_app, left_div)
add_demo("Tic Tac Toe", create_tic_tac_toe, left_div)
el.div([
el.h2("Markdown"),
markdown_txt_area,
translate_button,
result_div,
])
"""
add_demo("Markdown", create_markdown_app, left_div, source = markdown_source)
add_demo("Tic Tac Toe", tictactoe.create_tic_tac_toe, left_div, source=inspect.getsource(tictactoe))
# ********** CREATE ALL THE LAYOUT **********
grid = el.Grid("minmax(100px, 200px) 20px auto", style={"min-height": "100%"})

View File

@@ -2,3 +2,5 @@ packages = []
[files]
"./examples.py" = "./examples.py"
"./tictactoe.py" = "./tictactoe.py"
"./styles.py" = "./styles.py"