Comments (11)
@Rich-Harris Ironically i've implemented this within the past few weeks. I've figured it out with your exact API coincidentally (even the ability to use new xComponent
format.
You and I seem to see eye to eye on recent patterns and is the reason i haven't (fully) drank the ng/em kool-aid. Besides the element based stuff I don't have much usage for the other tools the framework provides. Even "routing" is simplistic enough for me to have a mini extension. No need for anything else but I digress.
The trick was 2 abstractions (extensions). One to HTMLElement
and the other to DocumentFragment
So basically a "template" is a document fragment and is a nice abstraction as you can easily create one off document.createDocumentFragment
and this is what the default <template>
element returns from template.content
it's how you access the contents and DocumentFragment
dom as you may already know. There is one major caveat you may already know about but I didn't. Must use the native-shim.js
webcomponent fill or some REALLY funky stuff starts happening with firing constructors super()
. Also event callbacks don't get bound like you'd think. Spent 2 days battling this last week in Hawaii before finding a solution. I think it has something to do with the state of registering webcomponents being torn in migration.
CustomElements v0
// dynamically register
document.registerElement ( // less flexible
`svelt-button`,
{extends: 'button', prototype: Object.create (HTMLSveltButton.prototype)}
)
let element = document.registerElement (`svelt-button`, {extends: 'button'})
// dynamically create
// existing custom svelt element in the dom (i.e. <svelt-button></svelt-button>)
document.createElement (`svelt-button`, `button`)
// one caveat is this method seems to fire off the constructor (but not events)
// for existing elements in the DOM as a side effect when `creating` a new element.
CustomElements v1
// dynamically register
// preferred but DEFINITELY need a polyfill as the spec is not fully matured.
// Pulled my hair out a bit on this one.
window.customElements.define ('my-svelte', SveltComponent)
With those two abstractions i've been able to build pretty much any interface even down to the event binding. Happy to contribute.
Let me know where I can help!
P.S. I gotta tell ya my most liked feature so far with all the components is how you get an attributes mutation observer out of the box! And can control which attributes are "watched" for mutation. it's baked into the spec @mohsen1
from svelte.
...or provide an option to compile to custom elements? From output code I can see how easy it is to do that.
Since custom elements need dash separated names compiler should convert camelCase to kebob-case.
from svelte.
So here's a few issues I think we'll have to solve before implementing something like this:
- Defining a custom element is global, while svelte currently uses imports + manually listing components that the component needs.
- Custom elements are supposed to have names with a dash in them, while svelte components are generally named after class name conventions (CamelCase vs lisp-case)
- Does svelte define the component? Does the user define each component?
from svelte.
- could possibly set a global env of
window
or pass inwindow.customElements
- Don't forget about hyphen names can't be started with one i.e.
<-foo>
but<foo->
is valid (but a little hackey to me). Currently having that discussion with my colleagues devpunks/snuggsi#86 - I believe user is
extend
ing from a Svelte component. Which seems to be the norm these days
Hope this helps.
from svelte.
I think maybe we could close this issue — I'm still not really sold on web components, so I'd be hesitant to add the maintenance burden of having the compiler support them directly. It's already very easy to use custom elements like so:
import Counter from './Counter.html';
import { register } from 'svelte-custom-elements';
register('my-component', Counter, [ 'value' ]);
document.body.innerHTML = '<my-component value="42"></my-component>';
You could even use svelte-custom-elements inside Svelte components:
<my-component value="{{value}}"></my-component>
<script>
import './my-component'; // contains the first three lines of the example above
export default {
data() {
return { value: 42 };
}
};
</script>
from svelte.
@Rich-Harris far better for Svelte to wrap around a custom element. As it's no different than a canonical dom node at that point from Svelte's perspective. Trust me on this one. You're def digging in the right direction and don't really have to do anyting much with the svelte-custom-element
"plugin"(?). I'll be working on updating the specs for Custom Elements soon.
from svelte.
@Rich-Harris re not buyin' it yet... Agreed on not sold 100% but we're working on that sales pitch ;-)
from svelte.
@snuggs There are some tangible benefits to components not being DOM nodes — for example, suppose you have a component like this...
<!-- App.html -->
<Foo bar='{{bar}}' baz='{{baz}}'/>
...which has a computed property qux
that's derived from bar
and baz
. At the moment, if bar
and baz
change simultaneously...
app.set({
bar: 1,
baz: 2
});
...then Foo
only needs to recompute qux
once, and no DOM manipulation is wasted. Whereas if it's a DOM node instead...
<!-- App.html -->
<my-foo bar='{{bar}}' baz='{{baz}}'/>
...then Svelte has to generate code like this:
foo.bar = state.bar; // invokes a setter, which in turn updates `qux`
foo.baz = state.baz; // invokes a setter again!
Now, one possible solution to that problem is for updates to happen asynchronously. But then you have a programming model that's much harder to reason about, because the DOM isn't necessarily the way you'd expect it to be given your application state.
This is just one small manifestation of the problem, but the point that it illustrates is that the DOM is kind of a bad API for building state-driven applications. They're good for some things, but I just don't think they're a great substance to build complex apps out of. I say that as someone who was very enthusiastic about web components at the beginning!
from svelte.
@Rich-Harris well... could just do work and trigger a render flag on rAF
(requestAnimationFrame). That way if your code runs within 16ms good to go (Which it shouldn't be longer than an order of magnitude less than that). Secondly going off community traction most aren't interested in attribute changes. (Not a valid excuse tho for this use case).
Lastly i feel a touch of a strawman situation as the spec as stated here prohibits any JS operation to the same constraints. I was thinking about on the fly updating observedAttributes
however perusing the spec defines this operation being put on the queue stack during define
ition and is not a live list. (Perhaps it should be if you have any interest in this feature).
One should be able to use or set attributes on a custom element no different than if an <img>
was in a Svelte component. Hence why I said your particular repro is merely an edge case of the DOM that would be there if custom elements didn't exist.
Thanks for the chat. Felt good riding on a 🦄 for a little bit but I think my $0.25 is up my friend. Meaning...what I proposed is great in theory. But Svelte doesn't have to do anything but sit back as it's in good position already.
Below are the implementation operations the platform must abide by. It's the isRunning
flag that's why the attribute list can't be live:
FWIW jQuery has been doing the same for almost a decade now. "Fast" often just has to be "Fast enough". And human perception of "instant" is 30ms. That's why benchmarks are futile. But that's a topic for another day: ❤️
// what React proposes for coupling with jQuery testing.
$('input', this.getDOMNode()).prop({
indeterminate: true,
checked: false
})
No magic trick there. Just plain (sequential) prop
erty updates to the HTML attribute. Any library would be in the same boat if needing transactional attribute updates. Luckily have the callback stack that only queues updates. They are processed non-determinantly so could possibly get off 2 operations in 1 on the queue but haven't tested so could be wrong.
from svelte.
Going to close this in favour of #797, which is a proposal for outputting custom elements directly from the compiler.
from svelte.
@Rich-Harris agreed! Wherever I can help let me know. I rock with you.
from svelte.
Related Issues (20)
- Ternary in html attributes doesn't compile for production HOT 2
- Svelte 5 bug when moving mouse HOT 6
- $state, $bindable without backup value become 'undefined' in $derived HOT 5
- Svelte 5: SSR breaks rendering of Select component when HMR is enabled HOT 19
- Data returned from load function is stateless HOT 2
- Svelte 5: Add `class:list` directive HOT 5
- Individual states seemingly working like a singleton? I don't even know how to caption this HOT 1
- Distinguish between properties and attributes on custom elements HOT 10
- [REPL] modifying file name to same value wipes contents HOT 1
- `$props` aliasing allows invalid names HOT 7
- Svelte5: unexpected `Component` type errors HOT 4
- Ability to ignore svelte warnings other than a11y HOT 2
- Svelte 5: only block root tags are checked for being closed HOT 9
- svelte5: while binding this to none-existing property on desctructed object, svelte adds the property HOT 4
- `<script context="module">` -> `<script module>` HOT 5
- PreventDefault on touchstart not working! HOT 13
- Svelte 5: `draggable="false"` gets rendered as `draggable="true"` when using `<svelte:element>`
- Svelte 5 performance of style and class directives
- Destructuring on input fills all values. HOT 1
- Class state has a fundamental typing flaw HOT 15
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from svelte.