Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slots in loops only assigned once when component used as custom element #10691

Open
sawmurai opened this issue Apr 13, 2024 · 3 comments
Open

Comments

@sawmurai
Copy link

sawmurai commented Apr 13, 2024

Vue version

3.4.21

Link to minimal reproduction

https://github.com/sawmurai/vue-custom-elements-slots-reproducer

Steps to reproduce

  • Clone the repo
  • Run pnpm install
  • Build the custom element (cd packages/vue-custom-elements && pnpm run build)
  • Run the reproducer (cd packages/vue-custom-elements-consumer && pnpm run dev)

What is expected?

The slot-content, rendered three times, should show the replacement, three times.

What is actually happening?

The slot-content, rendered three times, is only replaced once.

System Info

System:
    OS: Linux 6.5 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish)
    CPU: (16) x64 AMD Ryzen 7 3800X 8-Core Processor
    Memory: 56.84 GB / 62.67 GB
    Container: Yes
    Shell: 3.7.0 - /usr/bin/fish
  Binaries:
    Node: 20.12.1 - ~/.nvm/versions/node/v20.12.1/bin/node
    Yarn: 1.22.19 - ~/.yarn/bin/yarn
    npm: 10.5.0 - ~/.nvm/versions/node/v20.12.1/bin/npm
    pnpm: 8.15.6 - ~/.nvm/versions/node/v20.12.1/bin/pnpm
    bun: 1.0.0 - ~/.bun/bin/bun
  Browsers:
    Chrome: 121.0.6167.160
    Chromium: 123.0.6312.86

Any additional comments?

I think to fix this problem the slot assignment needs to be done manually (by setting the slotAssignment to manual). I played with that option and was able to get a rough version working (I cloned the <div slot="root"> elements and assigned them manually to each instance of the slot in the DOM). Of course, the devil is in the details and I did not even look at edge cases. Before attempting a full-blown PR, I would like your feedback, if this is something you even want to support, first.

@sawmurai
Copy link
Author

sawmurai commented Apr 20, 2024

I investigated some more and created a fix locally. Unfortunately I am not able to add a test because jsdom does not yet support the imperative slot API (see this issue and this PR). I would also have to disable the test for the default slot assignment as it needs HTMLSlotElement.assign as well (since the default assignment would not be used anymore).

If you like I can still push the branch and create a PR.

@yyx990803
Copy link
Member

HTMLSlotElement.assign is relatively new and doesn't align with Vue's baseline support (browsers that support ES2016+), so it might be problematic to use it directly.

Looks like it can be polyfilled, although we might be able to implement only what is needed by Vue?

@sawmurai
Copy link
Author

sawmurai commented Apr 23, 2024

Another idea would be to keep the automated assignment but update the slot names dynamically: After (or perhaps during?) rendering, check if a slot name is used more than once and make the copies of that slot name unique (the name attribute of the slot tags). Then, duplicate the slottables and assign the same unique names to the slot attributes. This way baseline support is respected and no polyfill is needed.

Edit: This appears to be very similar to what the polyfill you linked would do

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants