Skip to content

Releases: t-strings/tdom

Rearchitect with future performance, error handling, and other features in mind

17 Dec 00:41

Choose a tag to compare

This release contains a significant under-the-hood rearchitecting of both the processor and the parsing layer.

The new architecture is substantially more mature than the previous, and provides us with new opportunities for future performance gains, improved error handling, and several other interesting new features.

Many thanks to @ianjosephwilson for his essential contributions here.

v0.1.11

30 Oct 20:24

Choose a tag to compare

Fix handling of escaping in content nodes (#68), specifically <style>, <script>, <textarea>, and <title>. Thanks to @ianjosephwilson.

Bugfixes and cleanup

05 Oct 19:04

Choose a tag to compare

This release fixes issue #60 and cleans up support for multiple placeholders where appropriate.

Allow multiple substitutions in attribute values

03 Oct 19:52

Choose a tag to compare

Previously, we only supported single substitutions in attribute values. Now we allow multiple, so this works:

first = "Alice"
last = "Smith"
button = html(t"<button data-name='{first} {last}'>Click me</button>")
# <button data-name="Alice Smith">Click me</button>

Thanks to @koxudaxi for the PR!

Clarify rules for `children` in component invocations

17 Sep 19:58

Choose a tag to compare

children are now treated like all other attributes during component invocation:

  1. If there's an explicit children parameter, we pass in a tuple. If there are no children in the underlying HTML, the tuple will be empty.
  2. If there's a **kwargs parameter, we always include children; the component is free to ignore this key.
  3. If there's no children parameter and no **kwargs, we ignore children in the underlying HTML if there are any.

Support class-based components

15 Sep 20:44

Choose a tag to compare

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.

Add explicit fragment support (JSX-like syntax), and support Components returning iterables.

14 Sep 21:23

Choose a tag to compare

We now explicitly support JSX-like fragment syntax. This is useful when implementing component functions:

def Items() -> Node:
    return html(t"<><li>Item 1</li><li>Item 2</li></>")

result = html(t"<ul><{Items} /></ul>")
# <ul><li>Item 1</li><li>Item 2</li></ul>

As an alternative, we also support returning typing.Iterables from components as well; these are treated as implicitly creating a tdom.nodes.Fragment:

def Items() -> Iterable[Node]:
    for i in range(2):
        yield t"<li>Item {i + 1}</li>"

result = html(t"<ul><{Items} /></ul>")
# <ul><li>Item 1</li><li>Item 2</li></ul>

In practice, component functions can return any value and it will be converted to a Node in exactly the same way that any value substituted in children context would be normally (aka html(t"<div>{child_value}</div>")). The fallback case if a value isn't a special type is always simply to create a Text node from str(value).

It's a new world order.

09 Sep 22:38

Choose a tag to compare

We've updated tdom in many ways. See the README.md for details on the latest.

v0.0.7

19 Jun 14:24

Choose a tag to compare

Fix MicroPython early/eager import inspect which was failing.

Update and add package metadata.

19 May 18:17

Choose a tag to compare

v0.0.6

Add further classifiers/metadata