mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-21 11:15:36 -05:00
397 lines
10 KiB
Python
397 lines
10 KiB
Python
import string
|
|
from textwrap import dedent
|
|
|
|
from pyscript import document, when, window
|
|
from pyweb import JSProperty, js_property, pydom
|
|
from pyweb.ui import elements as el
|
|
|
|
|
|
class ShoeBase(pydom.Element):
|
|
tag = "div"
|
|
|
|
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
|
|
self._init_properties(**kwargs)
|
|
|
|
@staticmethod
|
|
def _init_properties(**kwargs):
|
|
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__}...")
|
|
for attr_name, attr in self.__class__.__dict__.items():
|
|
# print("Checking", attr_name, isinstance(attr, ShoelaceProperty), attr_name in kwargs)
|
|
# 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])
|
|
|
|
|
|
class TextShoeBase(ShoeBase):
|
|
def __init__(self, content, style=None, **kwargs):
|
|
if not style and getattr(self, "default_style", None):
|
|
style = self.default_style
|
|
|
|
super().__init__(style=style, **kwargs)
|
|
|
|
if isinstance(content, pydom.Element):
|
|
self.append(content)
|
|
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,
|
|
):
|
|
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.")
|
|
"""
|
|
|
|
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]
|
|
)
|
|
self.html = html_
|
|
print("options", options)
|
|
print("HTML", html_)
|
|
print("HTML", self.html)
|
|
# 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,
|
|
)
|
|
|
|
|
|
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,
|
|
)
|
|
|
|
|
|
class Dialog(TextShoeBase):
|
|
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
|
|
)
|
|
|
|
|
|
class Divider(ShoeBase):
|
|
tag = "sl-divider"
|
|
|
|
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):
|
|
return self._js.label
|
|
|
|
@label.setter
|
|
def label(self, value):
|
|
self._js.label = value
|
|
|
|
|
|
# class LabelProperty:
|
|
# def __get__(self, obj, objtype=None):
|
|
# return obj._js.label
|
|
|
|
# def __set__(self, obj, value):
|
|
# obj._js.label = value
|
|
|
|
|
|
class PlaceholderProperty:
|
|
def __get__(self, obj, objtype=None):
|
|
return obj._js.placeholder
|
|
|
|
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")
|
|
|
|
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")
|
|
|
|
|
|
class Rating(ShoeBase):
|
|
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")
|
|
# 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,
|
|
):
|
|
main_div = el.div()
|
|
if image:
|
|
if not isinstance(image, el.img):
|
|
image = el.img(image, alt=img_alt)
|
|
|
|
image.slot = "image"
|
|
|
|
if content:
|
|
if isinstance(content, pydom.Element):
|
|
main_div.append(content)
|
|
else:
|
|
main_div.append(el.div(content))
|
|
main_div.append(content)
|
|
|
|
super().__init__(content, style=style, **kwargs)
|
|
self._js.insertBefore(image._js, self._js.firstChild)
|
|
|
|
if header:
|
|
header = el.div(header, slot="header")
|
|
self._js.insertBefore(header._js, self._js.firstChild)
|
|
|
|
if footer:
|
|
self.append(el.div(footer, slot="footer"))
|
|
|
|
self.add_class("card-overview")
|
|
|
|
|
|
class Icon(ShoeBase):
|
|
tag = "sl-icon"
|
|
|
|
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
|
|
)
|
|
|
|
|
|
# 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>
|
|
def load_resources(parent=None):
|
|
print("Loading resources...")
|
|
if parent is None:
|
|
parent = pydom.body
|
|
parent.append(
|
|
el.link(
|
|
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/themes/light.css",
|
|
rel="stylesheet",
|
|
)
|
|
)
|
|
parent.append(
|
|
el.script(
|
|
src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/shoelace-autoloader.js",
|
|
type="module",
|
|
),
|
|
)
|
|
print("Resources loaded!")
|