Re: [Custom Elements] They are globals.

I get what you mean about the behaviors defined from classes that
exist in the scope, in React. The really great thing about React is
the ability to compose a class by using multiple classes to return the
render spec. One of React's strong-points at a high level is it offers
encapsulation where the components used in the HTML (which don't map
directly to the actual DOM result that the browser is finally given)
are specific to the component, encapsulated there.

The current methods of encapsulation that I see with normal HTML are
documents and shadow roots, where shadow roots seem to be closer to
React than documents because the top-level HTML that we inspect in the
DOM may not be what is actually rendered (like with React), although
the implementation is completely different, but at a high level shadow
dom has that small similarity with React.

So, to make code-reuse as possible as it is with React (due to React's
aforementioned encapsulation and use of the JavaScript scopefor it's
"HTML elements"), maybe the Custom Element API can take advantage of
ShadowDOM instead of documents?

What if custom elements can be registered on a shadow-root basis, so
that the author of a Custom Element (one that isn't registered by
default) can register a bunch of elements that it's shadow root will
use, passing constructors that the author code may have imported from
anywhere. Then that same author simply exports the custom element
(does not register it) for a following author to use. The following
author would import that custom element, then register it with the
shadow roots of his/her new custom elements, and thus the cycle
continues, with registered elements defined on shadow roots on a
per-custom-element basis, without those elements ever being registered
to some global registry.

```
// library code
import SomeClass from './somewhere'

export default
class AuthorElement extends HTMLElement {
    constructor() {
        this.shadowRoot.defineElement(
            'authors-should-call-this-anything-they-want',
            SomeClass
        )
        // ...
    }
}
```

Then, finally, the top-level app author can register the top-most
custom elements using an API similar to current, in the top-level
namespace (global scope) for the window or document.

```
// app code
import AuthorElement from './AuthorElement'
document.defineElement(
    'any-name-the-app-author-wants',
    SomeClass
)
```

So, basically, inaddition to global/window-or-document-based elements
there'd also be shadow root definitions for encapsulation, since
shadow roots are to custom elements as what (slightly stretched) JSX
specs are to React components.

An important part of the Custom Element API would be that Custom
Element authors should never register their Custom Elements globally,
only export them for the user of their custom element to register
them. The final top-level app author would register only the elements
that will be used in the top-level HTML of the app, all other elements
already registered in their shadow roots by the authors of each
element.

Something like this would create a development environment much more
similar to React, having encapsulation and making code more re-usable.
The only downside of this approach would be the need to manually
register elements per-shadow-root, not just importing them (in react,
importing is enough, as the JSX uses the JavaScript scope as the
element registry).

On a side note, interestingly, template string tag functions would let
us take advantage of JavaScript scope directly without build tools:

```
import SomeClass from './SomeClass'
import OtherClass from './OtherClass'

html`
  <div>
      <${SomeClass}>
          <${OtherClass}>
          </${OtherClass}>
      </${SomeClass}>
  </div>
`
```
/#!/JoePea


On Mon, Apr 11, 2016 at 11:25 AM, Domenic Denicola <d@domenic.me> wrote:
> I think you are being misled by a superficial similarity with React's JSX.
>
> JSX's `<Foo>` desugars to `React.createElement(Foo)`, which creates a `<div>` element with some of its behavior derived from the `Foo` class, found in JavaScript lexical scope. The `Foo` token has no impact on the DOM tree.
>
> Custom elements' `<x-foo>` is completely unlike that. In that case, `x-foo` is a tag name, and a full participant in the DOM tree structure. It affects CSS selector matching, APIs like querySelector and getElementsByTagName, and more. It's not just a div.
>
> As Ryosuke notes, it's very hard to imagine how "scoped tag names" would work. Both for implementation reasons, like the HTMLElement constructor, but also for cases like CSS or the DOM APIs, which operate fundamentally on a global mapping.
>

Received on Monday, 11 April 2016 21:30:09 UTC