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
orclassList
; - 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.