Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions text/0000-custom-element.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
- Start Date: 2019-07-05
- RFC PR: (leave this empty)
- Lightning Web Component Issue: (leave this empty)

# Summary

Facilitate the registration of LWC Constructor as Custom Elements.
Copy link
Contributor

Choose a reason for hiding this comment

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

registration with what?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

registration of LWC Constructor as Custom Elements


# Motivation

As today, the way to generate a qualifying Custom Element from a LWC Constructor, is via an experimental API: `buildCustomElementConstructor()`. Since this is a primary use case for LWC, we want to make it more ergonomic, and simpler. Additionally, the experimental API allow you to generate more than one Custom Element per LWC Constructors, which does not align with the web components semantics.
Copy link
Contributor

Choose a reason for hiding this comment

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

As of today?


Copy link
Contributor

Choose a reason for hiding this comment

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

Listing a use case would be useful

# Goals

1. Provide a dead simple way to register a custom element from a LWC Constructor.
2. Preserve the web components semantics.

# Proposal

This proposal provides a high-level API (an abstraction layer) for authors to access the custom element associate to a LWC Constructor:
Copy link
Contributor

Choose a reason for hiding this comment

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

did you mean: associated with LWC Constructor?


```js
import XFoo from 'x/foo';
Copy link
Contributor

Choose a reason for hiding this comment

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

is allowing to import 'constructor' property an option?

import { constructor as XFooConstructor } from 'x/foo';

customElements.define('x-foo', XFoo.CustomElement);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is the meat of this proposal... the .CustomElement static accessor on every LWC constructor

Copy link
Contributor

Choose a reason for hiding this comment

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

This would be quite verbose, but what do you think about 'CustomElementConstructor'?

Copy link
Contributor

Choose a reason for hiding this comment

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

The main issue that I have with CustomElement, is that the custom element represents a custom element instance while the custom elements registry accepts a constructor. I support @apapko into making this explicit.

Copy link
Member

Choose a reason for hiding this comment

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

I mentioned a similar concern in salesforce/lwc#1395 (review)

// using tagName `x-foo`:
document.body.appendChild(document.createElement('x-foo'));
```

Pros:
* it is extremely simple.
* it reads very nicely in plain english.
* it preserves the semantics of web components in a way that you can't bend them.

Cons:
* it can't be statically analyzed (but since we don't use this in platform, that should be ok).
* it does not provide a way for you to control whether or not you want open or closed shadowRoot (this is fine because consumers should not be in control)

## Semantics and Invariants

* There is a 1-1 mapping between LWC Constructors and the corresponding Custom Element.
* Claiming the Custom Element for the abstract `LightningElement` must be disallow.
Copy link
Contributor

Choose a reason for hiding this comment

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

what does this mean- Claiming the Custom Element for the abstract LightningElement?


## Implementation Details

`LightningElement.CustomElement` is a static getter that can be accessed by any Constructor extending `LightningElement`. This getter can rely on the `this` value, which points to the sub class. This can be used in a Map to link the LWC to the Custom Element. This is very similar to the trick we use in `LightningContextElement.Provider` for context.

As a consequence of this change, the existing experimental API can be removed.

# Adoption strategy

This is a brand new feature, we just need to document it.

# How we teach this

* The consumer aspect of it is very straight forward considering that they don't have to learn a new API, just a static field name in LWC Constructors.

# Unresolved questions

* How can users control the shadowRoot's mode?