Added TestableCheckbox

This commit is contained in:
2025-10-31 21:49:12 +01:00
parent 3721bb7ad7
commit 991a6f07ff
12 changed files with 306 additions and 18 deletions

View File

@@ -0,0 +1,15 @@
.mf-icon-20 {
width: 20px;
min-width: 20px;
height: 20px;
margin-top: auto;
margin-bottom: auto;
}
.mf-icon-16 {
width: 16px;
min-width: 16px;
height: 16px;
margin-top: auto;
margin-bottom: 4px;
}

View File

@@ -0,0 +1,33 @@
from fasthtml.components import *
from myfasthtml.core.commands import Command
from myfasthtml.core.utils import merge_classes
class mk:
@staticmethod
def button(element, command: Command = None, **kwargs):
return mk.manage_command(Button(element, **kwargs), command)
@staticmethod
def icon(icon, size=20,
can_select=True,
can_hover=False,
cls='',
command: Command = None,
**kwargs):
merged_cls = merge_classes(f"mf-icon-{size}",
'icon-btn' if can_select else '',
'mmt-btn' if can_hover else '',
cls,
kwargs)
return mk.manage_command(Div(icon, cls=merged_cls, **kwargs), command)
@staticmethod
def manage_command(ft, command: Command):
htmx = command.get_htmx_params() if command else {}
ft.attrs |= htmx
return ft

View File

View File

@@ -0,0 +1,26 @@
from fasthtml import serve
from myfasthtml.controls.helpers import mk
from myfasthtml.core.commands import Command
from myfasthtml.myfastapp import create_app
# Define a simple command action
def say_hello():
return "Hello, FastHtml!"
# Create the command
hello_command = Command("say_hello", "Responds with a greeting", say_hello)
# Create the app
app, rt = create_app(protect_routes=False)
@rt("/")
def get_homepage():
return mk.button("Click Me!", command=hello_command)
if __name__ == "__main__":
serve(port=5002)

View File

@@ -0,0 +1,25 @@
from fasthtml import serve
from fasthtml.components import *
from myfasthtml.controls.helpers import mk
from myfasthtml.core.commands import Command
from myfasthtml.icons.fa import icon_home
from myfasthtml.myfastapp import create_app
app, rt = create_app(protect_routes=False)
def change_text():
return "New text"
command = Command("change_text", "change the text", change_text).htmx(target="#text")
@rt("/")
def index():
return mk.button(Div(mk.icon(icon_home), Div("Hello World", id="text"), cls="flex"), command=command)
if __name__ == "__main__":
serve(port=5002)

View File

@@ -0,0 +1,15 @@
from fasthtml import serve
from fasthtml.components import *
from myfasthtml.myfastapp import create_app
app, rt = create_app(protect_routes=False)
@rt("/")
def get_homepage():
return Div("Hello, FastHtml!")
if __name__ == "__main__":
serve(port=5002)

View File

View File

@@ -345,10 +345,6 @@ class TestableElement:
elif options:
self.fields[name] = options[0]['value']
def _get_my_ft(self, element: Tag):
_inner = element.find(self.tag) if self.tag and self.tag != element.name else element
return MyFT(_inner.name, _inner.attrs)
@staticmethod
def _get_input_identifier(input_field, counter):
"""
@@ -432,14 +428,6 @@ class TestableElement:
# Default to string
return value
@staticmethod
def _get_element(html_fragment: str):
html_fragment = html_fragment.strip()
if (not html_fragment.startswith('<div') and
not html_fragment.startswith('<form')):
html_fragment = "<div>" + html_fragment + "</div>"
return BeautifulSoup(html_fragment, 'html.parser').find()
@staticmethod
def _parse(tag, html_fragment: str):
elt = BeautifulSoup(html_fragment, 'html.parser')
@@ -801,8 +789,8 @@ class TestableForm(TestableElement):
# return value
class TestableInput(TestableElement):
def __init__(self, client, source):
class TestableControl(TestableElement):
def __init__(self, client, source, tag):
super().__init__(client, source, "input")
assert len(self.fields) <= 1
self._input_name = next(iter(self.fields))
@@ -815,12 +803,40 @@ class TestableInput(TestableElement):
def value(self):
return self.fields[self._input_name]
def _send_value(self):
if self._input_name and self._support_htmx():
return self._send_htmx_request(data={self._input_name: self.value})
return None
class TestableInput(TestableControl):
def __init__(self, client, source):
super().__init__(client, source, "input")
def send(self, value):
self.fields[self.name] = value
if self.name and self._support_htmx():
return self._send_htmx_request(data={self.name: self.value})
return None
return self._send_value()
class TestableCheckbox(TestableControl):
def __init__(self, client, source):
super().__init__(client, source, "input")
@property
def is_checked(self):
return self.fields[self._input_name] == True
def check(self):
self.fields[self._input_name] = True
return self._send_value()
def uncheck(self):
self.fields[self._input_name] = False
return self._send_value()
def toggle(self):
self.fields[self._input_name] = not self.fields[self._input_name]
return self._send_value()
# def get_value(tag):