bigskysoftware / bigskysoftware/htmx
htmx.process not fully applying HTMX behaviors to elements in shadowDom
- Dominant language
- JavaScript
- Stars
- 49.4k
- Forks
- 1.7k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 30
Description
I am testing HTMX with web components and have found two issues, which seem to be related to how `htmx.process()` works.
Issue 1:
The `hx-on::before-request` attribute is ignored when using `htmx.process()` as outlined in the docs.
Note that this could be related to https://github.com/bigskysoftware/htmx/issues/2406
Issue 2:
The `hx-get` attribute is ignored when `htmx.process()` is called on a web component that is a child of another web component.
The example code below shows five buttons:
1. Not a component - Created using plain HTML. `hx-get` and `hx-on::before-request` both work.
2. MyComponent - A web component created by following the docs (https://v2-0v2-0.htmx.org/examples/web-components/). `hx-get` works and `hx-on::before-request` does not work.
3. MyComponentAlt - A web component similar to MyComponent, but with `htmx.process(buttonEl)` instead of `htmx.process(root)`. `hx-get` and `hx-on::before-request` both work.
4. MyButton - A simple button web component. `hx-get` and `hx-on::before-request` both work.
5. MyButtonWrapper - A more complex web component, with one web component inside another. `hx-get` does not work (and can't tell if `hx-on::before-request` works).
All five button should behave the same: click to show an alert. Buttons 'Not a component', MyComponentAlt and MyButton all work as expected. MyComponent and MyButtonWrapper do not.
I have tried with both HTMX v1.9.11 and v2.0.0-alpha1, with similar results.
```html
HTMX WebComponents
Not a component
MyButton
button {
cursor: pointer;
}
MyButtonWrapper
window.beforeRequestHandler = (evt) => {
evt.preventDefault();
alert(evt.detail.pathInfo.requestPath);
};
customElements.define(
"my-component",
class MyComponent extends HTMLElement {
connectedCallback() {
const root = this.attachShadow({ mode: "closed" });
root.innerHTML = `
<button
hx-on::before-request="beforeRequestHandler(event)"
hx-get="#my-component"
>MyComponent</button>`;
htmx.process(root);
}
}
);
customElements.define(
"my-compnent-alt",
class MyComponentAlt extends HTMLElement {
connectedCallback() {
const root = this.attachShadow({ mode: "closed" });
root.innerHTML = `
<button
hx-on::before-request="beforeRequestHandler(event)"
hx-get="#my-compnent-alt"
>MyComponentAlt</button>`;
const buttonEl = root.querySelector("button");
htmx.process(buttonEl);
}
}
);
customElements.define(
"my-button",
class MyButton extends HTMLElement {
connectedCallback() {
const root = this.attachShadow({ mode: "closed" });
const content = document
.querySelector(`#my-button-template`)
.content.cloneNode(true);
root.replaceChildren(content);
const url = this.getAttribute("url");
const buttonEl = root.querySelector("button");
buttonEl.setAttribute("hx-get", url);
htmx.process(buttonEl);
}
}
);
customElements.define(
"my-button-wrapper",
class MyButtonWrapper extends HTMLElement {
connectedCallback() {
const root = this.attachShadow({ mode: "closed" });
const content = document
.querySelector(`#my-button-wrapper-template`)
.content.cloneNode(true);
root.replaceChildren(content);
}
}
);
```
I have two questions:
1. Are the docs wrong? Should it be `htmx.process(someElement)` instead of `htmx.process(root)`?
2. Should `htmx.process()` work on nested web components?
Contributor guide
Assessment
This issue has not been assessed yet.