Installation
npm install @efflore/ui-element
Your First Component
JavaScript
import UIElement from '@efflore/ui-element';
customElements.define('show-appreciation', class extends UIElement {
static observedAttributes = ['count'];
attributeMapping = { count: 'integer' };
connectedCallback() {
this.querySelector('button').onclick = () => {
this.set('count', v => v + 1);
};
this.effect(() => {
this.querySelector('.count').textContent = this.get('count');
});
}
});
Important: When using multiple components, make sure you either bundle JavaScript on the server side or reference the same external module script for UIElement
from the client side!
Inter-component reactivity won't work if UIElement
is a different instance in multiple modules.
CSS
:root {
/* Define neccessary CSS custom properties */
}
show-appreciation {
display: inline-block;
button {
display: flex;
flex-direction: row;
gap: var(--space-s);
border: 1px solid var(--color-border);
border-radius: var(--space-xs);
background-color: var(--color-secondary);
color: var(--color-text);
padding: var(--space-xs) var(--space-s);
cursor: pointer;
font-size: var(--font-size-m);
line-height: var(--line-height-xs);
transition: transform var(--transition-short) var(--easing-inout);
&:hover {
background-color: var(--color-secondary-hover);
}
&:active {
background-color: var(--color-secondary-active);
.emoji {
transform: scale(1.1);
}
}
}
}
HTML
Combine markup, styles and scripts:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Web Compoment with UIElement</title>
<link href="index.css" rel="stylesheet">
<!-- more meta -->
</head>
<body>
<main>
<!-- main content -->
<show-appreciation count="42">
<button>
<span class="emoji">💖</span>
<span class="count">42</span>
</button>
</show-appreciation>
</main>
<script type="module" src="index.js"></script>
</body>
</html>
Result
Okay, this is a very simple "Hello World" example. But you can build complex applications with simple components like this one. To understand how to unleash the magic, we have to dive a bit deeper into the core concepts behind.
What's the Magic Behind?
If most of it looks like pretty normal HTML, CSS and JavaScript to you, you are absolutly right. Because it is!
You may have noticed a few things in JavaScript, which you normally don't see:
- a property
attributeMapping
in the class definition of your custom element - a method call
this.set()
in theclick
event handler of the button - a method call
this.effect()
in theconnectedCallback()
of your custom element - a method call
this.get()
in thethis.effect()
callback handler
These are what UIElement
adds on top of a regular custom element to extend HTMLElement
. The property tells UIElement
what to do with your observed attributes. The methods provide reactivity.