Velo By Wix: Types definitions for Custom Components
How to add support type checking for DOM elements in Velo using TypeScript Triple-Slash Directives
Velo editor has the built-in TypeScript compiler for type checking and code auto-completion. In the previous two posts, we looked at how to use JSDoc types annotations for Velo elements. And how to create global types.
In this post, we look at how to add type support for Custom Components development when we use Browser APIs like the window, document, customElements, etc.
DOM types support
In Velo, we have built-in support for DOM types. The DOM types are disabled by default. We can turn on it with the special JavaScript comment. TypeScript uses this comment as compiler directives.
All we need to do it's add a Triple-slash directive to the top of the file where we will use DOM APIs.
Add DOM types checking in Velo editor
/// <reference lib="dom" />
With this directive, TypeScript starts to use DOM types. 🙌
It provides a better development experience and saves a lot of time.
Example of use
TypeScript directives are open to us writing the Custom Component code in public files. We can move part of the code to a public file and reuse it for a few Custom Components.
Just try the next code in your project:
There is a util file with a function for creating a new HTML element. We can add DOM types annotations to provide type information about function signature.
public/domUtils.js
/// <reference lib="dom" />
/**
* @template {keyof HTMLElementTagNameMap} T
* @param {T} tagName
* @param {Partial<HTMLElementTagNameMap[T]>} [attrs]
* @returns {HTMLElementTagNameMap[T]}
*/
export const createElement = (tagName, attrs) => {
return Object.assign(document.createElement(tagName), attrs);
}
We can ensure that the util function covers DOM types.
public/custom-elements/my-button.js
import { createElement } from 'public/domUtils';
const css = `
.my-button {
border: 1px solid #000;
padding: 10px 20px;
cursor: pointer;
}
`;
class MyButton extends HTMLElement {
constructor() {
super();
const style = createElement('style', {
textContent: css,
});
const button = createElement('button', {
type: 'button',
textContent: 'Click Me',
className: 'my-button',
onclick: () => {
this.dispatchEvent(new CustomEvent('click'));
},
});
this.attachShadow({ mode: 'open' }).append(style, button);
}
}
customElements.define('my-button', MyButton);