0.3.7 ā€¢ Published 1 year ago

vanilla-elements v0.3.7

Weekly downloads
-
License
ISC
Repository
github
Last release
1 year ago

Vanilla Elements

Social Media Photo by Jocelyn Morales on Unsplash

šŸ“£ This project didn't gain nearly nough attention as hoped so I've decided to extend builtins with nonchalance and I suggest you check that out instead, as it doesn't rely at all to a maybe polyfill needed to work, it doesn't need to patch globals, and most importantly, it's half of the size of this module through its /runtime variant.


A Minimalistic Custom Elements Helper, with optional polyfill included, compatible with every evergreen browser.

The default module export, which is ~0.5K, works natively in Chrome, Edge, and Firefox, but if you target Safari / WebKit too, you can use the vanilla-elements/poly variant, which is ~2K, and it includes proper features detection, leaving Chrome, Edge, and Firefox 100% native.

import {define, HTML} from 'vanilla-elements';

// generic components ... or
define('my-comp', class extends HTML.Element {
  // native Custom Elements definition
});

// ... builtins extend simplified ... and
define('my-div', class extends HTML.Div {
  // native Custom Elements definition
});

// ... as decorator šŸ„³
@define('my-footer')
class MyFooter extends HTML.Footer {}

document.body.appendChild(new MyFooter);

API

  • the define(name:string, Class):Class automatically recognize the right way to define each component, either generic elements or built-ins.
  • the HTML namespace contains all available HTML classes from the browser, with shortcuts such as Div, Main, Footer, A, P, and everything else.

Live Example

import {define, HTML} from 'vanilla-elements';
import {render, html} from 'uhtml';

define('h2-greetings', class extends HTML.H2 {
  constructor() {
    super();
    this.html = (...args) => render(this, html(...args));
    this.render();
  }
  render() {
    this.html`Hello Vanilla Elements šŸ‘‹`;
  }
});

render(document.body, html`
  <h2 is="h2-greetings" />
`);

F.A.Q.

Beside solving this long outstanding bug out of the box, the feature detection for builtin extends is both ugly and not really Web friendly.

One could simply include @ungap/custom-elements polyfill on top of each page and call it a day, but I wanted to have only the missing part, builtin extends, embedded in a module, and this helper is perfect for that purpose.

On top of that, I really don't like the ugly dance needed to register builtin extends, so that having a tiny utility that simplifies their definition seemed to be about right.

// without this module
customElements.define(
  'my-div',
  class extends HTMLDivElement {},
  {extends: 'div'}
);

// with this module
import {define, HTML} from 'vanilla-elements';
define('my-div', class extends HTML.Div {});

As we can see, the definition through this module is more compact, elegant, and natural, than its native counter-part, and that's about it.

The only browser that needs a polyfill for builtin extends is Safari / WebKit, and it needs it only for builtin extends, but not everyone develops for the Web, and not everyone uses builtin extends, so the sane default is to provide a minimal utility that simplifies custom elements registration that works out of the box in every modern browser.

Whenever the target needs to include Safari / WebKit, and builtin extends are used, it takes nothing to switch import from vanilla-elements to vanilla-elements/poly or use an import-map workaround to load the poly only in Safari.

<!doctype html>
<script>
(({document, chrome, netscape}) => {
  const src = 'https://cdn.skypack.dev/vanilla-elements/';
  const {head} = document;
  const script = head.insertBefore(document.createElement('script'), head.firstChild);
  script.type = 'importmap';
  script.textContent = JSON.stringify({
    imports: {
      'vanilla-elements': (chrome || netscape) ? src : (src + 'es.js')
    }
  });
})(self);
</script>

For development usage, through bundlers and similar tools:

  • vanilla-elements points at the main.js, and it doesn't include the polyfill
  • vanilla-elements/poly points at the generated index.js file, and include the polyfill after feature detection

For CDN usage in the wild:

  • the //unpkg.com/vanilla-elements CDN points at the minified es.js which includes the polyfill (it's the minified index)
  • for skypack.dev minified file, you can point at the es.js file directly: //cdn.skypack.dev/vanilla-elements/es.js

0.3.7

1 year ago

0.3.6

2 years ago

0.3.5

2 years ago

0.3.4

2 years ago

0.3.3

2 years ago

0.3.0

2 years ago

0.3.2

2 years ago

0.3.1

2 years ago

0.2.4

2 years ago

0.2.3

3 years ago

0.2.2

3 years ago

0.2.1

3 years ago

0.2.0

3 years ago

0.1.6

3 years ago

0.1.4

3 years ago

0.1.5

3 years ago

0.1.3

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago

0.0.0

3 years ago