Skip to content

Support class-based components

Choose a tag to compare

@davepeck davepeck released this 15 Sep 20:44
· 35 commits to main since this release

This release contains a big set of changes to support class-based components, as described in #53.

In addition to writing standard function-based components:

from typing import Iterable
from tdom import html

def FunctionComponent(children: Iterable[Node], something: int) -> Node:
    return html(t"<div>Something: {something}<br />{children}</div>")

result = html(t"<{FunctionComponent} something={42}><p>hi</p></{FunctionComponent}>")
# <div>Something: 42<br /><p>hi</p></div>

You can now write class-based components:

from dataclasses import dataclass, field
from typing import Any, Iterable
from tdom import Node, html

@dataclass
class Card:
    children: Iterable[Node]
    title: str
    subtitle: str | None = None

    def __call__(self) -> Node:
        return html(t"""
            <div class='card'>
                <h2>{self.title}</h2>
                {self.subtitle and t'<h3>{self.subtitle}</h3>'}
                <div class="content">{self.children}</div>
            </div>
        """)

result = html(t"<{Card} title='My Card' subtitle='A subtitle'><p>Card content</p></{Card}>")
# <div class='card'>
#     <h2>My Card</h2>
#     <h3>A subtitle</h3>
#     <div class="content"><p>Card content</p></div>
# </div>

There are a number of under-the-hood changes to support this.

Also, we've now officially achieved 100% statement coverage.