Created
March 25, 2024 22:59
-
-
Save bessey/36bb432288fc268a7ea59131509f8132 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Any, Callable, Self | |
from htpy import ( | |
Element, | |
Node, | |
Iterator, | |
Attribute, | |
_id_class_names_from_css_str, | |
_kwarg_attribute_name, | |
div, | |
button, | |
span, | |
) | |
from markupsafe import Markup as _Markup | |
class Component(Element): | |
def __init__( | |
self, func: Callable[[Any], Any], attrs: dict[str, Attribute], children: Node | |
) -> None: | |
self._name = func.__name__ | |
self._func = func | |
self._attrs = attrs | |
self._children = children | |
def __iter__(self) -> Iterator[str]: | |
yield from self._func(**self._attrs, children=self._children) | |
def __call__(self, *args: Any, **kwargs: Any) -> Self: | |
id_class = "" | |
attrs: dict[str, Attribute] = {} | |
if len(args) == 1: | |
if isinstance(args[0], str): | |
# element(".foo") | |
id_class = args[0] | |
attrs = {} | |
else: | |
# element({"foo": "bar"}) | |
id_class = "" | |
attrs = args[0] | |
elif len(args) == 2: | |
# element(".foo", {"bar": "baz"}) | |
id_class, attrs = args | |
return self.__class__( | |
self._func, | |
{ | |
**self._attrs, | |
**(_id_class_names_from_css_str(id_class) if id_class else {}), | |
**attrs, | |
**{_kwarg_attribute_name(k): v for k, v in kwargs.items()}, | |
}, | |
self._children, | |
) | |
def __getitem__(self, children: Node) -> Self: | |
return self.__class__(self._func, self._attrs, children) | |
def component(func): | |
return Component(func, {}, None) | |
@component | |
def bootstrap_modal(*, children: Node) -> Element: | |
return div(".modal", tabindex="-1", role="dialog")[ | |
div(".modal-dialog", role="document")[div(".modal-content")[children]] | |
] | |
@component | |
def bootstrap_header(*, closeable: bool, children: Node) -> Element: | |
close_button = button( | |
".close", | |
type="button", | |
data_dismiss="modal", | |
aria_label="Close", | |
)[span(aria_hidden="true")[_Markup("×")]] | |
return div(".modal-header")[ | |
div(".modal-title")[ | |
children, | |
close_button if closeable else None, | |
] | |
] | |
@component | |
def bootstrap_body(*, children: Node) -> Element: | |
return div(".modal-body")[children] | |
@component | |
def bootstrap_footer(*, children: Node) -> Element: | |
return div(".modal-footer")[children] | |
print( | |
bootstrap_modal[ | |
bootstrap_header(closeable=True)["Hello, World!"], | |
bootstrap_body["Lorem ipsum"], | |
bootstrap_footer["Etc!"], | |
] | |
) | |
# <div class="modal" tabindex="-1" role="dialog"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><div class="modal-title">Hello, World!<button class="close" type="button" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div></div><div class="modal-body">Lorem ipsum</div><div class="modal-footer">Etc!</div></div></div></div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment