Open MartinKavik opened 4 years ago
Makes perfect sense to me. If I can reuse existing components easily, I can get results faster. This property is crucial for decision making in commercial projects.
@TatriX do you any experience with them?
So as mentioned on discord I think in theory this could be a great idea however the interop between seed infrastructure and a Web Component would need to be carefully thought through.
I.e. what api will seed expose to web components and what will it hook into. For instance will connectedCallback and attributeChangeCallback trigger seed messages etc. If so could this fall into the same inconsistent problems that virtual dom diffing triggering lifecycle hooks have?
So in short a good idea but needs careful thought.
I can't comment at this time, due to not being familiar with Web Components.
It would be great to have this functionality, especially Shadow Dom which would allow using CSS animations/selector without relying on CSS files, thus making very dynamic components.
@David-OConnor In a nutshell:
<my-div my-super-value="3000"><div id="I'm child"></div></my-div>
. connectedCallback
that can be used as lifecycle parts.el_ref
.Thank you for the detailed explanation
Hi @MartinKavik I would be interested in generating webcomponents with Seed. ~~Since @rebo mentioned discussions on discord, I wanted to know where I can find them. Unfortunately, there is no link or mention on the seed.rs webpage or Github repo.~~ Edit: found the link in #303 after skimming through open issues. Would it make sense to make the channel more public or do you still want to wait to see if discord is the right choice?
Since I have a small personl project in which I used webcomponents and one where I would like to use them, I could at least do testing, if time permits.
I did some research about implementation and found a blocker - wasm-bindgen
isn't smart enough (yet) to create a necessary bridge between the Rust and JS world to create custom elements.
Unfortunately I don't have enough free time to help them to add needed support. So I have to stop working on this issue until wasm-bindgen
is improved or I have a generous sponsor 💰
So.. you can use JS/TS components at the moment, but they are reconnected on each DOM render and not very tested. We/I'll add better support once the blocker above is resolved and I can write a library for creating custom elements.
IMO, I think it would be wise to consider exposing the base web components APIs as directly as possible, starting with an focusing on the custom elements API. A Seed component should be an HTML custom element. It should have all of the lifecycle methods of a custom element. It should be a DOM object under the hood. Any conveniences, like automatic getters and setters, can be built on top. This is what I would love to see.
@lastmjs If I understand you correctly - that's the plan. You would be able to use custom elements as black boxes - it's not important if they were written in/with VanillaJS, Typescript, Rust, LitElement, etc. The next step would be to create our web component API wrapper/library - so you can reuse your Seed knowledge (e.g. write HTML with Seed macros) and it's not as painful as writing custom elements with the original API.
Sounds pretty good then. Though, there are only a few major pain points with the raw custom elements API, IMO. Having a templating library with data binding to properties and event handlers, and automatically rendering when attributes or properties change. I use vanilla custom elements, extending directly from HTMLElement in JavaScript/TypeScript. Using a simple templating library like lit-html and some state management like Redux makes writing custom elements simple and elegant. I suppose my point is, I don't think you need to do much over the custom element APIs.
I also think it would be important to expose the entire custom element API just in case the developer needs access to it. I would still love to be able to hook into connectedCallback and create my own getters and setters
https://hybrids.js.org/ does nice job to wrap custom elements with functional API.
import { html, dispatch } from 'hybrids';
function change(host) {
host.value += 1;
// Trigger not bubbling `change` custom event
// Element user can subscribe to this event with
// `el..addEventListener('change', callback)
dispatch(host, 'change', { detail: host.value });
}
const MyElement = {
// This `value` becomes an attribute of the custom element.
// When the user of the element sets new value,
// the system calls `render` function with a new value.
value: 0,
render: ({ value }) => html`
<button onclick="${change}">You clicked me ${value} times!</button>
`,
};
Receiving attributes from the user could be done as a method for the application builder
Builder::handle_attribute(Builder, Fn(String, Strung) -> Ms)
where the first argument is the attribute name and the second is the value. And dispatch
could be added to Orders trait.
Hey guys, I'm thinking about implementing first-class support for not-only-Rust Web Components. Before I write some reasoning about it I would like to know your opinions and experience. So.. what do you think?