mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-20 02:37:41 -05:00
969 lines
17 KiB
Python
969 lines
17 KiB
Python
from textwrap import dedent
|
|
|
|
from pyweb import JSProperty, js_property, pydom
|
|
|
|
from pyscript import document, when, window
|
|
|
|
# Global attributes that all elements have (this list is a subset of the official one)
|
|
# and tries to capture the most used ones
|
|
GLOBAL_ATTRIBUTES = [
|
|
"accesskey",
|
|
"autofocus",
|
|
"autocapitalize",
|
|
"className",
|
|
"contenteditable",
|
|
"draggable",
|
|
"enterkeyhint",
|
|
"hidden",
|
|
"id",
|
|
"lang",
|
|
"nonce",
|
|
"part",
|
|
"popover",
|
|
"slot",
|
|
"spellcheck",
|
|
"tabindex",
|
|
"title",
|
|
"translate",
|
|
"virtualkeyboardpolicy",
|
|
]
|
|
|
|
# class and style are different ones that are handled by pydom.element directly
|
|
CUSTOM_ATTRIBUTES = {
|
|
"a": ["download", "href", "referrerpolicy", "rel", "target", "type"],
|
|
"td": ["colspan", "headers", "rowspan"],
|
|
"template": ["shadowrootmode"],
|
|
"textarea": [
|
|
"autocapitalize",
|
|
"autocomplete",
|
|
"autofocus",
|
|
"cols",
|
|
"dirname",
|
|
"disabled",
|
|
"form",
|
|
"maxlength",
|
|
"minlength",
|
|
"name",
|
|
"placeholder",
|
|
"readonly",
|
|
"required",
|
|
"rows",
|
|
"spellcheck",
|
|
"wrap",
|
|
],
|
|
"tr": ["abbr", "colspan", "headers", "rowspan", "scope"],
|
|
"time": ["datetime"],
|
|
"video": [
|
|
"autoplay",
|
|
"controls",
|
|
"crossorigin",
|
|
"disablepictureinpicture",
|
|
"disableremoteplayback",
|
|
"height",
|
|
"loop",
|
|
"muted",
|
|
"playsinline",
|
|
"poster",
|
|
"preload",
|
|
"src",
|
|
"width",
|
|
],
|
|
}
|
|
|
|
|
|
class ElementBase(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 isinstance(style, dict):
|
|
for key, value in style.items():
|
|
self.style[key] = value
|
|
elif style is None:
|
|
pass
|
|
else:
|
|
raise ValueError(
|
|
f"Style should be a dictionary, received {style} (type {type(style)}) instead."
|
|
)
|
|
|
|
# IMPORTANT!!! This is used to auto-harvest all input arguments and set them as properties
|
|
self._init_properties(**kwargs)
|
|
|
|
def _init_properties(self, **kwargs):
|
|
"""Set all the properties (of type JSProperties) provided in input as properties
|
|
of the class instance.
|
|
|
|
Args:
|
|
**kwargs: The properties to set
|
|
"""
|
|
# 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])
|
|
|
|
|
|
class TextElementBase(ElementBase):
|
|
def __init__(self, content=None, style=None, **kwargs):
|
|
super().__init__(style=style, **kwargs)
|
|
|
|
# If it's an element, append the element
|
|
if isinstance(content, pydom.Element):
|
|
self.append(content)
|
|
# If it's a list of elements
|
|
elif isinstance(content, list):
|
|
for item in content:
|
|
self.append(item)
|
|
# If the content wasn't set just ignore
|
|
elif content is None:
|
|
pass
|
|
else:
|
|
# Otherwise, set content as the html of the element
|
|
self.html = content
|
|
|
|
|
|
def _add_js_properties(cls, *attrs):
|
|
"""Add JSProperties to a class as `js_property` class attributes."""
|
|
# 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))
|
|
|
|
# Now we patch the __init__ method to specify the properties
|
|
cls.__init__.__doc__ = f"""Class constructor.
|
|
Official documentation: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/{cls.tag}
|
|
|
|
Args:
|
|
|
|
* content: The content of the element (can be a string, a list of elements or a single element)
|
|
* style: The style of the element (a dictionary)
|
|
* All the properties of the class: {attrs} (see the official documentation for more details)
|
|
|
|
"""
|
|
|
|
|
|
# IMPORTANT: For all HTML components defined below, we are not mapping all
|
|
# available attributes, only the global ones
|
|
|
|
|
|
class a(TextElementBase):
|
|
tag = "a"
|
|
|
|
|
|
# # Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attributes
|
|
_add_js_properties(a, "download", "href", "referrerpolicy", "rel", "target", "type")
|
|
|
|
|
|
class abbr(TextElementBase):
|
|
tag = "abbr"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(abbr)
|
|
|
|
|
|
class address(TextElementBase):
|
|
tag = "address"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(address)
|
|
|
|
|
|
class area(ElementBase):
|
|
tag = "area"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(
|
|
area,
|
|
"alt",
|
|
"coords",
|
|
"download",
|
|
"href",
|
|
"ping",
|
|
"referrerpolicy",
|
|
"rel",
|
|
"shape",
|
|
"target",
|
|
)
|
|
|
|
|
|
class article(TextElementBase):
|
|
tag = "article"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(article)
|
|
|
|
|
|
class aside(TextElementBase):
|
|
tag = "aside"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(aside)
|
|
|
|
|
|
class audio(ElementBase):
|
|
tag = "audio"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(
|
|
audio,
|
|
"autoplay",
|
|
"controls",
|
|
"controlslist",
|
|
"crossorigin",
|
|
"disableremoteplayback",
|
|
"loop",
|
|
"muted",
|
|
"preload",
|
|
"src",
|
|
)
|
|
|
|
|
|
class b(TextElementBase):
|
|
tag = "b"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(b)
|
|
|
|
|
|
class blockquote(TextElementBase):
|
|
tag = "blockquote"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(blockquote, "cite")
|
|
|
|
|
|
class br(ElementBase):
|
|
tag = "br"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(br)
|
|
|
|
|
|
class button(TextElementBase):
|
|
tag = "button"
|
|
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes
|
|
_add_js_properties(
|
|
button,
|
|
"autofocus",
|
|
"disabled",
|
|
"form",
|
|
"formaction",
|
|
"formenctype",
|
|
"formmethod",
|
|
"formnovalidate",
|
|
"formtarget",
|
|
"name",
|
|
"type",
|
|
"value",
|
|
)
|
|
|
|
|
|
class canvas(TextElementBase):
|
|
tag = "canvas"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(canvas, "height", "width")
|
|
|
|
|
|
class caption(TextElementBase):
|
|
tag = "caption"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(caption)
|
|
|
|
|
|
class cite(TextElementBase):
|
|
tag = "cite"
|
|
|
|
|
|
# br tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(cite)
|
|
|
|
|
|
class code(TextElementBase):
|
|
tag = "code"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(code)
|
|
|
|
|
|
class data(TextElementBase):
|
|
tag = "data"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(data, "value")
|
|
|
|
|
|
class datalist(TextElementBase):
|
|
tag = "datalist"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(datalist)
|
|
|
|
|
|
class dd(TextElementBase):
|
|
tag = "dd"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(dd)
|
|
|
|
|
|
class del_(TextElementBase):
|
|
tag = "del"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(del_, "cite", "datetime")
|
|
|
|
|
|
class details(TextElementBase):
|
|
tag = "details"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(details, "open")
|
|
|
|
|
|
class dialog(TextElementBase):
|
|
tag = "dialog"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(dialog, "open")
|
|
|
|
|
|
class div(TextElementBase):
|
|
tag = "div"
|
|
|
|
|
|
# div tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(div)
|
|
|
|
|
|
class dl(TextElementBase):
|
|
tag = "dl"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(dl, "value")
|
|
|
|
|
|
class dt(TextElementBase):
|
|
tag = "dt"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(dt)
|
|
|
|
|
|
class em(TextElementBase):
|
|
tag = "em"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(em)
|
|
|
|
|
|
class embed(TextElementBase):
|
|
tag = "embed"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(embed, "height", "src", "type", "width")
|
|
|
|
|
|
class fieldset(TextElementBase):
|
|
tag = "fieldset"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(fieldset, "disabled", "form", "name")
|
|
|
|
|
|
class figcaption(TextElementBase):
|
|
tag = "figcaption"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(figcation)
|
|
|
|
|
|
class figure(TextElementBase):
|
|
tag = "figure"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(figure)
|
|
|
|
|
|
class footer(TextElementBase):
|
|
tag = "footer"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(footer)
|
|
|
|
|
|
class form(TextElementBase):
|
|
tag = "form"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(
|
|
form,
|
|
"accept-charset",
|
|
"action",
|
|
"autocapitalize",
|
|
"autocomplete",
|
|
"enctype",
|
|
"name",
|
|
"method",
|
|
"nonvalidate",
|
|
"rel",
|
|
"target",
|
|
)
|
|
|
|
|
|
class h1(TextElementBase):
|
|
tag = "h1"
|
|
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements#attributes
|
|
# Heading elements only have global attributes
|
|
_add_js_properties(h1)
|
|
|
|
|
|
class h2(TextElementBase):
|
|
tag = "h2"
|
|
|
|
|
|
_add_js_properties(h2)
|
|
|
|
|
|
class h3(TextElementBase):
|
|
tag = "h3"
|
|
|
|
|
|
_add_js_properties(h3)
|
|
|
|
|
|
class h4(TextElementBase):
|
|
tag = "h4"
|
|
|
|
|
|
_add_js_properties(h4)
|
|
|
|
|
|
class h5(TextElementBase):
|
|
tag = "h5"
|
|
|
|
|
|
_add_js_properties(h5)
|
|
|
|
|
|
class h6(TextElementBase):
|
|
tag = "h6"
|
|
|
|
|
|
_add_js_properties(h6)
|
|
|
|
|
|
class header(TextElementBase):
|
|
tag = "header"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(header)
|
|
|
|
|
|
class hgroup(TextElementBase):
|
|
tag = "hgroup"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(hgroup)
|
|
|
|
|
|
class hr(TextElementBase):
|
|
tag = "hr"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(hr)
|
|
|
|
|
|
class i(TextElementBase):
|
|
tag = "i"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(i)
|
|
|
|
|
|
class iframe(TextElementBase):
|
|
tag = "iframe"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(
|
|
iframe,
|
|
"allow",
|
|
"allowfullscreen",
|
|
"height",
|
|
"loading",
|
|
"name",
|
|
"referrerpolicy",
|
|
"sandbox",
|
|
"src",
|
|
"srcdoc",
|
|
"width",
|
|
)
|
|
|
|
|
|
class img(ElementBase):
|
|
tag = "img"
|
|
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attributes
|
|
_add_js_properties(
|
|
img,
|
|
"alt",
|
|
"crossorigin",
|
|
"decoding",
|
|
"fetchpriority",
|
|
"height",
|
|
"ismap",
|
|
"loading",
|
|
"referrerpolicy",
|
|
"sizes",
|
|
"src",
|
|
"width",
|
|
)
|
|
|
|
|
|
# NOTE: Input is a reserved keyword in Python, so we use input_ instead
|
|
class input_(ElementBase):
|
|
tag = "input"
|
|
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attributes
|
|
_add_js_properties(
|
|
input_,
|
|
"accept",
|
|
"alt",
|
|
"autofocus",
|
|
"capture",
|
|
"checked",
|
|
"dirname",
|
|
"disabled",
|
|
"form",
|
|
"formaction",
|
|
"formenctype",
|
|
"formmethod",
|
|
"formnovalidate",
|
|
"formtarget",
|
|
"height",
|
|
"list",
|
|
"max",
|
|
"maxlength",
|
|
"min",
|
|
"minlength",
|
|
"multiple",
|
|
"name",
|
|
"pattern",
|
|
"placeholder",
|
|
"popovertarget",
|
|
"popovertargetaction",
|
|
"readonly",
|
|
"required",
|
|
"size",
|
|
"src",
|
|
"step",
|
|
"type",
|
|
"value",
|
|
"width",
|
|
)
|
|
|
|
|
|
class ins(TextElementBase):
|
|
tag = "ins"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(ins, "cite", "datetime")
|
|
|
|
|
|
class kbd(TextElementBase):
|
|
tag = "kbd"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(kbd)
|
|
|
|
|
|
class label(TextElementBase):
|
|
tag = "label"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(label, "for")
|
|
|
|
|
|
class legend(TextElementBase):
|
|
tag = "legend"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(legend)
|
|
|
|
|
|
class li(TextElementBase):
|
|
tag = "li"
|
|
|
|
|
|
# code tags only have the global attributes ones
|
|
_add_js_properties(li, "value")
|
|
|
|
|
|
class link(TextElementBase):
|
|
tag = "link"
|
|
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attributes
|
|
_add_js_properties(
|
|
link,
|
|
"as",
|
|
"crossorigin",
|
|
"disabled",
|
|
"fetchpriority",
|
|
"href",
|
|
"imagesizes",
|
|
"imagesrcset",
|
|
"integrity",
|
|
"media",
|
|
"rel",
|
|
"referrerpolicy",
|
|
"sizes",
|
|
"title",
|
|
"type",
|
|
)
|
|
|
|
|
|
class main(TextElementBase):
|
|
tag = "main"
|
|
|
|
|
|
_add_js_properties(main)
|
|
|
|
|
|
class map_(TextElementBase):
|
|
tag = "map"
|
|
|
|
|
|
_add_js_properties(map_, "name")
|
|
|
|
|
|
class mark(TextElementBase):
|
|
tag = "mark"
|
|
|
|
|
|
_add_js_properties(mark)
|
|
|
|
|
|
class menu(TextElementBase):
|
|
tag = "menu"
|
|
|
|
|
|
_add_js_properties(menu)
|
|
|
|
|
|
class map_(TextElementBase):
|
|
tag = "map"
|
|
|
|
|
|
_add_js_properties(map_, "name")
|
|
|
|
|
|
class meter(TextElementBase):
|
|
tag = "meter"
|
|
|
|
|
|
_add_js_properties(meter, "form", "high", "low", "max", "min", "optimum", "value")
|
|
|
|
|
|
class nav(TextElementBase):
|
|
tag = "nav"
|
|
|
|
|
|
_add_js_properties(nav)
|
|
|
|
|
|
class object_(TextElementBase):
|
|
tag = "object"
|
|
|
|
|
|
_add_js_properties(object_, "data", "form", "height", "name", "type", "usemap", "width")
|
|
|
|
|
|
class ol(TextElementBase):
|
|
tag = "ol"
|
|
|
|
|
|
_add_js_properties(ol, "reversed", "start", "type")
|
|
|
|
|
|
class optgroup(TextElementBase):
|
|
tag = "optgroup"
|
|
|
|
|
|
_add_js_properties(optgroup, "disabled", "label")
|
|
|
|
|
|
class option(TextElementBase):
|
|
tag = "option"
|
|
|
|
|
|
_add_js_properties(option, "disabled", "label", "selected", "value")
|
|
|
|
|
|
class output(TextElementBase):
|
|
tag = "output"
|
|
|
|
|
|
_add_js_properties(output, "for", "form", "name")
|
|
|
|
|
|
class p(TextElementBase):
|
|
tag = "p"
|
|
|
|
|
|
# p tags only have the global attributes ones
|
|
_add_js_properties(p)
|
|
|
|
|
|
class picture(TextElementBase):
|
|
tag = "picture"
|
|
|
|
|
|
_add_js_properties(picture)
|
|
|
|
|
|
class pre(TextElementBase):
|
|
tag = "pre"
|
|
|
|
|
|
# pre tags only have the global attributes ones (others have been deprecated)
|
|
_add_js_properties(pre)
|
|
|
|
|
|
class progress(TextElementBase):
|
|
tag = "progress"
|
|
|
|
|
|
_add_js_properties(progress, "max", "value")
|
|
|
|
|
|
class q(TextElementBase):
|
|
tag = "q"
|
|
|
|
|
|
_add_js_properties(q, "cite")
|
|
|
|
|
|
class nav(TextElementBase):
|
|
tag = "nav"
|
|
|
|
|
|
_add_js_properties(nav)
|
|
|
|
|
|
class s(TextElementBase):
|
|
tag = "s"
|
|
|
|
|
|
_add_js_properties(s)
|
|
|
|
|
|
class script(TextElementBase):
|
|
tag = "script"
|
|
|
|
# Let's add async manually since it's a reserved keyword in Python
|
|
async_ = js_property("async")
|
|
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attributes
|
|
_add_js_properties(
|
|
script,
|
|
"blocking",
|
|
"crossorigin",
|
|
"defer",
|
|
"fetchpriority",
|
|
"integrity",
|
|
"nomodule",
|
|
"nonce",
|
|
"referrerpolicy",
|
|
"src",
|
|
"type",
|
|
)
|
|
|
|
|
|
class section(TextElementBase):
|
|
tag = "section"
|
|
|
|
|
|
_add_js_properties(section)
|
|
|
|
|
|
class select(TextElementBase):
|
|
tag = "select"
|
|
|
|
|
|
_add_js_properties(select)
|
|
|
|
|
|
class small(TextElementBase):
|
|
tag = "small"
|
|
|
|
|
|
# small tags only have the global attributes ones
|
|
_add_js_properties(small)
|
|
|
|
|
|
class source(TextElementBase):
|
|
tag = "source"
|
|
|
|
|
|
_add_js_properties(source, "type", "src", "srcset", "sizes", "media")
|
|
|
|
|
|
class span(TextElementBase):
|
|
tag = "span"
|
|
|
|
|
|
class strong(TextElementBase):
|
|
tag = "strong"
|
|
|
|
|
|
# strong tags only have the global attributes ones
|
|
_add_js_properties(strong)
|
|
|
|
|
|
class style(TextElementBase):
|
|
tag = "style"
|
|
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style#attributes
|
|
_add_js_properties(style, "blocking", "media", "nonce", "title")
|
|
|
|
|
|
class sub(TextElementBase):
|
|
tag = "sub"
|
|
|
|
|
|
class summary(TextElementBase):
|
|
tag = "summary"
|
|
|
|
|
|
class sup(TextElementBase):
|
|
tag = "sup"
|
|
|
|
|
|
class table(TextElementBase):
|
|
tag = "table"
|
|
|
|
|
|
class tbody(TextElementBase):
|
|
tag = "tbody"
|
|
|
|
|
|
class td(TextElementBase):
|
|
tag = "td"
|
|
|
|
|
|
class template(TextElementBase):
|
|
tag = "template"
|
|
|
|
|
|
class textarea(TextElementBase):
|
|
tag = "textarea"
|
|
|
|
|
|
class tfoot(TextElementBase):
|
|
tag = "tfoot"
|
|
|
|
|
|
class th(TextElementBase):
|
|
tag = "th"
|
|
|
|
|
|
class thead(TextElementBase):
|
|
tag = "thead"
|
|
|
|
|
|
class time(TextElementBase):
|
|
tag = "time"
|
|
|
|
|
|
class title(TextElementBase):
|
|
tag = "title"
|
|
|
|
|
|
class tr(TextElementBase):
|
|
tag = "tr"
|
|
|
|
|
|
class track(TextElementBase):
|
|
tag = "track"
|
|
|
|
|
|
class u(TextElementBase):
|
|
tag = "u"
|
|
|
|
|
|
class ul(TextElementBase):
|
|
tag = "ul"
|
|
|
|
|
|
class var(TextElementBase):
|
|
tag = "var"
|
|
|
|
|
|
class video(TextElementBase):
|
|
tag = "video"
|
|
|
|
|
|
# Custom Elements
|
|
class grid(TextElementBase):
|
|
tag = "div"
|
|
|
|
def __init__(self, layout, content=None, gap=None, **kwargs):
|
|
super().__init__(content, **kwargs)
|
|
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
|