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: custom elements rework #8457

Merged
merged 42 commits into from
May 2, 2023

Conversation

dummdidumm
Copy link
Member

@dummdidumm dummdidumm commented Apr 6, 2023

This is an overhaul of custom elements in Svelte. Instead of compiling to a custom element class, the Svelte component class is mostly preserved as-is. Instead a wrapper is introduced which wraps a Svelte component constructor and returns a HTML element constructor. This has a couple of advantages:

Breaking changes:

Wrapped Svelte component now stays as a regular Svelte component (invokeing it like before with new Component({ target: ..}) won't create a custom element). Its custom element constructor is now a static property named element on the class (Component.element) and should be regularly invoked through setting it in the html.

- const component = new Component({ target: someDiv, props: { foo: 'bar' } });
+ const component = document.createElement('custom-element-tag');
+ component.foo = 'bar';
+ someDiv.appendChild(component);
// or, if you have no attributes or only have simple string attributes:
+ someDiv.innerHTML = '<custom-element-tag foo="bar"></custom-element-tag>';

The timing of mount/destroy/update is different. Mount/destroy/updating a prop all happen after a tick, so shadowRoot.innerHTML won't immediately reflect the change (Lit does this too). If you rely on it, you need to await a promise for example:

const component = someDiv.innerHTML = '<custom-element-tag foo="bar"></custom-element-tag>';
+ await Promise.resolve();
someDiv.querySelector('custom-element-tag').shadowRoot.querySelector('div');
// ...

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

@dummdidumm dummdidumm added this to the 4.x milestone Apr 6, 2023
@vercel
Copy link

vercel bot commented Apr 6, 2023

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

A member of the Team first needs to authorize it.

prop.key.name === 'reflect' && typeof prop.value.value !== 'boolean' ||
prop.key.name === 'attribute' && typeof prop.value.value !== 'string'
) {
return error();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe give specific explanation of why it failed, eg

'cePropsDefinition' must be a statically analyzable object literal of the form '{ prop: { attribute?: string; type?: 'String' | 'Boolean' | 'Number' | 'Array' | 'Object', reflect?: boolean; } }', found key 'xxx'
'cePropsDefinition' must be a statically analyzable object literal of the form '{ prop: { attribute?: string; type?: 'String' | 'Boolean' | 'Number' | 'Array' | 'Object', reflect?: boolean; } }', the value of reflect is not boolean

@dummdidumm dummdidumm changed the base branch from master to version-4 April 11, 2023 13:19
xxkl1 and others added 11 commits April 11, 2023 15:20
Instead of "both", which doesn't make sense at that point.
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
- upgrade to TypeScript 5
- upgrade @ampproject/remapping
- remove obsolete workarounds

---------

Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
bump to rollup 3. Includes reworking the "treat those imports as external" a bit so that Rollup builds correctly but doesn't bundle some of the (now relative) imports

---------

Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
nosovk added a commit to nosovk/open-wc that referenced this pull request Jul 23, 2023
There was always an option to build custom elements with svelte, but recently there was a [huge update](sveltejs/svelte#8457) and now dev experience is much better that was before. Lots of issues were fixed and now svelte is a pretty solid solution to build reliable custom elements. It would be nice to add it to the list of base libraries.

For example lots of svelte libraries were complied to custom elements before, (slidy)[https://github.com/Valexr/slidy/tree/main/packages] for example, and now it's even much easier than befor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment