Coverage for src / lexigram / ui / molecules / stack.py: 71%
34 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
1"""Stack layout component.
3Renders a vertical flex-column container with configurable gap between
4children. Built on top of the ``htpy`` element builder.
5"""
7from __future__ import annotations
9from typing import Any
11from htpy import el as _el
13el: Any = _el
16class Stack:
17 """A vertical flex-column layout container.
19 Stacks its *children* elements vertically with a Tailwind CSS gap.
21 Args:
22 children: Sequence of child elements to render inside the stack.
23 gap: Tailwind spacing unit for ``gap-*`` (e.g. ``6`` → ``gap-6``).
24 class_: Additional CSS classes appended to the container element.
26 Example::
28 content = Stack(
29 gap=4,
30 children=[
31 el("h2", "Title"),
32 el("p", "Body text"),
33 ],
34 )
35 """
37 def __init__(
38 self,
39 children: list[Any] | None = None,
40 gap: int = 4,
41 class_: str = "",
42 ) -> None:
43 self.children: list[Any] = children or []
44 self.gap = gap
45 self.class_ = class_
47 def __iter__(self) -> Any:
48 """Render as an htpy-compatible element iterator."""
49 base_classes = f"flex flex-col gap-{self.gap}"
50 if self.class_:
51 base_classes = f"{base_classes} {self.class_}"
52 yield from el(
53 "div",
54 self.children,
55 class_=base_classes,
56 )
58 def __html__(self) -> str:
59 """Return the rendered HTML string."""
60 parts: list[str] = []
61 base_classes = f"flex flex-col gap-{self.gap}"
62 if self.class_:
63 base_classes = f"{base_classes} {self.class_}"
64 parts.append(f'<div class="{base_classes}">')
65 for child in self.children:
66 if hasattr(child, "__html__"):
67 parts.append(child.__html__())
68 elif hasattr(child, "__iter__"):
69 try:
70 parts.extend(str(c) for c in child)
71 except TypeError:
72 parts.append(str(child))
73 else:
74 parts.append(str(child))
75 parts.append("</div>")
76 return "".join(parts)
78 def __str__(self) -> str:
79 return self.__html__()
82__all__ = ["Stack"]