Skip to content

Instantly share code, notes, and snippets.

@luvuong-le
Created November 16, 2018 05:42
Show Gist options
  • Save luvuong-le/ddff1121a3ee288765092a4bc99c1dda to your computer and use it in GitHub Desktop.
Save luvuong-le/ddff1121a3ee288765092a4bc99c1dda to your computer and use it in GitHub Desktop.
Module Web Components #1 - With DI
/* Web Component Register Function */
import { Register } from './webcomponents.js';
/* Import Components */
import Example from './Example.js';
// Register Components (Tag name must include a dash)
Register('example-tag', Example);
/* Pass Through Dependencies */
export default ({ html, props}) => {
/* Returns new Component (HTML Element) with access to dependency functions */
return class Example extends HTMLElement {
/* When the component is displayed */
connectedCallback() {
console.log('Props', this.props);
}
/* Define attributes to watch */
static get observedAttributes() {
return ['number']
}
/* Runs when an attribute is updated */
attributeChangedCallback(name, oldVal, newVal) {
console.log(`${name} prop changed | old: ${oldVal} | new: ${newVal}`);
}
constructor() {
super();
this.render(this.template);
}
get props() {
return props(this.attributes);
}
get template() {
return html('template', 'nav', `
<style>
/* :host refers to the component itself */
:host {
width: 100%;
}
.container {
text-align: center;
padding: 1rem;
}
</style>
<div class="container">
<h1>Example Title</h1>
<slot />
</div>
`);
}
/* Render the shadowDOM with the template */
render() {
return this
.attachShadow({ mode: 'open' })
.appendChild(this.template.content.cloneNode(true));
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Example Web Components</title>
</head>
<body>
<example-tag number="1">
Text From User
</example-tag>
<script src="./app.js"></script>
</body>
</html>
export const html = (id, classes, content) => {
let template = document.createElement('template');
template.id = id;
template.classList = classes;
template.innerHTML = `${content}`
return template;
}
export const props = (attributes) => {
const props = {};
for (const prop of attributes) {
props[prop.name] = prop;
}
return props;
}
export const Register = (tag, component) => {
customElements.define(tag, component({ html, props }));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment