Skip to main content Accessibility Feedback

Adding options to your Web Component

Yesterday, we learned how to create your first Web Component. Today, we’ll learn how to add options and settings.

Let’s dig in!

Our Web Component

We’ve got our <wc-count> Web Component from yesterday. When someone clicks the <button> element, the Web Component tracks the number of clicks and updates the text with the current count.

<wc-count>
	<button>Clicked 0 Times</button>
</wc-count>

Let’s add some options to let users customize how it works, including…

  • Starting at a number other than 0
  • Increasing the count by more than 1
  • Customizing the button text

Customizing Web Components with attributes

In a traditional JavaScript library, you pass in customizations and settings as an object of options…

new Counter('#my-button', {
	start: 42,
	step: 5,
	text: 'Press Me - {{count}}'
});

With a Web Component, those options are provided as attributes on the Web Component element.

<wc-count start="42" step="5" text="Press Me - {{count}}">
	<button>Clicked 0 Times</button>
</wc-count>

A benefit of this approach is that it’s really easy to provide custom options for different elements in different places in your UI.

You don’t have to instantiate your library multiple times with different settings, or even instantiate it at all. You also don’t need to figure out custom selectors for each different element.

The authoring experience is so much nicer, and it’s immediately obvious what an element’s settings are and what it will do based on the HTML alone.

Saving settings as Web Component properties

Inside our constructor() method, let’s first update our this.count property.

We’ll use the Element.getAttribute() method to get the [start] attribute. This returns a string, so we’ll pass it into the parseFloat() method to convert it to a number.

We’ll assign the value to the this.count property, but if no value is provided, we’ll set it to 0 instead.

/**
 * The class constructor object
 */
constructor () {

	// Always call super first in constructor
	super();

	// Instance properties
	this.button = this.querySelector('button');
	this.count = parseFloat(this.getAttribute('start')) || 0;

	// Listen for click events
	this.button.addEventListener('click', this);

	// Announce UI updates
	this.button.setAttribute('aria-live', 'polite');

}

We’ll do the same thing for the [step] attribute, and assign it to the this.step property.

We’ll also get the [text] attribute, if one exists, we’ll assign it to this.text. If not, we’ll use some default text. We’ll also include a {{count}} string that will serve as a variable we can replace with the actual count.

// Instance properties
this.button = this.querySelector('button');
this.count = parseFloat(this.getAttribute('start')) || 0;
this.step = parseFloat(this.getAttribute('step')) || 1;
this.text = this.getAttribute('text') || 'Clicked {{count}} Times';

Using our settings

Now that we have our user options, we can use them in the Web Component.

Inside the handlEvent() method, we’ll replace this.count++ with code that adds this.step to this.count instead.

/**
 * Handle events
 * @param  {Event} event The event object
 */
handleEvent (event) {
	this.count = this.count + this.step;
	this.button.textContent = `Clicked ${this.count} Times`;
}

We’ll also use the String.prototype.replace() method to replace {{count}} in this.text with this.count, and render that into this.button.

/**
 * Handle events
 * @param  {Event} event The event object
 */
handleEvent (event) {
	this.count = this.count + this.step;
	this.button.textContent = this.text.replace('{{count}}', this.count);
}

Now, users can create different types of counter buttons with different options, and they’ll behave differently.

Here’s a demo.