When writing a good component, it’s good to have a few things in mind. We follow the standards of @open-wc. On top of these standards, we have some custom standards to have a better and consistent way of working.
To get started right away, please check out the starter component
Designing
Before start working on a new component, we can make use of Figma to design the component. A figma organization is in place here.
Development
Coding
For a consistent development process, we have EsLint in place.
Styling
We make use of css variables. Basic variables can be seen here.
Testing
We can divide testing into 2 parts, unit testing and integration testing.
For unit testing, we use the .spec.ts
files. For integration testing, we use the .test.ts
files.
To unit test a component, we can create the component class as-is and test the exposed functions.
To integrate test a component, we can make a fixture
from the webcomponent and test that fixture
.
We also screenshot test each component.
Demoing
For demoing the component, we make use of Storybook.
It’s important to keep in mind that we only want to demo the current component in a story. Best way is to have a story for each variant.
Let’s say we have a custom element called my-button. This button can have 2 colors, primary and secondary. This button can also have the state disabled
.
This means that we need 4 stories: primary
, primary/disabled
, secondary
and secondary/disabled
.
Documentation
Cem Analyzer
You can add comments to your component, so the Custom Element Manifest Analyzer (CEM Analyzer) can generate docs from this.
CEM analyzer supports the following annotations:
@slot [name] | Document the named slot on top of the class |
@slot | Document the default slot on top of the class |
@cssprop | Document the css property on top of the class |
@event [name] | Document the events that can be fired from this component on top of the class |
@prop [name] | Document the property |
@internal / @ignore | Ignore these from CEM |
Example:
/**
* @slot icon - You can place the icon for the button here
* @slot - Default button slot
* @cssprop --text-color - Controls the color of the button
* @cssprop --background-color - Controls the background of the button
*
* @event {click} clickEvent - Emits a click event when button is clicked
*
* @summary This is the `my-button` Component, which represents a styled button.
*
* @tag my-button
*/
@customElement('my-button')
export class MyButton extends LitElement {
/**
* @prop {String} title - The title of the button. Showed when hovering over the button.
*/
@property({
type: String
})
title: string = '';
render(): TemplateResult {
return html`<button
class="button button--primary"
@click=${() => this.handleClick}
title=${this.title}
>
<span slot="icon"></span>
<slot></slot>
</button>`;
}
private handleClick() {
this.dispatchEvent(new CustomEvent('click');
}
static styles = css`
.button {
background: var(--background-color);
color: var(--text-color);
}
`;
}
Deploying
We deploy our components to npmjs. To test this locally, you can make use of verdaccio. Verdaccio is a local npm registry.
To make verdaccio work, just follow the installation process here.
Next, create a .npmrc
in your project root that points to your verdaccio registry.
Example:
registry=http://localhost:4873
Now you can test your published component in a new project (just use npm i [component_name] --regsitry=http://localhost:4873
Storybook can be deployed to the GitHub Pages of the repository.
To do automatic deploys, you can check out the GitHub actions in oscd-component.