htpy-htmx 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- htpy_htmx-0.1.0/.github/workflows/test.yml +52 -0
- htpy_htmx-0.1.0/.gitignore +6 -0
- htpy_htmx-0.1.0/.pre-commit-config.yaml +20 -0
- htpy_htmx-0.1.0/LICENCE +21 -0
- htpy_htmx-0.1.0/PKG-INFO +83 -0
- htpy_htmx-0.1.0/README.md +64 -0
- htpy_htmx-0.1.0/htpy_htmx/__init__.py +0 -0
- htpy_htmx-0.1.0/htpy_htmx/_types.py +107 -0
- htpy_htmx-0.1.0/htpy_htmx/ext.py +129 -0
- htpy_htmx-0.1.0/htpy_htmx/hx.py +509 -0
- htpy_htmx-0.1.0/htpy_htmx.egg-info/PKG-INFO +83 -0
- htpy_htmx-0.1.0/htpy_htmx.egg-info/SOURCES.txt +20 -0
- htpy_htmx-0.1.0/htpy_htmx.egg-info/dependency_links.txt +1 -0
- htpy_htmx-0.1.0/htpy_htmx.egg-info/requires.txt +1 -0
- htpy_htmx-0.1.0/htpy_htmx.egg-info/top_level.txt +1 -0
- htpy_htmx-0.1.0/pyproject.toml +58 -0
- htpy_htmx-0.1.0/setup.cfg +4 -0
- htpy_htmx-0.1.0/tests/__init__.py +0 -0
- htpy_htmx-0.1.0/tests/test_ext.py +73 -0
- htpy_htmx-0.1.0/tests/test_hx.py +225 -0
- htpy_htmx-0.1.0/tests.sh +8 -0
- htpy_htmx-0.1.0/uv.lock +1409 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: tests
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
tests:
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
include:
|
|
13
|
+
- name: pytest (3.10)
|
|
14
|
+
python: "3.10"
|
|
15
|
+
- name: pytest (3.11)
|
|
16
|
+
python: "3.11"
|
|
17
|
+
- name: pytest (3.12)
|
|
18
|
+
python: "3.12"
|
|
19
|
+
- name: pytest (3.13)
|
|
20
|
+
python: "3.13"
|
|
21
|
+
- name: pytest (3.14)
|
|
22
|
+
python: "3.14"
|
|
23
|
+
name: ${{ matrix.name }}
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v7
|
|
27
|
+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
28
|
+
with:
|
|
29
|
+
python-version: ${{ matrix.python }}
|
|
30
|
+
activate-environment: true
|
|
31
|
+
- run: uv sync
|
|
32
|
+
- run: uv run --python ${{ matrix.python }} pytest
|
|
33
|
+
|
|
34
|
+
mypy:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v7
|
|
38
|
+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.10"
|
|
41
|
+
- run: uv sync
|
|
42
|
+
- run: uv run mypy .
|
|
43
|
+
|
|
44
|
+
black:
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v7
|
|
48
|
+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
49
|
+
with:
|
|
50
|
+
python-version: "3.10"
|
|
51
|
+
- run: uv sync
|
|
52
|
+
- run: uv run black --check .
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# See https://pre-commit.com for more information
|
|
2
|
+
# See https://pre-commit.com/hooks.html for more hooks
|
|
3
|
+
repos:
|
|
4
|
+
- repo: https://github.com/psf/black
|
|
5
|
+
rev: 26.5.1
|
|
6
|
+
hooks:
|
|
7
|
+
- id: black
|
|
8
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
9
|
+
rev: v2.3.0
|
|
10
|
+
hooks:
|
|
11
|
+
- id: mypy
|
|
12
|
+
- repo: local
|
|
13
|
+
hooks:
|
|
14
|
+
- id: pytest
|
|
15
|
+
name: pytest
|
|
16
|
+
entry: ./.venv/bin/pytest
|
|
17
|
+
language: system
|
|
18
|
+
types: [python]
|
|
19
|
+
pass_filenames: false
|
|
20
|
+
always_run: true
|
htpy_htmx-0.1.0/LICENCE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 August Malmdahl
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
htpy_htmx-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: htpy-htmx
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Helpers for using htmx in htpy
|
|
5
|
+
Author-email: August Malmdahl <august.malmdahl@gmail.com>
|
|
6
|
+
Project-URL: Repository, https://github.com/augustifolia/htpy-htmx
|
|
7
|
+
Project-URL: Issues, https://github.com/augustifolia/htpy-htmx/issues
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Typing :: Typed
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENCE
|
|
17
|
+
Requires-Dist: htpy
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# htpy-htmx
|
|
21
|
+
|
|
22
|
+
htpy-htmx is a library to make it easier to work with [htmx](https://four.htmx.org/) in [htpy](https://htpy.dev/).
|
|
23
|
+
|
|
24
|
+
This library is intended to work with htmx 4.
|
|
25
|
+
|
|
26
|
+
Note: This project is still a work in progress and there may be breaking changes.
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
You can import htpy-htmx as htpy_htmx.hx. All normal htmx attributes are available from the module,
|
|
31
|
+
but without the "hx-" prefix. So `hx-get="url"` would become `hx.get("url")`.
|
|
32
|
+
|
|
33
|
+
Some htmx extension attributes are available in the htpy_htmx.ext module.
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
import htpy as h
|
|
37
|
+
from htpy_htmx import hx
|
|
38
|
+
from htpy_htmx import ext
|
|
39
|
+
|
|
40
|
+
# pass htmx attributes as functions
|
|
41
|
+
h.div("#div-id", hx.get("/some-url/"), hx.trigger("click"))
|
|
42
|
+
|
|
43
|
+
# hx-partial is also available as a htpy element
|
|
44
|
+
h.div("#div-id")[
|
|
45
|
+
h.h2["header"],
|
|
46
|
+
hx.partial("#part-id", hx.target("#some-element"))[
|
|
47
|
+
h.div("#div1")[
|
|
48
|
+
h.p["part one"]
|
|
49
|
+
]
|
|
50
|
+
],
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
h.div(
|
|
54
|
+
# trigger allows a list of trigger events
|
|
55
|
+
hx.trigger("blur", "keyup[key=='Enter']"),
|
|
56
|
+
# swap takes a swap style as string and modifiers as keyword arguments
|
|
57
|
+
hx.swap("before", swap="1s", scroll="bottom"),
|
|
58
|
+
# hx-on takes an event and a JavaScript expression
|
|
59
|
+
hx.on("htmx:before:request", "showSpinner()"),
|
|
60
|
+
# vals takes a dict of data.
|
|
61
|
+
# To evaluate JavaScript, wrap your js expression in hx.JS() and pass js=True.
|
|
62
|
+
hx.vals({"foo": "bar", "some_js": hx.JS("getSomeData()")}, js=True),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# to enable inheritance pass inherited=True to a hx-function
|
|
66
|
+
h.div(hx.confirm("Are you sure?", inherited=True))[
|
|
67
|
+
h.button(hx.delete("/account"))["Delete My Account"],
|
|
68
|
+
h.button(hx.put("/account"))["Update My Account"],
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
# Some extension attributes are available in ext:
|
|
72
|
+
h.div(
|
|
73
|
+
ext.preload("touchstart"),
|
|
74
|
+
ext.optimistic("#msg-opt"),
|
|
75
|
+
ext.ws(connect="click"),
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
|
|
81
|
+
To install with pip run:
|
|
82
|
+
|
|
83
|
+
pip install htpy-htmx
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# htpy-htmx
|
|
2
|
+
|
|
3
|
+
htpy-htmx is a library to make it easier to work with [htmx](https://four.htmx.org/) in [htpy](https://htpy.dev/).
|
|
4
|
+
|
|
5
|
+
This library is intended to work with htmx 4.
|
|
6
|
+
|
|
7
|
+
Note: This project is still a work in progress and there may be breaking changes.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
You can import htpy-htmx as htpy_htmx.hx. All normal htmx attributes are available from the module,
|
|
12
|
+
but without the "hx-" prefix. So `hx-get="url"` would become `hx.get("url")`.
|
|
13
|
+
|
|
14
|
+
Some htmx extension attributes are available in the htpy_htmx.ext module.
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
import htpy as h
|
|
18
|
+
from htpy_htmx import hx
|
|
19
|
+
from htpy_htmx import ext
|
|
20
|
+
|
|
21
|
+
# pass htmx attributes as functions
|
|
22
|
+
h.div("#div-id", hx.get("/some-url/"), hx.trigger("click"))
|
|
23
|
+
|
|
24
|
+
# hx-partial is also available as a htpy element
|
|
25
|
+
h.div("#div-id")[
|
|
26
|
+
h.h2["header"],
|
|
27
|
+
hx.partial("#part-id", hx.target("#some-element"))[
|
|
28
|
+
h.div("#div1")[
|
|
29
|
+
h.p["part one"]
|
|
30
|
+
]
|
|
31
|
+
],
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
h.div(
|
|
35
|
+
# trigger allows a list of trigger events
|
|
36
|
+
hx.trigger("blur", "keyup[key=='Enter']"),
|
|
37
|
+
# swap takes a swap style as string and modifiers as keyword arguments
|
|
38
|
+
hx.swap("before", swap="1s", scroll="bottom"),
|
|
39
|
+
# hx-on takes an event and a JavaScript expression
|
|
40
|
+
hx.on("htmx:before:request", "showSpinner()"),
|
|
41
|
+
# vals takes a dict of data.
|
|
42
|
+
# To evaluate JavaScript, wrap your js expression in hx.JS() and pass js=True.
|
|
43
|
+
hx.vals({"foo": "bar", "some_js": hx.JS("getSomeData()")}, js=True),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# to enable inheritance pass inherited=True to a hx-function
|
|
47
|
+
h.div(hx.confirm("Are you sure?", inherited=True))[
|
|
48
|
+
h.button(hx.delete("/account"))["Delete My Account"],
|
|
49
|
+
h.button(hx.put("/account"))["Update My Account"],
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
# Some extension attributes are available in ext:
|
|
53
|
+
h.div(
|
|
54
|
+
ext.preload("touchstart"),
|
|
55
|
+
ext.optimistic("#msg-opt"),
|
|
56
|
+
ext.ws(connect="click"),
|
|
57
|
+
)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
To install with pip run:
|
|
63
|
+
|
|
64
|
+
pip install htpy-htmx
|
|
File without changes
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from typing import TypeAlias, Literal
|
|
2
|
+
|
|
3
|
+
_swap_style: TypeAlias = (
|
|
4
|
+
str # This allows extensions to add new swap_styles (like upsert and download)
|
|
5
|
+
| Literal[
|
|
6
|
+
"innerHTML",
|
|
7
|
+
"outerHTML",
|
|
8
|
+
"beforebegin",
|
|
9
|
+
"before",
|
|
10
|
+
"afterbegin",
|
|
11
|
+
"prepend",
|
|
12
|
+
"beforeend",
|
|
13
|
+
"append",
|
|
14
|
+
"afterend",
|
|
15
|
+
"after",
|
|
16
|
+
"delete",
|
|
17
|
+
"none",
|
|
18
|
+
"innerMorph",
|
|
19
|
+
"outerMorph",
|
|
20
|
+
"textContent",
|
|
21
|
+
"outerSync",
|
|
22
|
+
# "upsert", # Requires the hx-upsert extension.
|
|
23
|
+
# "download", # Required the hx-download extension.
|
|
24
|
+
]
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
_selector: TypeAlias = (
|
|
28
|
+
str | Literal["this", "next", "previous", "body", "document", "window", "host"]
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
_event: TypeAlias = (
|
|
32
|
+
str
|
|
33
|
+
| Literal[
|
|
34
|
+
"load",
|
|
35
|
+
"revealed",
|
|
36
|
+
"intersect",
|
|
37
|
+
"submit",
|
|
38
|
+
"change",
|
|
39
|
+
"input",
|
|
40
|
+
"focus",
|
|
41
|
+
"blur",
|
|
42
|
+
"click",
|
|
43
|
+
"dblclick",
|
|
44
|
+
"mousedown",
|
|
45
|
+
"mouseup",
|
|
46
|
+
"mousemove",
|
|
47
|
+
"mouseenter",
|
|
48
|
+
"mouseleave",
|
|
49
|
+
"wheel",
|
|
50
|
+
"mousewheel",
|
|
51
|
+
"keyup",
|
|
52
|
+
"keydown",
|
|
53
|
+
"keypress",
|
|
54
|
+
"dragstart",
|
|
55
|
+
"drag",
|
|
56
|
+
"dragend",
|
|
57
|
+
"dragenter",
|
|
58
|
+
"dragover",
|
|
59
|
+
"dragleave",
|
|
60
|
+
"drop",
|
|
61
|
+
"play",
|
|
62
|
+
"pause",
|
|
63
|
+
"ended",
|
|
64
|
+
"volumechange",
|
|
65
|
+
"touchstart",
|
|
66
|
+
"touchend",
|
|
67
|
+
"touchmove",
|
|
68
|
+
"touchcancel",
|
|
69
|
+
"resize",
|
|
70
|
+
"scroll",
|
|
71
|
+
"select",
|
|
72
|
+
"search",
|
|
73
|
+
"invalid",
|
|
74
|
+
"contextmenu",
|
|
75
|
+
"reset",
|
|
76
|
+
]
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
_htmx_events: TypeAlias = Literal[
|
|
80
|
+
"htmx:config:request",
|
|
81
|
+
"htmx:before:request",
|
|
82
|
+
"htmx:after:request",
|
|
83
|
+
"htmx:finally:request",
|
|
84
|
+
"htmx:before:swap",
|
|
85
|
+
"htmx:after:swap",
|
|
86
|
+
"htmx:finally:swap",
|
|
87
|
+
"htmx:before:cleanup",
|
|
88
|
+
"htmx:after:cleanup",
|
|
89
|
+
"htmx:confirm",
|
|
90
|
+
"htmx:error",
|
|
91
|
+
"htmx:abort",
|
|
92
|
+
"htmx:before:init",
|
|
93
|
+
"htmx:after:init",
|
|
94
|
+
"htmx:before:process",
|
|
95
|
+
"htmx:after:process",
|
|
96
|
+
"htmx:before:history:update",
|
|
97
|
+
"htmx:after:history:update",
|
|
98
|
+
"htmx:after:history:push",
|
|
99
|
+
"htmx:after:history:replace",
|
|
100
|
+
"htmx:before:history:restore",
|
|
101
|
+
"htmx:before:viewTransition",
|
|
102
|
+
"htmx:after:viewTransition",
|
|
103
|
+
"htmx:before:response",
|
|
104
|
+
"htmx:before:settle",
|
|
105
|
+
"htmx:after:settle",
|
|
106
|
+
"htmx:response:error",
|
|
107
|
+
]
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Literal
|
|
3
|
+
from ._types import _selector, _event
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def multipart(*, connect: str, close: _event, inherited: bool = False) -> dict[str, str]:
|
|
7
|
+
"""Stream HTML with multipart/mixed.
|
|
8
|
+
|
|
9
|
+
https://four.htmx.org/extensions/hx-multipart
|
|
10
|
+
"""
|
|
11
|
+
data: dict[str, str] = {}
|
|
12
|
+
if connect:
|
|
13
|
+
data[f"hx-multipart:connect{':inherited' if inherited else ''}"] = connect
|
|
14
|
+
if close:
|
|
15
|
+
data[f"hx-multipart:close{':inherited' if inherited else ''}"] = close
|
|
16
|
+
return data
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def sse(*, connect: _event = "", close: _event = "", inherited: bool = False) -> dict[str, str]:
|
|
20
|
+
"""Stream HTML with text/event-stream (SSE).
|
|
21
|
+
|
|
22
|
+
https://four.htmx.org/extensions/hx-sse
|
|
23
|
+
"""
|
|
24
|
+
data: dict[str, str] = {}
|
|
25
|
+
if connect:
|
|
26
|
+
data[f"hx-sse:connect{':inherited' if inherited else ''}"] = connect
|
|
27
|
+
if close:
|
|
28
|
+
data[f"hx-sse:close{':inherited' if inherited else ''}"] = close
|
|
29
|
+
return data
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def ws(*, connect: _event = "", send: bool = False, inherited: bool = False) -> dict[str, str]:
|
|
33
|
+
"""Stream HTML and send data over WebSockets.
|
|
34
|
+
|
|
35
|
+
https://four.htmx.org/extensions/hx-ws
|
|
36
|
+
"""
|
|
37
|
+
data: dict[str, str] = {}
|
|
38
|
+
if connect:
|
|
39
|
+
data[f"hx-ws:connect{':inherited' if inherited else ''}"] = connect
|
|
40
|
+
if send:
|
|
41
|
+
data[f"hx-ws:send{':inherited' if inherited else ''}"] = ""
|
|
42
|
+
return data
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def live(attribute: str, expression: str, *, inherited: bool = False) -> dict[str, str]:
|
|
46
|
+
"""Add reactive bindings to HTML.
|
|
47
|
+
|
|
48
|
+
https://four.htmx.org/extensions/hx-live
|
|
49
|
+
"""
|
|
50
|
+
return {f"hx-live:{attribute}{':inherited' if inherited else ''}": expression}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def optimistic(selector: _selector, *, inherited: bool = False) -> dict[str, str]:
|
|
54
|
+
"""Shows optimistic content during request.
|
|
55
|
+
|
|
56
|
+
Note: This is an extension attribute. To use it, you must include the optimistic extension.
|
|
57
|
+
https://four.htmx.org/reference/attributes/hx-optimistic
|
|
58
|
+
"""
|
|
59
|
+
return {f"hx-optimistic{':inherited' if inherited else ''}": selector}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def browser_indicator(show_indicator: bool = True, *, inherited: bool = False) -> dict[str, str]:
|
|
63
|
+
"""Show tab's spinner with hx-browser-indicator.
|
|
64
|
+
|
|
65
|
+
https://four.htmx.org/extensions/hx-browser-indicator
|
|
66
|
+
"""
|
|
67
|
+
return {f"hx-browser-indicator{':inherited' if inherited else ''}": str(show_indicator).lower()}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def prompt(prompt: str, *, inherited: bool = False) -> dict[str, str]:
|
|
71
|
+
"""Prompt before requests with hx-prompt='Reason?'
|
|
72
|
+
|
|
73
|
+
https://four.htmx.org/extensions/hx-prompt
|
|
74
|
+
"""
|
|
75
|
+
return {f"hx-prompt{':inherited' if inherited else ''}": prompt}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def preload(
|
|
79
|
+
event: Literal["mouseenter", "mouseover", "touchstart"], *, inherited: bool = False
|
|
80
|
+
) -> dict[str, str]:
|
|
81
|
+
"""Preloads content before user triggers request.
|
|
82
|
+
|
|
83
|
+
Note: This is an extension attribute. To use it, you must include the preload extension.
|
|
84
|
+
https://four.htmx.org/reference/attributes/hx-preload
|
|
85
|
+
"""
|
|
86
|
+
return {f"hx-preload{':inherited' if inherited else ''}": event}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def ptag(tag: str, *, inherited: bool = False) -> dict[str, str]:
|
|
90
|
+
"""Skip unchanged polls with HX-PTag: "v42".
|
|
91
|
+
|
|
92
|
+
https://four.htmx.org/extensions/hx-ptag
|
|
93
|
+
"""
|
|
94
|
+
return {f"hx-ptag{':inherited' if inherited else ''}": tag}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def history(save_to_cache: bool, *, inherited: bool = False) -> dict[str, str]:
|
|
98
|
+
"""Restore back/forward pages from sessionStorage.
|
|
99
|
+
|
|
100
|
+
https://four.htmx.org/extensions/hx-history-cache
|
|
101
|
+
"""
|
|
102
|
+
return {f"hx-history{':inherited' if inherited else ''}": str(save_to_cache).lower()}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def head(
|
|
106
|
+
strategy: Literal["merge", "append", "re-eval"], *, inherited: bool = False
|
|
107
|
+
) -> dict[str, str]:
|
|
108
|
+
"""Merge <head> tags with hx-head='merge'.
|
|
109
|
+
|
|
110
|
+
https://four.htmx.org/extensions/hx-head
|
|
111
|
+
"""
|
|
112
|
+
return {f"hx-head{':inherited' if inherited else ''}": strategy}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def targets(*selector: _selector, inherited: bool = False) -> dict[str, str]:
|
|
116
|
+
"""Target many elements.
|
|
117
|
+
|
|
118
|
+
Requires the hx-targets extension
|
|
119
|
+
https://four.htmx.org/extensions/hx-targets
|
|
120
|
+
"""
|
|
121
|
+
return {f"hx-targets{':inherited' if inherited else ''}": ", ".join(selector)}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def nonce(csp_nonce: str, *, inherited: bool = False) -> dict[str, str]:
|
|
125
|
+
"""Make htmx work under strict Content Security Policy.
|
|
126
|
+
|
|
127
|
+
https://four.htmx.org/extensions/hx-csp
|
|
128
|
+
"""
|
|
129
|
+
return {f"hx-nonce{':inherited' if inherited else ''}": csp_nonce}
|