[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
This commit is contained in:
pre-commit-ci[bot]
2024-01-31 22:27:15 +00:00
parent a9057e4cea
commit 6c5052221e
7 changed files with 553 additions and 276 deletions

View File

@@ -1,2 +1,3 @@
from .pydom import JSProperty
from .pydom import dom as pydom
from .pydom import JSProperty, js_property
from .pydom import js_property

View File

@@ -39,7 +39,7 @@ class JSProperty:
name in the underlying Shoelace JS component."""
def js_property(name: str, allow_nones: bool=False):
def js_property(name: str, allow_nones: bool = False):
"""Create a property that maps to the property with the same name in the underlying
JS component.
@@ -60,6 +60,7 @@ def js_property(name: str, allow_nones: bool=False):
Returns:
the property created
"""
class CustomProperty(JSProperty):
def __get__(self, obj, objtype=None):
return getattr(obj._js, name)

View File

@@ -1 +1 @@
from . import elements, shoelace
from . import elements, shoelace

View File

@@ -1,39 +1,40 @@
from textwrap import dedent
from pyscript import document, when, window
from pyweb import pydom, js_property, JSProperty
from pyweb import JSProperty, js_property, pydom
class ElementBase(pydom.Element):
tag = 'div'
tag = "div"
def __init__(self, style = None, **kwargs):
def __init__(self, style=None, **kwargs):
super().__init__(document.createElement(self.tag))
# set all the style properties provided in input
if style:
for key, value in style.items():
self.style[key] = value
# IMPORTANT!!! This is used to auto-harvest all input arguments and set them as properties
kwargs['self'] = self
kwargs["self"] = self
self._init_properties(**kwargs)
@staticmethod
def _init_properties(**kwargs):
self = kwargs.pop('self')
self = kwargs.pop("self")
# Look at all the properties of the class and see if they were provided in kwargs
for attr_name, attr in self.__class__.__dict__.items():
# For each one, actually check if it is a property of the class and set it
if isinstance(attr, JSProperty) and attr_name in kwargs:
setattr(self, attr_name, kwargs[attr_name])
setattr(self, attr_name, kwargs[attr_name])
# def __add__(self, other):
# if isinstance(other, list):
# other = div(*other)
# return WidgetCollection(*self.widgets, other, separator=self.separator)
class TextElementBase(ElementBase):
def __init__(self, content=None, style=None, **kwargs):
super().__init__(style=style, **kwargs)
@@ -48,6 +49,7 @@ class TextElementBase(ElementBase):
else:
self._js.innerHTML = content
class h1(TextElementBase):
tag = "h1"
@@ -61,118 +63,168 @@ class h3(TextElementBase):
class button(TextElementBase):
tag = 'button'
tag = "button"
# JS Properties
autofocus = js_property('autofocus')
disabled = js_property('disabled')
name = js_property('name')
type = js_property('type')
value = js_property('value')
autofocus = js_property("autofocus")
disabled = js_property("disabled")
name = js_property("name")
type = js_property("type")
value = js_property("value")
class a(TextElementBase):
tag = 'a'
href = js_property('href')
tag = "a"
href = js_property("href")
def __init__(self, content, href, style = None, **kwargs):
def __init__(self, content, href, style=None, **kwargs):
super().__init__(content, href=href, style=style, **kwargs)
class link(TextElementBase):
tag = 'link'
tag = "link"
rel = js_property('rel')
type = js_property('type')
href = js_property('href')
media = js_property('media')
rel = js_property("rel")
type = js_property("type")
href = js_property("href")
media = js_property("media")
def __init__(self, content=None, rel=None, type=None, href=None, media=None, style = None, **kwargs):
super().__init__(content=content, rel=rel, type=type, href=href, media=media, style=style, **kwargs)
def __init__(
self,
content=None,
rel=None,
type=None,
href=None,
media=None,
style=None,
**kwargs
):
super().__init__(
content=content,
rel=rel,
type=type,
href=href,
media=media,
style=style,
**kwargs
)
class script(TextElementBase):
tag = 'script'
tag = "script"
async_ = js_property('async')
defer = js_property('defer')
blocking = js_property('blocking')
crossorigin = js_property('crossorigin')
fetchpriority = js_property('fetchpriority')
src = js_property('src')
type = js_property('type')
nonce = js_property('nonce')
nomodule = js_property('nomodule')
integrity = js_property('integrity')
async_ = js_property("async")
defer = js_property("defer")
blocking = js_property("blocking")
crossorigin = js_property("crossorigin")
fetchpriority = js_property("fetchpriority")
src = js_property("src")
type = js_property("type")
nonce = js_property("nonce")
nomodule = js_property("nomodule")
integrity = js_property("integrity")
def __init__(
self,
content=None,
src=None,
type=None,
async_=None,
defer=None,
blocking=None,
crossorigin=None,
fetchpriority=None,
nonce=None,
nomodule=None,
integrity=None,
style=None,
**kwargs
):
super().__init__(
content=content,
src=src,
type=type,
async_=async_,
defer=defer,
blocking=blocking,
crossorigin=crossorigin,
fetchpriority=fetchpriority,
nonce=nonce,
nomodule=nomodule,
integrity=integrity,
style=style,
**kwargs
)
def __init__(self, content=None, src=None, type=None, async_=None, defer=None, blocking=None,
crossorigin=None, fetchpriority=None, nonce=None, nomodule=None, integrity=None,
style = None, **kwargs):
super().__init__(content=content, src=src, type=type, async_=async_,
defer=defer, blocking=blocking, crossorigin=crossorigin,
fetchpriority=fetchpriority, nonce=nonce, nomodule=nomodule,
integrity=integrity, style=style, **kwargs)
class p(TextElementBase):
tag = 'p'
tag = "p"
class code(TextElementBase):
tag = 'code'
tag = "code"
class pre(TextElementBase):
tag = 'pre'
tag = "pre"
class strong(TextElementBase):
tag = 'strong'
tag = "strong"
class small(TextElementBase):
tag = 'small'
tag = "small"
class br(ElementBase):
tag = 'br'
tag = "br"
class div(TextElementBase):
tag = 'div'
tag = "div"
class img(ElementBase):
tag = 'img'
src = js_property('src')
tag = "img"
src = js_property("src")
# TODO: This should probably go on the ElementBase class since it's a global attribtute
# https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/slot
slot = js_property('slot')
slot = js_property("slot")
def __init__(self, src, alt="", style = None, **kwargs):
def __init__(self, src, alt="", style=None, **kwargs):
super().__init__(src=src, alt=alt, style=style, **kwargs)
class Grid(ElementBase):
tag = 'div'
tag = "div"
def __init__(self, layout="", gap=None, **kwargs):
super().__init__(**kwargs)
self.style['display'] = 'grid'
self.style['grid-template-columns'] = layout
self.style["display"] = "grid"
self.style["grid-template-columns"] = layout
# TODO: This should be a property
if not gap is None:
self.style['gap'] = gap
self.style["gap"] = gap
class input(ElementBase):
tag = 'input'
tag = "input"
# JS Properties
autofocus = js_property('autofocus')
alt = js_property('alt')
autocapitalize = js_property('autocapitalize')
autocomplete = js_property('autocomplete')
checked = js_property('checked')
disabled = js_property('disabled')
name = js_property('name')
type = js_property('type')
value = js_property('value')
placeholder = js_property('placeholder')
autofocus = js_property("autofocus")
alt = js_property("alt")
autocapitalize = js_property("autocapitalize")
autocomplete = js_property("autocomplete")
checked = js_property("checked")
disabled = js_property("disabled")
name = js_property("name")
type = js_property("type")
value = js_property("value")
placeholder = js_property("placeholder")
# TODO: This is by anymeans complete!! We need to add more attributes
def __init__(self, style = None, **kwargs):
def __init__(self, style=None, **kwargs):
super().__init__(style=style, **kwargs)

View File

@@ -2,28 +2,28 @@ import string
from textwrap import dedent
from pyscript import document, when, window
from pyweb import pydom, JSProperty, js_property
from pyweb import JSProperty, js_property, pydom
from pyweb.ui import elements as el
class ShoeBase(pydom.Element):
tag = 'div'
tag = "div"
def __init__(self, style = None, **kwargs):
def __init__(self, style=None, **kwargs):
super().__init__(document.createElement(self.tag))
# set all the style properties provided in input
if style:
for key, value in style.items():
self.style[key] = value
# IMPORTANT!!! This is used to auto-harvest all input arguments and set them as properties
kwargs['self'] = self
kwargs["self"] = self
self._init_properties(**kwargs)
@staticmethod
def _init_properties(**kwargs):
self = kwargs.pop('self')
self = kwargs.pop("self")
# Look at all the properties of the class and see if they were provided in kwargs
# print(f"Looking for element properties for {self.__class__}...")
@@ -33,9 +33,10 @@ class ShoeBase(pydom.Element):
if isinstance(attr, JSProperty) and attr_name in kwargs:
setattr(self, attr_name, kwargs[attr_name])
class TextShoeBase(ShoeBase):
def __init__(self, content, style=None, **kwargs):
if not style and getattr(self, 'default_style', None):
if not style and getattr(self, "default_style", None):
style = self.default_style
super().__init__(style=style, **kwargs)
@@ -45,47 +46,76 @@ class TextShoeBase(ShoeBase):
else:
self._js.innerHTML = content
class Button(ShoeBase):
tag = 'sl-button'
variant = js_property('variant')
size = js_property('size')
outline = js_property('outline')
pill = js_property('pill')
circle = js_property('circle')
def __init__(self, content, variant='primary', size=None, outline=False, pill=False, circle=False, **kwargs):
class Button(ShoeBase):
tag = "sl-button"
variant = js_property("variant")
size = js_property("size")
outline = js_property("outline")
pill = js_property("pill")
circle = js_property("circle")
def __init__(
self,
content,
variant="primary",
size=None,
outline=False,
pill=False,
circle=False,
**kwargs,
):
super().__init__(**kwargs)
self._js.textContent = content
# IMPORTANT!!! This is use to auto-harvest all input arguments and set them as properties
self._init_properties(**locals())
class Alert(TextShoeBase):
"""Alerts are used to display important messages inline or as toast notifications.
Example: Alert("This is a standard alert. You can customize its content and even the icon.")"""
Example: Alert("This is a standard alert. You can customize its content and even the icon.")
"""
tag = 'sl-alert'
open = js_property('open')
variant = js_property('variant')
tag = "sl-alert"
open = js_property("open")
variant = js_property("variant")
def __init__(self, content, variant=None, open=True, **kwargs):
# TODO: Should content be appended so we can support html Elements as well?
super().__init__(content, variant=variant, open=open, **kwargs)
class Select(ShoeBase):
tag = 'sl-select'
label = js_property('label')
helpText = js_property('helpText')
placeholder = js_property('placeholder')
pill = js_property('pill')
value = js_property('value')
def __init__(self, label=None, options=None, placeholder=None, help_text=None, value=None, style=None, **kwargs):
super().__init__(label=label, placeholder=placeholder, help_text=help_text, value=value, style=style, **kwargs)
html_ = '\n'.join([f'<sl-option value="{option}">{option}</sl-option>' for option in options])
class Select(ShoeBase):
tag = "sl-select"
label = js_property("label")
helpText = js_property("helpText")
placeholder = js_property("placeholder")
pill = js_property("pill")
value = js_property("value")
def __init__(
self,
label=None,
options=None,
placeholder=None,
help_text=None,
value=None,
style=None,
**kwargs,
):
super().__init__(
label=label,
placeholder=placeholder,
help_text=help_text,
value=value,
style=style,
**kwargs,
)
html_ = "\n".join(
[f'<sl-option value="{option}">{option}</sl-option>' for option in options]
)
self.html = html_
print("options", options)
print("HTML", html_)
@@ -93,52 +123,86 @@ class Select(ShoeBase):
# for option in options:
# self.append(el.option(option))
class Button(TextShoeBase):
"""Buttons represent actions that are available to the user."""
tag = 'sl-button'
variant = js_property('variant')
size = js_property('size')
outline = js_property('outline')
pill = js_property('pill')
circle = js_property('circle')
def __init__(self, content, variant='primary', size=None, outline=False, pill=False, circle=False, **kwargs):
super().__init__(content, variant=variant, size=size, outline=outline, pill=pill, circle=circle, **kwargs)
tag = "sl-button"
variant = js_property("variant")
size = js_property("size")
outline = js_property("outline")
pill = js_property("pill")
circle = js_property("circle")
def __init__(
self,
content,
variant="primary",
size=None,
outline=False,
pill=False,
circle=False,
**kwargs,
):
super().__init__(
content,
variant=variant,
size=size,
outline=outline,
pill=pill,
circle=circle,
**kwargs,
)
class Details(TextShoeBase):
"""Details are used as a disclosure widget from which users can retrieve additional information."""
tag = 'sl-details'
open = js_property('open')
summary = js_property('summary')
disabled = js_property('disabled')
update_complete = js_property('updateComplete')
def __init__(self, content, summary, open=None, disabled=None, style=None, **kwargs):
super().__init__(content, summary=summary, open=open, disabled=disabled, style=style, **kwargs)
tag = "sl-details"
open = js_property("open")
summary = js_property("summary")
disabled = js_property("disabled")
update_complete = js_property("updateComplete")
def __init__(
self, content, summary, open=None, disabled=None, style=None, **kwargs
):
super().__init__(
content,
summary=summary,
open=open,
disabled=disabled,
style=style,
**kwargs,
)
class Dialog(TextShoeBase):
tag = 'sl-dialog'
label = js_property('label')
noheader = js_property('noheader')
open = js_property('open')
tag = "sl-dialog"
label = js_property("label")
noheader = js_property("noheader")
open = js_property("open")
# TODO: We should map the `modal` property as well but it's a bit of special...
def __init__(self, content, label=None, open=None, disabled=None, style=None, **kwargs):
super().__init__(content, label=label, open=open, disabled=disabled, style=style, **kwargs)
def __init__(
self, content, label=None, open=None, disabled=None, style=None, **kwargs
):
super().__init__(
content, label=label, open=open, disabled=disabled, style=style, **kwargs
)
class Divider(ShoeBase):
tag = 'sl-divider'
tag = "sl-divider"
vertical = js_property("vertical")
vertical = js_property('vertical')
def __init__(self, vertical=None, **kwargs):
super().__init__(vertical=vertical, **kwargs)
self._init_properties(**locals())
class BaseMixin(pydom.Element):
@property
def label(self):
@@ -148,6 +212,7 @@ class BaseMixin(pydom.Element):
def label(self, value):
self._js.label = value
# class LabelProperty:
# def __get__(self, obj, objtype=None):
# return obj._js.label
@@ -155,6 +220,7 @@ class BaseMixin(pydom.Element):
# def __set__(self, obj, value):
# obj._js.label = value
class PlaceholderProperty:
def __get__(self, obj, objtype=None):
return obj._js.placeholder
@@ -162,53 +228,108 @@ class PlaceholderProperty:
def __set__(self, obj, value):
obj._js.placeholder = value
class Input(ShoeBase):
tag = "sl-input"
label = js_property('label')
placeholder = js_property('placeholder')
pill = js_property('pill')
help_text = js_property('helpText')
value = js_property('value')
label = js_property("label")
placeholder = js_property("placeholder")
pill = js_property("pill")
help_text = js_property("helpText")
value = js_property("value")
def __init__(self, label=None, value=None, type='text', placeholder=None, help_text=None,
size=None, filled=False, pill=False, disabled=False, readonly=False, autofocus=False,
autocomplete=None, autocorrect=None, autocapitalize=None, spellcheck=None, min=None, max=None,
step=None, name=None, required=False, pattern=None, minlength=None, maxlength=None,
style=None, **kwargs):
super().__init__(style=style, label=label, value=value, type=type, placeholder=placeholder, help_text=help_text,
size=size, filled=filled, pill=pill, disabled=disabled, readonly=readonly, autofocus=autofocus,
autocomplete=autocomplete, autocorrect=autocorrect, autocapitalize=autocapitalize,
spellcheck=spellcheck, min=min, max=max,
step=step, name=name, required=required, pattern=pattern, minlength=minlength, maxlength=maxlength,
**kwargs)
def __init__(
self,
label=None,
value=None,
type="text",
placeholder=None,
help_text=None,
size=None,
filled=False,
pill=False,
disabled=False,
readonly=False,
autofocus=False,
autocomplete=None,
autocorrect=None,
autocapitalize=None,
spellcheck=None,
min=None,
max=None,
step=None,
name=None,
required=False,
pattern=None,
minlength=None,
maxlength=None,
style=None,
**kwargs,
):
super().__init__(
style=style,
label=label,
value=value,
type=type,
placeholder=placeholder,
help_text=help_text,
size=size,
filled=filled,
pill=pill,
disabled=disabled,
readonly=readonly,
autofocus=autofocus,
autocomplete=autocomplete,
autocorrect=autocorrect,
autocapitalize=autocapitalize,
spellcheck=spellcheck,
min=min,
max=max,
step=step,
name=name,
required=required,
pattern=pattern,
minlength=minlength,
maxlength=maxlength,
**kwargs,
)
class Badge(TextShoeBase):
tag = 'sl-badge'
variant = js_property('variant')
pill = js_property('pill')
pulse = js_property('pulse')
tag = "sl-badge"
variant = js_property("variant")
pill = js_property("pill")
pulse = js_property("pulse")
class Rating(ShoeBase):
tag = 'sl-rating'
label = js_property('label')
value = js_property('value')
max = js_property('max')
tag = "sl-rating"
label = js_property("label")
value = js_property("value")
max = js_property("max")
# TODO: Properties missing...
class TextArea(ShoeBase):
tag = 'sl-textarea'
label = js_property('label')
helpText = js_property('helpText')
tag = "sl-textarea"
label = js_property("label")
helpText = js_property("helpText")
# TODO: Properties missing...
class Card(TextShoeBase):
tag = 'sl-card'
def __init__(self, content=None, image=None, img_alt=None, header=None, footer=None, style=None, **kwargs):
class Card(TextShoeBase):
tag = "sl-card"
def __init__(
self,
content=None,
image=None,
img_alt=None,
header=None,
footer=None,
style=None,
**kwargs,
):
main_div = el.div()
if image:
if not isinstance(image, el.img):
@@ -223,7 +344,6 @@ class Card(TextShoeBase):
main_div.append(el.div(content))
main_div.append(content)
super().__init__(content, style=style, **kwargs)
self._js.insertBefore(image._js, self._js.firstChild)
@@ -234,19 +354,25 @@ class Card(TextShoeBase):
if footer:
self.append(el.div(footer, slot="footer"))
self.add_class('card-overview')
self.add_class("card-overview")
class Icon(ShoeBase):
tag = 'sl-icon'
tag = "sl-icon"
name = js_property('name')
src = js_property('src')
label = js_property('label')
library = js_property('library')
update_complete = js_property('updateComplete')
name = js_property("name")
src = js_property("src")
label = js_property("label")
library = js_property("library")
update_complete = js_property("updateComplete")
def __init__(
self, name=None, src=None, label=None, library=None, style=None, **kwargs
):
super().__init__(
name=name, src=src, label=label, library=library, style=style, **kwargs
)
def __init__(self, name=None, src=None, label=None, library=None, style=None, **kwargs):
super().__init__(name=name, src=src, label=label, library=library, style=style, **kwargs)
# ************* EXAMPLES SECTION *************
@@ -256,56 +382,70 @@ LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do e
Details(LOREM_IPSUM, summary="Try me")
"""
example_dialog_close_btn = Button("Close")
example_dialog = Dialog(el.div([el.p(LOREM_IPSUM), example_dialog_close_btn]), label="Try me")
example_dialog = Dialog(
el.div([el.p(LOREM_IPSUM), example_dialog_close_btn]), label="Try me"
)
example_dialog_btn = Button("Open Dialog")
def toggle_dialog():
example_dialog.open = not (example_dialog.open)
when('click', example_dialog_btn)(toggle_dialog)
when('click', example_dialog_close_btn)(toggle_dialog)
when("click", example_dialog_btn)(toggle_dialog)
when("click", example_dialog_close_btn)(toggle_dialog)
pydom.body.append(example_dialog)
examples = {
'Alert': {
"instance": Alert("This is a standard alert. You can customize its content and even the icon."),
"code": el.code("Alert('This is a standard alert. You can customize its content and even the icon.'"),
"Alert": {
"instance": Alert(
"This is a standard alert. You can customize its content and even the icon."
),
"code": el.code(
"Alert('This is a standard alert. You can customize its content and even the icon.'"
),
},
'Icon': {
"Icon": {
"instance": Icon(name="heart"),
"code": el.code('Icon(name="heart")'),
},
'Button': {
"Button": {
"instance": Button("Try me"),
"code": el.code('Button("Try me")'),
},
'Card': {
"instance": Card(el.p("This is a cool card!"), image="https://pyscript.net/assets/images/pyscript-sticker-black.svg",
footer=el.div([Button("More Info"), Rating()])),
"code": el.code('''
"Card": {
"instance": Card(
el.p("This is a cool card!"),
image="https://pyscript.net/assets/images/pyscript-sticker-black.svg",
footer=el.div([Button("More Info"), Rating()]),
),
"code": el.code(
"""
Card(el.p("This is a cool card!"), image="https://pyscript.net/assets/images/pyscript-sticker-black.svg", footer=el.div([Button("More Info"), Rating()]))
'''),
"""
),
},
'Details': {
"Details": {
"instance": Details(LOREM_IPSUM, summary="Try me"),
"code": el.code('Details(LOREM_IPSUM, summary="Try me")'),
},
'Dialog': {
"Dialog": {
"instance": example_dialog_btn,
"code": el.code('Dialog(div([p(LOREM_IPSUM), Button("Close")]), summary="Try me")'),
"code": el.code(
'Dialog(div([p(LOREM_IPSUM), Button("Close")]), summary="Try me")'
),
},
'Divider': {
"Divider": {
"instance": Divider(),
"code": el.code('Divider()'),
"code": el.code("Divider()"),
},
'Rating': {
"Rating": {
"instance": Rating(),
"code": el.code('Rating()'),
"code": el.code("Rating()"),
},
}
# Load resources...
# <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/themes/light.css" />
# <script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/shoelace-autoloader.js"></script>
@@ -325,4 +465,4 @@ def load_resources(parent=None):
type="module",
),
)
print("Resources loaded!")
print("Resources loaded!")

View File

@@ -1,11 +1,13 @@
from pyweb import pydom
from pyscript import when, window
from textwrap import dedent
from pyscript import when, window
from pyweb import pydom
from pyweb.ui import elements as el
from pyweb.ui import shoelace
# 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"}
@@ -13,46 +15,54 @@ STYLE_CODE_BLOCK = {"text-align": "left", "background-color": "#eee", "padding":
# 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
# 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']
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 = 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),
el.div(shoelace.examples[component]["code"], style=STYLE_CODE_BLOCK),
summary="View Code",
style={'background-color': 'gainsboro'}
style={"background-color": "gainsboro"},
)
)
div.append(example_div)
@@ -61,21 +71,25 @@ def create_component_details(component):
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'})
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)
when("click", div)(_change)
print("adding component", component)
parent_div.append(div)
return div
@@ -83,25 +97,29 @@ def add_component_section(component, parent_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"""
widget_code = Markdown(
dedent(
f"""
```python
{code}
```
"""))
"""
)
)
grid.append(el.div(widget_code, style=STYLE_CODE_BLOCK))
return grid
@@ -109,93 +127,122 @@ def create_example_grid(widget, code):
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.h1(
"Welcome to PyDom UI!",
style={"text-align": "center", "margin": "20px auto 30px"},
)
)
div.append(el.h2("What is PyShoes?"))
div.append(Markdown(dedent("""\
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("""\
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")
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'})
result_div = el.div(
style={
"margin-top": "20px",
"min-height": "200px",
"background-color": "cornsilk",
}
)
@when('click', translate_button)
@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,
])
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!"))""")
# btn_code = dedent("""btn = button("Click me!"})
# when('click', btn)(lambda: window.alert("Clicked!"))""")
# div.append(create_example_grid(btn, btn_code))
# 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)
# # 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.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))
# # 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:"))
@@ -203,10 +250,12 @@ def create_basic_components_page():
# Buttons
div.append(el.h3("Buttons"))
btn = el.button("Click me!")
when('click', btn)(lambda: window.alert("Clicked!"))
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_example_grid(btn, btn_code))
@@ -214,71 +263,105 @@ when('click', btn)(lambda: window.alert("Clicked!"))""")
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'}))
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)
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'})
_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%'})
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'})
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'}))
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_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'}))
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)
when("click", left_panel_title)(restore_home)
# BASIC COMPONENTS
basic_components_text = el.h3("Basic Components", style={'text-align': 'left', 'margin': '20px auto 0'})
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'}))
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)
when("click", basic_components_text)(basic_components)
# MARKDOWN COMPONENTS
markdown_title = create_new_section("Markdown", left_div)
when('click', markdown_title)(markdown_components)
when("click", markdown_title)(markdown_components)
# SHOELACE COMPONENTS
shoe_components_text = el.h3("Shoe Components", style={'text-align': 'left', 'margin': '20px auto 0'})
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'}))
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)

View File

@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="../../dist/core.css">
<script type="module" src="../../dist/core.js"></script>
<script type="module" src="../../dist/core.js"></script>
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/themes/light.css" />
@@ -19,11 +19,11 @@
.card-overview {
max-width: 300px;
}
.card-overview small {
color: var(--sl-color-neutral-500);
}
.card-overview [slot='footer'] {
display: flex;
justify-content: space-between;
@@ -41,4 +41,4 @@
<body>
<script type="py" src="./demo.py" config="./pyscript.toml"></script>
</body>
</html>
</html>