-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Proposal] Registration API #52
Comments
What is the benefit of this over just doing |
I can think of some benefits:
|
But you can just do this as well? Im trying to understand what the benefit of having a import Button from "./components/button.js";
import Icon from "./components/icon.js";
import Selector from "./components/selector.js";
[Button, Icon, Selector].forEach((comp) => {
comp.tagName = "prefix-" + comp.tagName;
- comp.register();
+ customElements.define(comp.tagName, comp);
}); |
@oscarotero thanks for starting this conversation!! The "Goals" section proposed in @matthewp's protocol proposal template will be a useful piece of work to smooth the discussion around any proposal. Would be great to start there (even if it's just one or two to get the conversation started) in issues opened as well, so we can all be sure to be on the same page when discussing something like this. We will be discussing the template ratification at next week's Web Components Community Group meeting, feel free to join in the conversation. |
Thanks @Westbrook |
I've used a similar pattern in WebComponents.guide. One of the benefits to having a static method call is that components can more easily register their dependants, and I imagine it'll be more useful when we have scoped registries: class MyComponent extends HTMLElement {
static define(tagName = 'my-component', registry = customElements) {
registry.define(tagName, this);
const myreg = new CustomElementRegistry()
MyDependant.define('my-dependant', myreg);
MyOtherDependant.define('my-other', myreg);
}
} This allows consumers to call |
Shouldnt an element that uses other elements internally via scoped registries just define them by default? If you forget calling .define, the element doesnt render anything? Why not do it automatically? |
You mean to move it into the constructor or something? So the code in my comment would instead be: let registry = new CustomElementRegistry()
class MyComponent extends HTMLElement {
constructor() {
super()
if (!registry.get('my-dependent')) registry.define('my-dependent', MyDependent)
if (!registry.get('my-other')) registry.define('my-other', MyOtherDependent)
}
} |
Yeah, or something like we do in scoped-elements: https://github.com/open-wc/open-wc/blob/master/packages/scoped-elements/html-element.js im not sure what the benefit of requiring a consumer of your element to manually call .define before being able to use the element is? I do like a static property to suggest a default tagName (even though its just that; a suggestion, because a consumer of your class may register it under a different name) I also do this in generic-components, I just dont think a lot of abstractions over customElements.define actually provide anything over… just calling customElements.define. |
I believe scoped registries solve all use cases listed so far. The only difficulty is getting all library authors to not automatically define their elements. And what about existing libraries that authors don't have time to update existing libraries? There are many custom elements today using a class decorator like Maybe that's what frameworks similar to Lit should do in that case, is release a breaking major version at some point where the decorator does not define by default? Those decorators can return a subclass with a method similar to above import {element, Element} from '@lume/element'
@element('my-el')
export class MyEl extends Element {...} import {MyEl} from './MyEl.js'
// ... inside other element class ...
const reg = new CustomElementsRegistry()
this.attachShadow({mode: 'open', customElements: reg})
MyEl.defineElement() // error, no reg provided
MyEl.defineElement(reg) // ok
MyEl.defineElement(reg, 'other-name') // custom name |
But I strongly agree with @thepassle that abstracting The biggest problem I have with this protocol proposal is: I don't think this is a protocol, since it doesn't relate to interaction between components. A component author could simply choose to expose this or some variation of it as part of a component's public API, and indeed, the only way you could use this is if the component author chose to make it part of the public API—in which case, this isn't some standard 'protocol'; it's just that component's particular API. This proposal cannot achieve "a consistent way to register web components" for "all components", since in general, most components will not support this. And indeed, we already have a consistent way to register web components, that all components support: it's |
FWIW instances can access |
I was mistaken in my previous comment; I got confused and thought you could register a custom element twice under different names, but it's fairly intuitive that you can't, since if you instantiated a custom element directly, but it has multiple names, what the tag name would be for that instance is indeterminate. Given that, I don't think it's obvious that user-customized tag names actually are a good idea. If two different implementations try and define the same custom element on the same page under different names, the one that goes second will fail, which is unpredictable since in general the ordering is arbitrary. Of course, scoped registries would theoretically solve this problem, and the fact that this limitation exists at all is silly (I think all the limitations of custom element registries are silly, but that's a matter for another time), but the single global registry is currently the status quo. The linked article justifies user-customized tag names by saying
But I think the flexibility the author desires simply isn't possible with a single global registry. Customizing the tag name solves one problem but creates another, equivalent problem. EDIT: Also, how do we know whether |
Hi. I'd like to propose a generic API to register custom elements easier, and allow to customize the tag name if it's needed. I got the inspiration from this article from @mayank99.
The code:
This would allow to register the element in different ways:
The text was updated successfully, but these errors were encountered: