Coverage for src / lexigram / ui / atoms / fieldset.py: 43%
14 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-10 04:11 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-10 04:11 +0800
1from __future__ import annotations
3from typing import Any
5from lexigram.ui.core.base import Component, el, raw, render_to_string
8class Fieldset(Component):
9 """
10 Native fieldset component for grouping form fields with a legend.
12 Args:
13 legend: The title of the fieldset
14 description: Optional description text
15 """
17 def __init__(
18 self,
19 *children,
20 legend: str,
21 description: str | None = None,
22 **props,
23 ) -> None:
24 super().__init__(*children, legend=legend, description=description, **props)
25 self.legend = legend
26 self.description = description
28 def render(self) -> Any:
29 children_html = [
30 raw(render_to_string(c))
31 if hasattr(c, "__html__") or hasattr(c, "render")
32 else str(c)
33 for c in self.children
34 ]
36 legend_el = el(
37 "legend",
38 self.legend,
39 class_="text-base font-semibold leading-6 text-foreground px-2",
40 )
42 desc_el = (
43 el(
44 "p",
45 self.description,
46 class_="mt-1 text-sm text-muted-foreground mb-4 px-2",
47 )
48 if self.description
49 else ""
50 )
52 # Filter out props that shouldn't be attributes
53 attrs = {
54 k: v
55 for k, v in self.props.items()
56 if k not in ("legend", "description", "children")
57 }
59 return el(
60 "fieldset",
61 legend_el,
62 desc_el,
63 el("div", *children_html, class_="space-y-4"),
64 class_="border border-border rounded-lg p-6 mb-6",
65 **attrs,
66 )