Skip to content

Latest commit

 

History

History
173 lines (130 loc) · 4.5 KB

features.md

File metadata and controls

173 lines (130 loc) · 4.5 KB

Dominix features

These are features not present in Dominate. See the main article for common features.

All code samples assume Dominix being imported like this:

from dominix.tags import *

HTMX support

The most important difference from Dominate is of course the support for HTMX. All HTMX attributes are available as named arguments and properties, including docstrings. This provides code completion and better IDE support.

Screen shot

The attributes are available both as constructor arguments and as tag properties:

tag = div(hx_get="/my/endpoint")
print(tag)

tag = div()
tag.hx_get = "/my/endpoint"
print(tag)

Output:

<div hx-get="/my/endpoint"></div>
<div hx-get="/my/endpoint"></div>

Special attributes

The following attributes have special implementation to provide better developer experience.

Attribute hx-on

HTMX requires one hx-on* attriubute for each event handler:

<div hx-on:click="alert()">Click</div>

In Dominix hx-on is a property that returns a dictionary:

tag = div()
tag.hx_on["click"] = "alert()"

Or it can be set using the constructor:

tag = div(hx_on={"click": "alert('Clicked')"}

In both cases the resulting HTMX will be:

<div hx-on:click="alert()"></div>

Attributes hx-val and hx-headers

These HTMX attributes are also available as dictionary properties / constructor arguments. They will be converted to JSON when the tag is rendered:

tag = div(hx_headers={"foo": "bar", "baz": "qux"})
tag.hx_vals = {"foo": "bar", "baz": "qux"}
<div hx-headers='{"foo": "bar", "baz": "qux"}' hx-vals='{"foo": "bar", "baz": "qux"}'></div>

Attribute cls

The cls property can be used for easy manipulation of the HTML class attribute using standard Python list operations:

tag = div(cls="a b c")
tag.cls.extend(["d", "e", "f"])
tag.cls.append("g")
tag.cls.remove("b")
<div class="a b d e f g"></div>

(You can assign lists and strings to cls interchangably. Strings will be converted to lists as needed.)

Attribute style

The style property can be used for easy manipulation of the HTML style attribute using standard Python dictionary operations:

tag = div(style="color: red; font-size: 12px")
tag.style["color"] = "blue"
del tag.style["font-size"]
tag.style["font-color"] = "green"
<div style="color:blue; font-color:green"></div>

(You can assign dictionaries and strings to style interchangably. Strings will be converted to dictionaries as needed.)

Method chaining

All the special attributes mentioned above have convenience methods for addiing and deleting elements with support for method chaining:

  • add_class / rem_class
  • upd_style / del_style
  • upd_hx_on / del_hx_on
  • upd_hx_vals / del_hx_vals
  • upd_hx_headers / del_hx_headers

Example:

# Let's say you have created this component in your design system
def component():
    return div("Hello", cls="one two three", hx_on={"click": "alert('click')"})

# ... and you want to make your own variation of it:
def my_component():
    return component().add_class("four").rem_class("one").upd_hx_on("mouseover", "alert('mouseover')").del_hx_on("click")

# Or using with:
def my_component():
    with component() as c:
        add_class("four")
        rem_class("one")
        upd_hx_on("mouseover", "alert('mouseover')")
        del_hx_on("click")
    return c

The result of my_component().render()is the same in both cases:

<div class="two three four" hx-on:mouseover="alert('mouseover')">Hello</div>

Dominate comes with the attr function for adding attributes to the current tag (when using with syntax). Dominix has the same function, with the only change that it will return self. In addition, attr has also been added as a method. This allows for using method chaining, which may be more convenient in some situation:

def section(title):
    return div(h1(title))

def my_section():
    return section("Chained").attr(hx_get="/my/endpoint")

# Alternative without method chaining
def my_section():
    tag = section("Chained")
    with tag:
        attr(hx_get="/my/endpoint")
    return tag

The result of my_section().render(): is the same in both cases:

<div hx-get="/my/endpoint">
    <h1>Chained</h1>
</div>