CWCO logo

v1.7.9

Observed Attributes

Observed attributes are any HTML attributes you decide that should trigger an update when set, removed or updated. In other libraries and frameworks these are often referred to as Props.

Defining observed attributes

CWCO way to declare observedAttributes is the same as the native way. It must be declared as an array of string attributes exactly how they would appear when set on the HTML tag.

class SubmitButton extends WebComponent {
	static observedAttributes = ['label'];

	get template() {
		return '<button type="submit">{label}</button>';
	}
}
<submit-button label="Send Message"></submit-button>

The web standard rules to naming attribute are:

  • kebab-case
  • lowercase
  • must start with a letter
  • may contain numbers

Any attribute will automatically convert to lowercase when set on the DOM. It is very important to follow these rules when observing custom attributes for your component.

Attribute to properties.

CWCO takes the list of observedAttributes to change into camelCased properties. This is so you can reference them inside the class and from the component element instance.

Accessing observed attribute

If the attribute is in kebab case they will be changed into a camel case equivalent class property.

class StatusIndicator extends WebComponent {
	static observedAttributes = ['current-status'];

	get template() {
		return '<div class="curr-status">{currentStatus}</div>'
  }

	onMount() {
		console.log(this.currentStatus)
	}
}

StatusIndicator.register();

Since attributes are mapped to be properties, they also work like properties.

const indicator = new StatusIndicator();

document.body.appendChild(indicator);

// access attribute as property
indicator.currentStatus = 'Pending';

When setting them, you use their attribute name.

const indicator = new StatusIndicator();

document.body.appendChild(indicator);

// access attribute as attribute
indicator.setAttribute('current-status', 'Pending');

class, data-* and style attributes

There are three special attributes that will not be mapped to properties because they already contain their respective special properties in the element.

These are the class, style and data-* attributes.

class StatusIndicator extends WebComponent {
	static observedAttributes = [
		'class',
		'style',
		'data-sample'
	];
}

When you observe these attributes you can later access them like:

  • class: className or classList;
  • style: style;
  • data-x: dataset;

When you use these native properties to update the attributes, they will trigger the onUpdate callback as long as they are observed.

const indicator = new StatusIndicator();

indicator.className = 'indicator';
indicator.classList.add('active');
indicator.style.background = 'red';
indicator.dataset.sample = 'x'

Default value

By default an attribute is either a string or boolean. HTML has boolean attributes and CWCO will automatically detect these and create a property matching them with a boolean value(false). Everything else is an empty string if not set on the tag.

You can define an observed attribute default value by simply setting a value to its property name.

class MyButton extends WebComponent {
	static observedAttributes = [
		'label',
		'type'
	];
	type = 'button';
	
	get template() {
		return '<button type="{type}">{label}</button>';
	}
}

Auto parsing

The WebComponent will automatically try to parse your attribute string into proper data type.

<flat-list list="[2, 4, 6]"></flat-list>
class FlatList extends WebComponent {
	static observedAttributes = ['list'];

	onMount() {
		console.log(this.list); // will be an Array [2, 4, 6]
	}
}
Note: These strings must be valid JSON strings.

If you use curly brace to bind a specific data, CWCO will reference that data from the component that passed it down.

Custom Boolean Attributes

If you use native boolean attributes like disabled and checked you don't to set values.

<my-button disabled></my-button>
<radio-button checked></radio-button>

They are the only ones which values are correctly assumed to be of type boolean. If you create a custom attribute and want it to be boolean you must give them boolean values and set the default inside the class.

class StatusIndicator extends WebComponent {
	static observedAttributes = [
		'error',
		'success',
		'warning',
		'info'
	];
	error = false;
	success = false;
	warning = false;
	info = true;
}
<status-indicator error="true"></status-indicator>
<status-indicator success="true"></status-indicator>
<status-indicator warning="true"></status-indicator>
<status-indicator></status-indicator>

Attributes vs Properties

Attributes end up working just like properties because they are changed to be properties. On top of that, they have the advantage of triggering changes when they are set or changed on the HTML tag.

You should prefer attributes whenever you are expecting data to be set directly on the tag.

WebComponent allows you to receive simple to complex data via attributes.

<flat-list list="[2, 4, 6, 90]"></flat-list>

// when inside another component template you can refer to the property
// using the curly braces
<flat-list list="{items}"></flat-list>

This is a feature you cannot find natively in web components API and that is strongly recommended as best practice which CWCO automatically support and handle for you.