Custom Element Demo

by kevinbalicot

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.2.1/webcomponents-bundle.js"></script>
<script src="https://github.com/kevinbalicot/custom-element/releases/download/v1.1.0/custom-element.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.0/showdown.min.js"></script>
<nav-component>
  <span slot="title">Custom Element</span>
</nav-component>

<home-component></home-component>

JavaScript

class NavComponent extends CustomElement {
  static get template() {
    return `
        	<nav>
            <slot name="title">Generic app name</slot>
              <slot name="nav">
                	<ul>
                    	<li><a href="#/">Home</a></li>
                      <li><a href="#/demo">Demo</a></li>
                      <li><a href="#/about">About</a></li>
                  </ul>
              </slot>
        	</nav>
        `;
  }

  static get styles() {
    return [
      '::slotted([slot=title]) { display: block; text-align: center; }',
      'ul { padding: 0; margin: 0; }',
      'ul li { display: inline-block; }'
    ];
  }
}

class AboutComponent extends CustomElement {
  static get template() {
    return `
        	<h1>About</h1>
            <div>
            	<p>By <a href="https://github.com/kevinbalicot" target="_blank">Kevin Balicot</a></p>
                <p>Repository <a href="https://github.com/kevinbalicot/custom-element" target="_blank">Github</a></p>
            </div>
        `;
  }
}

class Http {
  get(url) {
    return fetch(url).then(result => result.text());
  }
}

class MarkdownDecoder {
  constructor() {
    this.converter = new showdown.Converter();
  }

  decode(markdown) {
    return this.converter.makeHtml(markdown);
  }
}

class ReadmeLoader extends Injectable {
  constructor(http, markdownDecoder) {
    super();

    this.http = http;
    this.decoder = markdownDecoder;
  }

  load(url) {
    return this.http.get(url).then(data => this.decoder.decode(data));
  }

  static get injects() {
    return [Http, MarkdownDecoder];
  }
}

class ReadmeComponent extends CustomElement {
  constructor() {
    super();

    this.url = 'https://raw.githubusercontent.com/kevinbalicot/custom-element/master/README.md';
    this.readmeLoader = this.get('ReadmeLoader');

    this.content = null;
  }

  onConnected() {
    this.readmeLoader.load(this.url).then(content => {
      this.update({ content });
    });
  }

  static get...