Elementos personalizados
Aprende más sobre el uso de elementos personalizadosLos componentes web de Gstock son elementos HTML normales, o para ser más precisos, elementos personalizados. Puedes usarlos como cualquier otro elemento. Cada componente tiene documentación detallada que describe su API completa, incluyendo propiedades, eventos, métodos y más.
Si no estás familiarizado con los elementos personalizados, a menudo llamados “componentes web”, esta sección te familiarizará con su uso.
Atributos y Propiedades
Muchos componentes tienen propiedades que se pueden configurar a través de atributos. Por ejemplo, los botones aceptan un atributo size que se mapea a la propiedad size que determina el tamaño del botón.
Algunas propiedades son booleanas, por lo que solo tienen valores verdadero/falso. Para activar una propiedad booleana, agrega el atributo correspondiente sin un valor.
En casos excepcionales, una propiedad puede requerir un array, objeto o función. Por ejemplo, para personalizar la lista de muestras predefinidas del selector de color, estableces la propiedad swatches a un array de colores. Esto debe hacerse con JavaScript.
Consulta la documentación de un componente para obtener una lista completa de sus propiedades.
Eventos
Puedes escuchar eventos estándar como click, mouseover, etc. como lo harías normalmente. Sin embargo, es importante tener en cuenta que muchos eventos emitidos dentro del shadow root de un componente serán redirigidos al elemento anfitrión. Esto puede resultar en, por ejemplo, múltiples manejadores de click ejecutándose incluso si el usuario hace clic solo una vez. Además, event.target apuntará al elemento anfitrión, haciendo las cosas aún más confusas.
Como resultado, casi siempre deberías escuchar eventos personalizados en su lugar. Por ejemplo, en lugar de escuchar click para determinar cuándo un <gstock-checkbox> está marcado o desmarcado, escucha gstock-change-event.
Todos los eventos personalizados tienen el prefijo gstock- y el sufijo -event para evitar colisiones con eventos estándar y otras bibliotecas.
Consulta la documentación de un componente para obtener una lista completa de sus eventos personalizados.
Métodos
Algunos componentes tienen métodos que puedes llamar para activar varios comportamientos. Por ejemplo, puedes establecer el foco en un Gstock Input usando el método focus().
Consulta la documentación de un componente para obtener una lista completa de sus métodos y sus argumentos.
Slots
Muchos componentes usan slots para aceptar contenido dentro de ellos. El slot más común es el slot predeterminado, que incluye cualquier contenido dentro del componente que no tiene un atributo slot.
Por ejemplo, el slot predeterminado de un botón se usa para poblar su etiqueta.
<gstock-button>Haz clic</gstock-button>
Algunos componentes también tienen slots nombrados. Un slot nombrado puede ser “llenado” agregando un elemento hijo con el atributo slot apropiado. ¿Notas cómo el icono de abajo tiene el atributo slot="prefix"? Esto le dice al componente que coloque el icono en su slot prefix.
<gstock-button>
<gstock-icon slot="prefix" name="gear"></gstock-icon>
Configuración
</gstock-button>
La ubicación de un slot nombrado no importa. Puedes colocarlo en cualquier lugar dentro del componente y el navegador lo moverá al lugar correcto automáticamente.
Consulta la documentación de un componente para obtener una lista completa de slots disponibles.
No uses etiquetas de cierre automático
Los elementos personalizados no pueden tener etiquetas de cierre automático. Similar a <script> y <textarea>, siempre debes incluir la etiqueta de cierre completa.
<!-- No hagas esto -->
<gstock-input />
<!-- Siempre haz esto -->
<gstock-input></gstock-input>
Diferencias con elementos nativos
Podrías esperar que los elementos con nombres similares compartan la misma API que los elementos HTML nativos, pero este no es siempre el caso. Los Gstock Web Components no están diseñados para ser reemplazos uno a uno de sus contrapartes HTML. Si bien a menudo comparten la misma API, puede haber diferencias sutiles.
Por ejemplo, <button> y <gstock-button> ambos tienen un atributo type, pero el nativo por defecto es submit mientras que el de Gstock por defecto es button, ya que este es un mejor valor predeterminado para la mayoría de los casos.
¡No hagas suposiciones sobre la API de un componente! Para evitar comportamientos inesperados, tómate el tiempo de revisar la documentación y asegúrate de entender qué se pretende que haga cada atributo, propiedad, método y evento.
Esperando a que los componentes se carguen
Los componentes web se registran con JavaScript, por lo que dependiendo de cómo y cuándo cargues Gstock, podrías notar un Flash de elementos personalizados indefinidos (FOUCE) cuando la página se carga. Hay un par de formas de prevenir esto, ambas descritas en el artículo enlazado.
Una opción es usar la pseudo-clase CSS :defined para “ocultar” elementos personalizados que aún no han sido registrados. Puedes limitarlo a etiquetas específicas, o puedes ocultar todos los elementos personalizados indefinidos como se muestra a continuación.
:not(:defined) {
visibility: hidden;
}
Tan pronto como un elemento personalizado se registra, aparecerá inmediatamente con todos sus estilos, eliminando efectivamente el FOUCE. Nota el uso de visibility: hidden en lugar de display: none para reducir el desplazamiento a medida que los elementos se registran. La desventaja de este enfoque es que los elementos personalizados pueden aparecer potencialmente uno a la vez en lugar de todos a la vez.
Otra opción es usar customElements.whenDefined(), que devuelve una promesa que se resuelve cuando el elemento especificado está registrado. Probablemente querrás usarlo con Promise.allSettled() en caso de que un elemento falle al cargar por alguna razón.
Una forma inteligente de usar este método es ocultar el <body> con opacity: 0 y agregar una clase que lo haga aparecer tan pronto como todos los elementos personalizados estén definidos.
<style>
body {
opacity: 0;
}
body.ready {
opacity: 1;
transition: 0.25s opacity;
}
</style>
<script type="module">
await Promise.allSettled([
customElements.whenDefined('gstock-button'),
customElements.whenDefined('gstock-input'),
customElements.whenDefined('gstock-select'),
]);
// ¡El botón, input y select están registrados ahora! Agrega
// la clase `ready` para que la UI aparezca gradualmente.
document.body.classList.add('ready');
</script>
Renderizado y actualización de componentes
Los Gstock Web Components están construidos con Lit, una pequeña biblioteca que hace que crear elementos personalizados sea más fácil y mantenible. Aquí hay información útil sobre renderizado y actualización que probablemente deberías saber.
Para optimizar el rendimiento y reducir los pases de renderizado, Lit agrupa las actualizaciones de componentes. Esto significa que cambiar múltiples atributos o propiedades a la vez resultará en un solo pase de renderizado. En la mayoría de los casos esto no es un problema, pero puede haber momentos en los que necesites esperar a que el componente se actualice antes de continuar.
Considera este ejemplo. Cambiemos la propiedad checked del checkbox y observemos su atributo checked correspondiente, que resulta reflejarse.
const checkbox = document.querySelector('gstock-checkbox');
checkbox.checked = true;
console.log(checkbox.hasAttribute('checked')); // false
La mayoría de los desarrolladores esperan que esto sea true en lugar de false, pero el componente no ha tenido la oportunidad de volver a renderizarse todavía, por lo que el atributo no existe cuando se llama a hasAttribute(). Dado que los cambios se agrupan, necesitamos esperar a que ocurra la actualización antes de continuar. Esto se puede hacer usando la propiedad updateComplete, que está disponible en todos los componentes basados en Lit.
const checkbox = document.querySelector('gstock-checkbox');
checkbox.checked = true;
checkbox.updateComplete.then(() => {
console.log(checkbox.hasAttribute('checked')); // true
});
¡Esta vez vemos una cadena vacía, lo que significa que el atributo booleano está ahora presente!
Evita usar setTimeout() o requestAnimationFrame() en situaciones como esta. Pueden funcionar, pero es mucho más confiable usar updateComplete en su lugar.
Completado de código
VS Code
Gstock Web Components incluye un archivo llamado vscode.html-custom-data.json que se puede usar para describir componentes web en Visual Studio Code. Esto habilita el completado de código (también conocido como “sugerencias de código” o “IntelliSense”). Para habilitarlo, necesitas decirle a VS Code dónde está ubicado el archivo.
- Instala Gstock Web Components localmente
- Si no existe ya, crea una carpeta llamada
.vscodeen la raíz de tu proyecto - Si no existe ya, crea un archivo dentro de esa carpeta llamado
settings.json - Agrega lo siguiente al archivo
{
"html.customData": ["./node_modules/@gstock/webcomponents/dist/vscode.html-custom-data.json"]
}
Si settings.json ya existe, simplemente agrega la línea anterior a la raíz del objeto. Ten en cuenta que es posible que necesites reiniciar VS Code para que los cambios surtan efecto.
IDEs de JetBrains
Si estás usando un IDE de JetBrains e instalando Gstock Web Components desde NPM, el editor detectará automáticamente el archivo web-types.json del paquete y deberías ver la información del componente web en tu editor inmediatamente.
{
...
"web-types": "./web-types.json"
...
}
Si estás usando tipos de múltiples proyectos, puedes agregar un array de referencias.
{
...
"web-types": [..., "./web-types.json"]
...
}