Source code for animaid.html_object

"""Base class for HTML-renderable types."""

from abc import ABC, abstractmethod
from typing import Self


[docs] class HTMLObject(ABC): """Abstract base class for all HTML-renderable types. All HTML* types (HTMLString, HTMLList, HTMLDict) inherit from this to ensure a consistent interface for rendering Python objects as styled HTML. When rendering nested objects, any item that is an HTMLObject will have its render() method called automatically. """ _styles: dict[str, str] _css_classes: list[str]
[docs] @abstractmethod def render(self) -> str: """Return HTML representation of this object. Returns: A string containing valid HTML that can be embedded in a page. """ ...
def __html__(self) -> str: """Jinja2 auto-escaping protocol. When Jinja2 encounters an object with __html__, it calls this method and marks the result as safe (no escaping). Returns: The rendered HTML string. """ return self.render()
[docs] @abstractmethod def styled(self, **styles: str) -> Self: """Return a copy with additional inline styles. Style names use Python convention (underscores) and are converted to CSS convention (hyphens) automatically. Args: **styles: CSS property-value pairs, e.g., font_size="16px" Returns: A new instance with the combined styles. """ ...
[docs] @abstractmethod def add_class(self, *class_names: str) -> Self: """Return a copy with additional CSS classes. Args: *class_names: CSS class names to add. Returns: A new instance with the additional classes. """ ...
def _build_style_string(self) -> str: """Convert internal styles dict to CSS style attribute value.""" if not self._styles: return "" return "; ".join(f"{k}: {v}" for k, v in self._styles.items()) def _build_class_string(self) -> str: """Convert internal classes list to CSS class attribute value.""" if not self._css_classes: return "" return " ".join(self._css_classes) def _build_attributes(self) -> str: """Build the complete HTML attributes string.""" parts = [] class_str = self._build_class_string() if class_str: parts.append(f'class="{class_str}"') style_str = self._build_style_string() if style_str: parts.append(f'style="{style_str}"') return " ".join(parts)