refactor: allow Checkbox and Radio primitives to render headlessly without labels

This commit is contained in:
2026-06-09 20:42:57 +02:00
parent 00758d6a50
commit 7fc29fccb8
2 changed files with 22 additions and 11 deletions
+12 -10
View File
@@ -403,7 +403,7 @@ def Label(
def Checkbox( def Checkbox(
name: str, name: str,
label: str, label: str | None = None,
checked: bool = False, checked: bool = False,
value: str = "1", value: str = "1",
attributes: list[HTMLAttribute] | None = None, attributes: list[HTMLAttribute] | None = None,
@@ -421,20 +421,21 @@ def Checkbox(
if checked: if checked:
input_attrs.append(("checked", "true")) input_attrs.append(("checked", "true"))
input_el = Input(type="checkbox", attributes=input_attrs)
if label is None:
return input_el
return Label( return Label(
attributes=[ attributes=[
("class", "flex items-center gap-2 text-sm text-heading cursor-pointer") ("class", "flex items-center gap-2 text-sm text-heading cursor-pointer")
], ],
children=[ children=[input_el, label],
Input(type="checkbox", attributes=input_attrs),
label,
],
) )
def Radio( def Radio(
name: str, name: str,
label: str, label: str | None = None,
checked: bool = False, checked: bool = False,
value: str = "", value: str = "",
attributes: list[HTMLAttribute] | None = None, attributes: list[HTMLAttribute] | None = None,
@@ -452,14 +453,15 @@ def Radio(
if checked: if checked:
input_attrs.append(("checked", "true")) input_attrs.append(("checked", "true"))
input_el = Input(type="radio", attributes=input_attrs)
if label is None:
return input_el
return Label( return Label(
attributes=[ attributes=[
("class", "flex items-center gap-1.5 text-sm text-heading cursor-pointer") ("class", "flex items-center gap-1.5 text-sm text-heading cursor-pointer")
], ],
children=[ children=[input_el, label],
Input(type="radio", attributes=input_attrs),
label,
],
) )
+10 -1
View File
@@ -827,13 +827,22 @@ from common.components.primitives import Checkbox, Radio
class ComponentPrimitivesTest(SimpleTestCase): class ComponentPrimitivesTest(SimpleTestCase):
def test_checkbox_primitive(self): def test_checkbox_primitive(self):
html = Checkbox(name="test-check", label="Accept Terms", checked=True, value="yes") html = Checkbox(
name="test-check", label="Accept Terms", checked=True, value="yes"
)
self.assertIn('type="checkbox"', html) self.assertIn('type="checkbox"', html)
self.assertIn('name="test-check"', html) self.assertIn('name="test-check"', html)
self.assertIn('value="yes"', html) self.assertIn('value="yes"', html)
self.assertIn('checked="true"', html) self.assertIn('checked="true"', html)
self.assertIn("Accept Terms", html) self.assertIn("Accept Terms", html)
def test_checkbox_headless(self):
html = Checkbox(name="test-headless", label=None, checked=True)
self.assertNotIn("<label", html)
self.assertIn("<input", html)
self.assertIn('type="checkbox"', html)
self.assertIn('name="test-headless"', html)
def test_radio_primitive(self): def test_radio_primitive(self):
html = Radio(name="test-radio", label="Option A", checked=False, value="A") html = Radio(name="test-radio", label="Option A", checked=False, value="A")
self.assertIn('type="radio"', html) self.assertIn('type="radio"', html)