Open NullVoxPopuli opened 5 days ago
This is very open ended. I think some ideas need to thought about first.
Specifically that the Glimmer-VM is currently designed to manage rendering from the top down holistically. What I mean by that is Each component that Glimmer renders is invoked by another parent Glimmer Component making the Glimmer-VM the main rendering engine for the entire hierarchy. Obviously there is a top mount point but once in there it is usually Glimmer all the way down. React is like this to.
However, thinking about this more, if a Glimmer component mounted to its own custom element it could be a self contained tree much like an island. The more I think about it it would mean that a Glimmer Component would have two modes. If added to the DOM via <custom-element>
then it would mount the Glimmer component to the custom element shell via its connectedCallback()
But once the Glimmer Component part (mode) renders it could then invoke just Glimmer Components without the need to wrap them in a custom element.
Basically when the Glimmer-VM renders a Glimmer Component <MyComponent>syntax</MyComponent>
it is just like any other Glimmer environment. But if the same component is invoked via <my-component>syntax</my-component>
Then it is isolated (has it's own shadow DOM or what ever) and does not participate in the same DDAU you normally get as the parent Component sees it as just another custom-element even though internally it has a new Glimmer-VM rendering instance under the hood.
I think most of all what you mention above is available as is and only needs a connectedCallback()
level addition to the base implementation. Thoughts?
Example:
<div ...attributes>
I am just a Glimmer component
<FooBaz @note="this is another glimmer component" />
<baz-frotz>
This is a glimmer component but lacks all the glimmer parts as it is treated like any other Vanilla Element.
</baz-frotz>
</div>
Then in the VanillaJS page: document.body.appendChild(document.createElement('foo-bar'))
.
FooBar's connectedCallback
will instantiate a VM instance and use it to render its shadowDOM which will have a <div>
and its attributes splatted. It will invoke a FooBaz
component like in Ember (yields, blocks, helpers, modifiers, and all). But the <baz-frotz>
is a generic element from the FooBar's perspective only talking via attributes and events.
Meanwhile, BazFrotz's connectedCallback
will instantiate a VM instance and use it to render its shadowDOM
I think our fist step is to see if we can get a non ember Glimmer app to mount to it's own shadowDOM via a connectedCallback
we would have the initial POC to move on to other features.
But I do think it is important to keep the invocation of a <GlimmerCoponent>
separate from the insertion of a <custom-element>
and in that way minimal if no modification would be needed to the Glimmer-VM for the first MVP.
What things do we need to compile, and how?
Features that don't exist or have direct equivalents will need to be compiled to lower-fidelity native web-component behaviors and APIs,
Yield and Named Yield
Blocks and named blocks / slots can provide data back to the caller
Potentially: https://fancy-pants.js.org/module-component-Component.html#yields
...attributes
Applying all attributes on a specific element within the component.
Currying components, modifiers, helpers
Yielding pre-wired up components, modifiers, and helper-functions to the caller.
Could maybe do https://lit.dev/docs/data/context/
Reactivity
Optimized minimal updates to the DOM when data changes
Template Control Flow
ifs, each, etc