Los web componentes son una serie diferentes tecnologías estándar que nos permiten re-utilizar elementos HTML personalizados, en otras palabras lo que llamamos componentes. Muy similar a lo que se puedes hacer con librerías como React, Vue, Angular, pero, con una gran diferencia: de manera nativa.

Especificaciones

A continuación vamos a describir cada una de las tres especificaciones actuales.

Sobre HTML Imports, ES Modules y HTML Modules

Es importante recordar que la especificación original mencionaba los HTML Imports como la cuarta tecnología. Sin embargo, los navegadores considerando que los ES Modules podrían ser la solución alternativa. Por lo que, a partir de la version de Google Chrome 73, esta tecnología se volvió obsoleta. Hoy por hoy, se esta trabajando en una nueva propuesta llamada HTML Modules que pretende complementar ES Modules e integrar HTML Imports.

Más información

Custom Elements

Con Custom Elements básicamente podemos crear elementos HTML de manera personalizada. Es decir, asi como tenemos <div>, <span>, <input>, etc. Podemos crear un elemento llamado <primary-button> que al hacer usado nos mostraría un botón con unas características especificas.

Con este ejemplo cada vez que yo introduzca el elemento <primary-button> va a mostrar el button azul vemos arriba. Como pueden estamos aplicando estilos inline al contenido de nuestro Custom Element, pero también podemos aplicar estilos directamente al Custom Element desde un archivo CSS.

Hay dos tipos de Custom Elements:

  • Autonomous custom elements: Estos son elementos independientes que casi siempre heredan de HTMLElement como el ejemplo anterior.
  • Customized built-in elements: Estos son elementos que heredan las propiedades de elementos ya definidos como HTMLParagraphElement o HTMLUListElement, etc. Puede ser muy util para usar las funcionalidades y comportamiento que ya están definidas en el elemento del que heredamos.

Por ejemplo si queremos hacer una lista que tuviese propiedades extra:

// En este caso estenemos del elemento Unordered List 
class DynamicList extends HTMLUListElement { }

// Tambien debemos agregar de donde extiende en la definición
customElements.define('dynamic-list', DynamicList, { extends: "ul" });
<!-- El uso en el HTML varia un poco, usando el atributo is -->
<ul is="expanding-list"></ul>

En el repositorio de MDN (Mozilla Developer Network) podemos ver un ejemplo completo.

Actualmente muchas de las librerías de JavaScript actuales soportan el uso de Web Componentes dentro de ellas. Se puede ver el estado de su soporte aquí.

Acerca del nombre del Custom Element

Es importante que el nombre del Custom Element tenga un - pues de otra manera el navegador tomara el elemento como un elemento desconocido.

Más información

Shadow DOM

Con Shadow DOM tenemos la posibilidad de encapsular estilos y markup en un elemento. El DOM en el documento se le llama generalmente Light DOM, mientras que al DOM dentro de un shadowRoot se le llama Shadow DOM.

En este ejemplo tenemos dos <div> con un elemento <button>  respectivamente. Sin embargo, vemos que en vez de ver los botones "Shadow DOM" y "Light DOM", vemos que el primero imprime "Shadow Root" con unos estilos diferentes. Esto es precisamente porque mediante el Shadow DOM hemos encapsulado los estilos e incluso el botón dentro del shadowRoot.

Modo abierto y cerrado

A la hora de llamar el método attachShadow podemos configurar si queremos que el mode sea open (Abierto) o closed (Cerrado). La diferencia es que el modo open permite acceder al Shadow DOM desde el contexto principal de la pagina, mediante Element.shadowRoot. Si el modo es closed Element.shadowRoot va a retornar null.

Más información

HTML Templates

Con HTML Templates podemos crear templates de forma nativa que no son rendered (pintados) en nuestra pagina, por lo que obtendremos un mayor rendimiento a la hora de carga pero aun asi podemos acceder a ellos mediante JavaScript.

En el ejemplo anterior definimos un template llamado card-template. Solo hasta que leemos nuestra lista de lugares y definimos que vamos a usar el template haciendo una clonación de mismo y luego haciendo una inserción en nuestro documento es que es va a pintar.

Flexibilidad con Slots

Los slots son como pequeños placeholders (comodines) que pueden tener identificación mediante el atributo name. De esta manera podemos definir como queremos estructura la información cuando la recibimos desde un Custom Element.

Un ejemplo completo

Ya que hablamos de cada una de las especificaciones y vimos que se pueden usar de manera independiente. Veamos como podemos usarlas en conjunto para definir un Web Component del mundo real.

Como pueden notar en este ejemplo estamos usando los tres conceptos para crear un Custom Element beauty-card que recibe una imagen, un titulo y una descripción. Si no encuentra una imagen, agregamos una por defecto.

Aplicando estilos a los hijos de los elementos slot

En el ejemplo anterior tuvimos que usar el selector beauty-card img para poder aplicarle los debidos estilos a las imágenes que se pasaron mediante los elementos slot. Aparentemente no hay forma de modificar los estilos desde adentro desde el Custom Element.

Referencias