Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

define: extend built-in elements #34

Closed
AndyOGo opened this issue Jan 15, 2019 · 6 comments
Closed

define: extend built-in elements #34

AndyOGo opened this issue Jan 15, 2019 · 6 comments
Labels

Comments

@AndyOGo
Copy link

AndyOGo commented Jan 15, 2019

I really like the concept.

Can I use define to extend existing build-in elements like <button>?

The docs seem to only support autonomous custom elements 馃
https://hybrids.js.org/core-concepts/definition

@smalluban
Copy link
Contributor

smalluban commented Jan 15, 2019

The hybrids does not support extending built-in elements for two reasons:

  1. Safari won't implement it (I can't find URL with an article about it at the moment), so it is impossible to use them in Safari without polyfill.
  2. It requires using the proper base class, but hybrids definition is all about plain objects with properties. There is no place for setting for example HTMLDivElement rather than HTMLElement.

However, it doesn't mean that you are out of luck. Even though you can't create custom element using is attribute, you can use built-in element inside of your definition:

const MyButton = {
  render: () => html`
    <button>...</button>
  `,
};

A <button> inside of the template still works correctly in accessibility terms, including not required aria attributes.

@AndyOGo
Copy link
Author

AndyOGo commented Jan 15, 2019

@smalluban
Thank for your quick answer.
Yeah I know Safari is the only browser who refuses to support extending built-ins.

Indeed, the correct constructor has to be specified.

Though we need and use it for custom tables, so that we can benefit from rowspan, colspan, etc.

@smalluban smalluban changed the title extend built-in elements define: extend built-in elements Jan 15, 2019
@smalluban
Copy link
Contributor

smalluban commented Jan 15, 2019

If context object鈥檚 local name is not a valid custom element name, article, aside, blockquote, body, div, footer, h1, h2, h3, h4, h5, h6, header, main, nav, p, section, or span, then throw a NotSupportedError DOMException.

Using extended built-ins is limited. For example, table elements don't support Shadow DOM, so building custom tables using them is rather hard to implement. You can't change styles, internal structure, etc... The only thing that you can is adding custom JavaScript logic (new methods, event listeners, behaviors). It is not a real use case for hybrids library.

Also, the whole "is" idea is quite complex and creates a lot of edge cases. That is one of the reasons why Safari might refuse to implement it.

Closing issue. Fill free to re-open if you have any additional questions about the subject.

@AndyOGo
Copy link
Author

AndyOGo commented Jan 15, 2019

@smalluban

Thanks for your quick answer.

Indeed, extended build-ins and the is attribute has consequences for all DOM related API's like document.createElement.
Though it's a living standard despite the fact that Safari refuses to implement it.

IMHO it's a super important feature to extend existing elements, not only in regards to SEO, accessibility, semantics, but also developer effort.

May I ask you to consider this feature and reopen this issue.
Please have a read on this article about extending built-ins:
https://hackernoon.com/extending-built-in-elements-9dce404b75b4

@smalluban
Copy link
Contributor

smalluban commented Jan 16, 2019

I went through the article you provided, and only what I can see there is a lot of hate. I disagree with most of the arguments. V1 version of the Shadow DOM and Custom Elements API is widely supported, and polyfill for Shadow DOM V1 is working (look at the tests results), unlike the V0 version, where it was hard to implement, as for example, you could have multiple shadowRoots. Styling is not so complicated as he claims, and shadow DOM finally introduced real encapsulation, not a fake one - for example using [is="..."] selector can be easily overwritten. Accessibility is still provided, by using built-in elements inside of the custom element. Of course, there are limitations, like building custom inputs, that will work with <form> element. However, with extending built-in elements, you still can't create input, which renders custom content (like calendar or color picker).

The other thing is a hybrids architecture. It was my well-thought-out decision about using plain objects for the definition. It disallows extending custom constructor for the class definition.

Let's take simple composition example. If you have ElementA definition, which you decide that extends <input>, and ElementB, which extends <div>. The first one depends on the input API, so your properties require the HTMLInputElement constructor. Now image, that you want to reuse one of the property from the first definition...

const ElementA = {
  property: ...
};

const ElementB = {
  ...ElementA,
  otherProperty: ...,
};

The composition is broken now - one of the principles of the hybrids. An object with property descriptors can't be related to the custom element base class. There is no place for that.

Custom Element API is very flexible, and if you stick to standards, you can create them with any library or even without them. They will still be able to work together. If you really need to extend built-in elements, you should find another tool for that.

@AndyOGo
Copy link
Author

AndyOGo commented Jan 16, 2019

@smalluban
Thanks for reply.
I appreciate that you took the time to read above article.

I see your points of view.
And as I said, I really like your functional concept.

Though I'm convinced that extending built-ins is a valid concept too.
Nevertheless, it's your lib and so you rule it.

smalluban added a commit that referenced this issue Jan 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants