Sebb
Motivated by the success @benkimpel had with shoelace (see: Improve Support for Web Components in Forms with "Element Adapters") and the thread by @adw632 (see: Adobe Spectrum 2 web components with LiveView) I tried it myself.
I had some success, but there are also some problems I do not know how to solve and if they are solvable.
Solved? Problem 1 - LV removes attributes set by shoelace
If you do not set all relevant attributes on an element, shoelace sets defaults, LV removes them. This can be easily solved by either wrapping all shoelace elements into function components (see Ben’s thread) or just:
SL_DEFAULTS = {
"SL-BUTTON": { "variant": "default", "size": "medium" },
"SL-AVATAR": { "shape": "circle" },
"SL-BADGE": { "variant": "neutral" },
"SL-ICON": { "library": "default" },
...
}
let liveSocket = new LiveSocket("/live", Socket, {
params: { _csrf_token: csrfToken },
dom: {
onBeforeElUpdated(_from, to) {
const sl_defaults_for_current = SL_DEFAULTS[to.tagName];
if (sl_defaults_for_current) {
Object.entries(sl_defaults_for_current).forEach(([key, value]) => {
if (!to.hasAttribute(key)) {
to.setAttribute(key, value);
}
});
}
}
}
})
this seems to work fine.
Solved? Problem 2 - LV removes state like in @open
Multiple components store their state in an @open, eg <sl-details>
<sl-details summary="Toggle Me">
Lorem ipsum ...
</sl-details>
So when you
- render → closed (
@opennot set) - toggle → opens (
@openset) - rerender → closes (
@openremoved by LV)
This can be fixed by sth like
window.addEventListener("sl-after-show", (evt) => {
liveSocket.execJS(evt.target, '[["set_attr", {"attr": ["open", true]}]]');
})
window.addEventListener("sl-after-hide", (evt) => {
liveSocket.execJS(evt.target, '[["remove_attr", {"attr": "open"}]]');
})
Or sth more sophisticated (see Ben’s thread)
Seems to work fine.
Problem 3 - LV removes elements that shoelace places into the light-DOM
This happens with <sl-breadcrumb>, code:
<sl-breadcrumb>
<sl-icon name="arrow-right" slot="separator" aria-hidden="true"></sl-icon>
<sl-breadcrumb-item>
<sl-icon slot="prefix" name="house"></sl-icon>First
</sl-breadcrumb-item>
<sl-breadcrumb-item>Second</sl-breadcrumb-item>
<sl-breadcrumb-item>Third</sl-breadcrumb-item>
</sl-breadcrumb>
This is how the breadcrumbs look like after first render (correct):

Note the arrow-icon that shoelace dynamically put into the separator slot of the item:
after a rerender it looks like:

Note the missing arrow-icon:
Problem 4 - LV removes generated classes
happens with <button-group>, code:
<sl-button-group label="Alignment">
<sl-button size="small">Left</sl-button>
<sl-button size="small">Center</sl-button>
<sl-button size="small">Right</sl-button>
</sl-button-group>
first render (correct):

note the classes:
after rerender:
classes missing:

Problem 5 - ARIA
Seems like shoelace puts some important aria attributes which LV removes, didn’t look into that.
Problem 6 - Forms
This does absolutely not work right now, see Ben’s thread.
Trending in Discussions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex














Most Liked- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Sebb
sad story.
Thank’s for all the help so far, did put me on the right track.
We’ll see what comes of it.
benkimpel
This is great. Let’s see if we can fix these.
When we were testing it out we found that adding an ID to some of the Shoelace slots helped with patching. It triggers different behavior in morphdom since the id is the
nodeKeyso rather than patching as children it patches directly.There’s a more drastic option as well…
benkimpel
For example, this fixes the button group…
But how fragile is all of this? idk