Sebb

Sebb OP

Oh I didn’t even notice that the classes are namespaced. That’s a start.
But true. I think that all of this leads to flaky stuff.
With lots of testing and insight you can get some version of shoelace working.
But they may break everything with the next bugfix-release.

0
Post #11
cmo

cmo

I’ve not used web components yet so I am just curious. You want to do stuff like this?

<sl-something ...>
  <%= @name %>
  <.some_function_component ...>
</sl-something>
0
Post #12
Sebb

Sebb OP

Yes thats, why you can’t just update-ignore (everything).

0
Post #13
Sebb

Sebb OP

I played with and thought about this a little more.

I think it is not possible to use web-components with LV the way I imagined.

What about this:

  • wrap all components in function components and do not allow setting any custom attributes directly on the WC-elements
  • prevent all changes LV does with a onBeforeElUpdated-callback (see above) - note: can’t just use phx-update=ignore because of nested elements.
  • if you really need to set attributes (like class) move this to sth like phx-class and merge this gracefully in onBeforeElUpdated to the real attribute (but the WC-lib may come with better ways to style them and you could also get away to only style plain child-elements of the WC-elements)
  • still a problem how to handle elements generated in the light-DOM. It seems like at least for shoelace this does not happen too often. Maybe just don’t use those and rebuild as a plain function component. But this could still be a problem if the WC-lib introduces sth like this in a release.

I also just re-read this post Adobe Spectrum 2 web components with LiveView - #36 by TunkShif by @TunkShif which gives a very good overview of all the challenges.

2
Post #14
benkimpel

benkimpel

These are pretty much the constraints that we arrived at in our exploration, but we didn’t pursue it further because of missing form support. (See function component example from our other thread for example of wrapping shoelace.) I think if you took the approach you’re describing you could get something decent in place. I think there are edge cases around morphdom patching children so watch out there.

0
Post #15
benkimpel

benkimpel

@Sebb I think this probably has the same solution as the reflected attributes getting clobbered, which boils down to: do what Shoelace would do in your wrapping function so there is nothing to patch.

So in this case you’re setting a Shoelace slot on sl-breadcrumb which in turn is setting the slot on each sl-breadcrumb-item. Here’s how i’d solve this one:

# NOT TESTED

##
## Function component Shoelace wrappers
##

# ATTRS SKIPPED
slot :inner_block, required: true
slot :separator

def sl_breadcrumb(assigns) do
  ~H"""
  <sl-breadcrumb ... >
    <%= render_slot(@inner_block, %{separator: sl_breadcrumb_separator(assigns)} %>
  </sl-breadcrumb>
  """
end

defp sl_breadcrumb_separator(%{separator: []} = assigns) do
  ~H"""
  <sl-icon name="arrow-right" slot="separator" aria-hidden="true" library="default"></sl-icon>
  """
end

defp sl_breadcrumb_separator(assigns) do
  ~H"""
  <%= render_slot(@separator) %>
  """
end

# ATTRS SKIPPED
slot :inner_block, required: true
slot :separator

def sl_breadcrumb_item(assigns) do
  ~H"""
  <sl-breadcrumb-item ... >
    <%= render_slot(@inner_block) %>
    <%= render_slot(sl_breadcrumb_separator(assigns)) %>
  </sl-breadcrumb-item>
  """
end

##
## USAGE
##

## Regular usage

<.sl_breadcrumb>
  <.sl_breadcrumb_item>First</.sl_breadcrumb>
  <.sl_breadcrumb_item>Second</.sl_breadcrumb>
  <.sl_breadcrumb_item>Third</.sl_breadcrumb>
</.sl_breadcrumb>

## Usage w/ custom breadcrumb separator and override for last item

<.sl_breadcrumb let={breadcrumb}>
  <:separator>
    <.sl_icon slot="separator"... />
  </:separator>

  <.sl_breadcrumb_item separator={breadcrumb.separator}>First</.sl_breadcrumb_item>
  <.sl_breadcrumb_item separator={breadcrumb.separator}>Second</.sl_breadcrumb_item>
  <.sl_breadcrumb_item>
    Third
    <:separator>
      <span slot="separator">special something</span>
    </:separator>
  </.sl_breadcrumb_item>
</.sl_breadcrumb>

See if that works for you. (I won’t have time to test anything for a while now since I’ve mostly concluded our spike on this.)

0
Post #16
Sebb

Sebb OP

Thanks for your input!
I’ll look at that as soon as I can.

Just another thought:
Did you ever consider going around the LV-form stuff altogether by catching formdata (on submit) or change on changes of form elements? (and send it to the LV-server, obviously)

0
Post #17
benkimpel

benkimpel

Only briefly because, iirc, there were other challenges around losing focus on inputs and such. So the problems were a bit higher-level… or lower-level. not sure how best to describe that. :smiley:

0
Post #18
Sebb

Sebb OP

This is most likely the best solution, but it demands a deep understanding of the WC-lib and lots of attention on each WC-release.

I reread your post. Did you try to patch phoenix_html as a POC? Looking at the code it does not seem to be too hard…? And it should solve the problems with focus and selection.

0
Post #19
joddm

joddm

Have you tried to add sl- as a global attribute prefix?

Phoenix.Component — Phoenix LiveView v0.20.4 (hexdocs.pm)

0
Post #20