Click here for English version

このcodelabでは、LitElementを使ったカスタムエレメントの作り方について学べます。ボタンをトグルする簡単なLitElementエレメントを作ります。完成イメージは以下のような感じになります。

これは以下のような簡単なマークアップで利用可能になります。

<icon-toggle></icon-toggle>

このcodelabでは、LitElementを使って作業するための重要なコンセプトについても紹介していきます。

もし全てのコンセプトについて理解できなくても心配しないでください。それらの内容はLitElementの公式ドキュメントにより詳しく書かれています。

チュートリアルを始める前に、以下のソフトウェアがあることを確認してください:

以下の項目について、基本的なスキルや知識が必要になります:

Gitのインストール

Gitはバージョン管理ツールです

Gitインストーラーをダウンロードする

  1. Gitインストーラーをダウンロードして実行してください
  2. 次のコマンドを実行して Git のバージョンを確認してください: git --version

インストールが成功していれば、Gitのバージョンが表示されるはずです。

もしGitのバージョン番号がgit version 2.19.1のように表示されない場合は、次のリンクを参照してみることをおススメします。公式ドキュメント - Gitのインストール.

Node と npm のインストール

NodeはJavaScriptの実行環境です。npmはNodeのパッケージ管理ツールです。これらはNodeをインストールすると両方ともインストールされます。

Nodeインストーラーをダウンロードする

  1. Nodeインストーラーをダウンロードして実行してください(npmもインストールされるはずです)
  2. npmを最新版に更新してください: npm install npm@latest -g
  3. 次のコマンドを実行してnodeとnpmのインストールが成功したかを確認してください:

現時点で node -vv10.14.2 でした

現時点で npm -v6.4.1 でした

バージョン番号が表示されなかったら 公式ドキュメントのインストールガイドを参照してください

チュートリアルをインストールする

次のコマンドでリポジトリをクローンしてください。

git clone https://github.com/Polymer-Japan/litelement-first-element.git

依存するパッケージのインストール

ディレトリをクローン先に移動してから、npmコマンドで依存するパッケージをインストールします。

cd litelement-first-elements
npm install

インターネット回線が遅いと、とても時間がかかる場合があります....

インストールが終了すると、以下のようなディレクトリ構造になります。

作業する主なファイルはicon-toggle.jsです。このファイルにはカスタムエレメントの定義が入っています。

デモを実行する

デモの実行方法はとても簡単です。まだアプリは何も実装していませんが、以下のコマンドを実行してみましょう。

npm start

すると、Polymerの開発サーバーが動いて、デモがブラウザ(chrome)の新しいタブで開きます。アイコントグルは表示されず、テキストだけが表示されるはずです。どうってことないかもしれませんが、これで全てがうまく動いていることが確認できます。

次に、画面にアイコンを表示するための簡単なエレメントを作ってみましょう。

このステップでは、以下のようなことを学習できます。

icon-toggle.js を編集する

エディタでicon-toggle.jsファイルを開いてください。このファイルにはカスタムエレメントのスケルトンが入っています。

既存コードを見ながら進めましょう。

ES6 Module importsの書き方

import { LitElement, html } from '@polymer/lit-element';
import '@polymer/iron-icons/iron-icons.js';
import '@polymer/iron-icon/iron-icon.js';
        

キーポイント:

次はエレメント自体を定義していきます。

Shadow DOM テンプレートの書き方



class IconToggle extends LitElement {
  render() {
    return html`
      <style>
        /* local DOM styles go here */
        :host {
          display: inline-block;
        }
      </style>
      <!-- local DOM goes here -->
      <span>Not much here yet.</span>
    `;
  }
}

        

キーポイント:

エレメントの登録方法


window.customElements.define('icon-toggle', IconToggle);
        

キーポイント:

Shadow DOM構造を作る

エレメントの基本構造にふれたところで、Shadow DOMテンプレートを編集してみましょう。

local DOM goes hereというコメントの後に書いてある<span>タグを見つけてください。

icon-toggle.js—修正前

    <!-- local DOM goes here -->
    <span>Not much here yet.</span>
  `;

<span>タグを、以下のように<iron-icon>に置き換えてみてください。

icon-toggle.js—修正後

    <!-- local DOM goes here -->
    <iron-icon icon="polymer">
    </iron-icon>
  `;

キーポイント:

Shadow DOMにスタイルを付ける

Shadow DOMで利用できる新しいCSSセレクターがいくつかあります。icon-toggle.jsファイルの:hostセレクターはすでに紹介しました。これは<icon-toggle> エレメントそのもののスタイルを指定します。

<iron-icon>エレメントのスタイルを指定するために、<style>タグ内のCSSを以下の内容に書き換えてください:

icon-toggle.js

    <style>
      /* local styles go here */
      :host {
        display: inline-block;
      }
      iron-icon {
        fill: rgba(0,0,0,0);
        stroke: currentcolor;
      }
      :host([pressed]) iron-icon {
        fill: currentcolor;
      }
    </style>

キーポイント:

これまでの修正で、カスタムエレメント定義は以下のようになっていると思います。

icon-toggle.js


import { LitElement, html } from '@polymer/lit-element';
import '@polymer/iron-icons/iron-icons.js';
import '@polymer/iron-icon/iron-icon.js';

/**
 * `icon-toggle`
 * Get started creating custom elements with LitElement
 *
 * @customElement
 * @demo demo/index.html
 */
class IconToggle extends LitElement {
  render() {
    return html`
      <style>
        /* local styles go here */
        :host {
          display: inline-block;
        }
        iron-icon {
          fill: rgba(0,0,0,0);
          stroke: currentcolor;
        }
        :host([pressed]) iron-icon {
          fill: currentcolor;
        }
      </style>
      <!-- local DOM goes here -->
      <iron-icon icon="polymer">
      </iron-icon>
    `;
  }
}

window.customElements.define('icon-toggle', IconToggle);

デモページの初期値を設定する

ホスト要素の値に応じてメッセージを表示するようにするため、constructorを追加してisFav属性の初期値を設定するように編集してください。

icon-toggle-demo.js

class IconToggleDemo extends LitElement {
  constructor() {
    super();
    this.isFav = false;
  }
        

デモページをリロードしてください。ハードコーディングしたアイコン表示のトグルボタンが表示されるはずです。

1つのトグルだけが押されたようなスタイルになっています。そのタグにはpressed属性が設定されているためです。しかし、トグルボタンをクリックしても、まだトグルは動きません。pressedプロパティを変更するコードがまだないためです。

今のところエレメントは、変化しません。このステップでは、アイコンをマークアップ上から指定するための属性の使い方と、JavaScriptからプロパティを使う方法について、基本的なAPIを紹介します。

まず、データバインディングから始めましょう。 <iron-icon>エレメントを探して、icon属性の値を"polymer"から"${this.icon}"に変更してみましょう。

icon-toggle.js

<!-- local DOM goes here -->
<iron-icon icon="${this.icon}">
</iron-icon>

キーポイント:

以下の例のように、エレメントのマークアップで記述するか、JavaScriptを使用してiconプロパティの値を設定できます(このコードをプロジェクトに追加する必要はありません)

例—マークアップを使ってアイコンを指定する

<icon-toggle icon="favorite"></icon-toggle>

例—JavaScriptからアイコンを指定する

var myToggle = document.querySelector('icon-toggle');
myToggle.icon = "favorite";

続いて、iconプロパティの宣言を追加します。

次のようなstatic get properties関数をIconToggleクラスに追加してください:

icon-toggle.js

class IconToggle extends LitElement {
  static get properties() {
    return {
      icon: String,
    };
  }

キーポイント:

propertiesオブジェクトは、さらにいくつかの機能をサポートしています。pressedプロパティを利用できるようにするため、以下のように変更します。

icon-toggle.js


  constructor() {
    super();
    this.pressed = false;
  }
  static get properties() {
    return {
      icon: String,
      pressed: {
        type: Boolean,
        reflect: true
      }
    };
  }

キーポイント:

この修正でエレメントの pressedicon プロパティが動くようになりました。

デモページをリロードすると、前のステップまでハードコーディングされていたアイコンが、星とハートのアイコンに変わって表示されているはずです。

星とハートがどこで指定されたのか興味があれば、demo/icon-toggle-demo.jsを見てください。以下のように記述されています。

<icon-toggle icon="star"></icon-toggle>
<icon-toggle icon="star" pressed></icon-toggle>

もちろん、クリックできないボタンはボタンではありません。ボタンをトグルするには、イベントリスナーを追加します。iron-iconエレメントにイベントリスナーを追加するには、以下のように@clickプロパティを要素に追加します。

icon-toggle.js

<iron-icon icon="${this.icon}" @click="${this.toggle}">

キーポイント:

イベントリスナーが呼び出すハンドラーを追加します。

icon-toggle.js

  toggle() {
    this.pressed = !this.pressed;
  }
  attributeChangedCallback(name, oldval, newval) {
    super.attributeChangedCallback(name, oldval, newval);
    if(name === 'pressed') this.dispatchEvent(new CustomEvent('pressed-changed', { detail: this.pressed }));
  }
        

キーポイント:

icon-toggle.jsファイルを保存し、デモをリロードします。ボタンを押すと、押した状態と押していない状態を切り替えることができるはずです。

これまで、ベーシックな機能のボタンを作りました。しかし、押された状態と押されていない状態の両方ともに、標準テキストカラーを使用しています。ちょっと派手にしたいと思ったら、どうしたら良いでしょう?

Shadow DOMは、ユーザーが意図せずにエレメントの内部にスタイルを適用するのを防ぎます(同時に外部からスタイルを指定できなくなります)。こうしたときのために、カスタムプロパティを使うと、エレメント内のスタイルをユーザーが設定できるように特定のプロパティセットを提供できます。

var関数を使って、エレメント内部にカスタムプロパティを適用します。

background-color: var(--my-custom-property, defaultValue);

--my-custom-propertyはカスタムプロパティ名で、常に2つのダッシュ(--)で始まり、defaultValueはカスタムプロパティが設定されていない場合に使用される(オプションの)CSS値です。

エレメントの<style>タグを編集し、現在のfillstrokeの値をカスタムプロパティに変更します。

icon-toggle.js

  <style>
    /* local styles go here */
    :host {
      display: inline-block;
    }
    iron-icon {
      fill: var(--icon-toggle-color, rgba(0,0,0,0));
      stroke: var(--icon-toggle-outline-color, currentcolor);
    }
    :host([pressed]) iron-icon {
      fill: var(--icon-toggle-pressed-color, currentcolor);
    }
  </style>

SVGのデフォルト値として、colorを設定するだけで<icon-toggle>のスタイルを変更することもできますが、他のオプションを使ってみます。 demo/icon-toggle-demo.jsを開き、以下のようにカスタムプロパティを設定します

icon-toggle-demo.js

    <style>
      :host {
        font-family: sans-serif;
        --icon-toggle-color: lightgrey;
        --icon-toggle-outline-color: black;
        --icon-toggle-pressed-color: red;
      };
    </style>

デモページをリロードするとカラフルになっているはずです。

これでチュートリアルは終わりです。基本的なUIやAPIとカスタムスタイリングプロパティを持つ要素を作成しました。

もし作業に問題があったときは、完成版のコードを参照してください。