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

feat: Allow use of ElementInternals with Web Components #8473

Conversation

tronicboy1
Copy link

@tronicboy1 tronicboy1 commented Apr 11, 2023

First time contributing! Please excuse me if I'm doing something wrong.

Problem

You cannot add ElementInternals to a Svelte Web Component because we cannot add the static property formAssociated in the constructor.

Solution

I added an option to the <svelte:options> tag to add the formAssociated property to a Web Component's construction.
I also added a function to attach the internals to the component and then return them for use.

<svelte:options tag="wc-svelte-select-demo" elementInternals />

<script>
    import { createCustomElementInternals } from 'svelte/internal';

    const _internals = createCustomElementInternals();
    let value = 'a';
    $: value, _internals.setFormValue(value);
</script>

<select id="demo" bind:value>
    <option value="a">A</option>
    <option value="b">B</option>
</select>

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with npm test and lint the project with npm run lint

@vercel
Copy link

vercel bot commented Apr 11, 2023

@tronicboy1 is attempting to deploy a commit to the Svelte Team on Vercel.

A member of the Team first needs to authorize it.

@tronicboy1 tronicboy1 changed the title Allow use of ElementInternals with Web Components feat: Allow use of ElementInternals with Web Components Apr 11, 2023
@dummdidumm
Copy link
Member

Thank you! I'm wondering if #4534 is a more general solution to this, implementing the $$host and then accessing all methods on it you want. That said, I'm not sure how/when $$host lands.

@tronicboy1
Copy link
Author

Thank you! I'm wondering if #4534 is a more general solution to this, implementing the $$host and then accessing all methods on it you want. That said, I'm not sure how/when $$host lands.

@dummdidumm

Thanks for the reply and review!

If my understanding is correct, $$host is a reference to the actual custom element instance (this) yes?

If that is the case then unfortunately we could not use that as a solution. The reason why is that accessing an instance would be after the constructor (class Wc extends HTMLElement) is registered to the component registery.

The static property for ElementInternals needs to be set before being registered with customElements.define.

@dummdidumm
Copy link
Member

The static property yes, but not attachInternals which could go through $$host if I'm not mistaken

@tronicboy1
Copy link
Author

@dummdidumm
Oh! Yes the .attachInternals method should be accessible on the $$host variable.

Are you suggesting that we drop the helper function in this or and just have users do something like const internals = $$host.attachInternals()?

@dummdidumm dummdidumm added this to the one day milestone Apr 20, 2023
@dummdidumm
Copy link
Member

Are you suggesting that we drop the helper function in this or and just have users do something like const internals = $$host.attachInternals()?

Yes that's my thinking - though I wouldn't want you to change this now. The whole web component story is in the middle of a rework now, and $$host is something we need to have a deeper thought about after Svelte 4. So this likely won't land soon (neither $$host nor your PR).

@tronicboy1
Copy link
Author

Are you suggesting that we drop the helper function in this or and just have users do something like const internals = $$host.attachInternals()?

Yes that's my thinking - though I wouldn't want you to change this now. The whole web component story is in the middle of a rework now, and $$host is something we need to have a deeper thought about after Svelte 4. So this likely won't land soon (neither $$host nor your PR).

@dummdidumm
Understood! I will leave it as is for now; let me know if you think we can do away with it.

I am really happy that we may be able to include this in version 4!! 🥰 Let me know if there is anything I can help with.

dummdidumm added a commit that referenced this pull request Jul 18, 2023
This should help everyone who has special needs and use cases around custom elements. Since Svelte components are wrapped and only run on connectedCallback, it makes sense to expose the custom element class for modification before that.
- fixes #8954 - use extend to attach the function manually and save possible values to a prop
- closes #8473 / closes #4168 - use extend to set the proper static attribute and then call attachInternals in the constructor
closes #8472 - use extend to attach anything custom you need
closes #3091 - pass `this` to a prop of your choice and use it inside your component
dummdidumm added a commit that referenced this pull request Jul 18, 2023
This should help everyone who has special needs and use cases around custom elements. Since Svelte components are wrapped and only run on connectedCallback, it makes sense to expose the custom element class for modification before that.
- fixes #8954 / closes #8955 - use extend to attach the function manually and save possible values to a prop
- closes #8473 / closes #4168 - use extend to set the proper static attribute and then call attachInternals in the constructor
- closes #8472 - use extend to attach anything custom you need
- closes #3091 - pass `this` to a prop of your choice and use it inside your component
- add some doc for #8987
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants