RiotGear入門その1

[Riot.js Advent Calendar 2019](https://qiita.com/advent-calendar/2019/riotjs) の20日目です。
元々RiotGearについて予約されていましたが、辞退されてしまったようなので僭越ながら代わりに投稿します。

## RiotGearとは

[RiotGear](https://riotgear.js.org/)とはRiot.jsのオープンソースコンポーネントライブラリです。
よく使うHTML部品をカスタムタグとして提供することで、簡単かつ汎用的に呼び出せるようになっています。

`npm i -S riotgear`でインストールできます。
直接使う場合は`<script src="https://cdn.jsdelivr.net/riotgear/latest/rg.min.js"></script>`

v4にはまだ対応しておらず、Riot v3.13.2サポートとなっています。
また、Blaze CSSというものを使っているそうですが、
証明書が怪しいので公式ページは見ていません。

後継版？のBlaze UIには対応していないようです。
https://www.blazeui.com/


今回Riot v4に対応しようかと思いましたが、ちょっと量が多いのでv3で使っていきます。
使うには以下の3セットが必要です。

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/blazecss/1.1.3/blaze.min.css">
<script src="https://cdn.jsdelivr.net/npm/riot@3.13.2/riot+compiler.js"></script>
<script src="https://cdn.jsdelivr.net/npm/riotgear@3.6.0/dist/rg.min.js"></script>
```

サンプルは公式ページにありますが、APIドキュメントは無さそうなので以下の説明ではソースから内容を判断して記載しています。

## アラート
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="KAJIKEN" data-slug-hash="ExaWdMV" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="ExaWdMV">
  <span>See the Pen <a href="https://codepen.io/KAJIKEN/pen/ExaWdMV">
  ExaWdMV</a> by KAJIKEN (<a href="https://codepen.io/KAJIKEN">@KAJIKEN</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

アラートメッセージを表示します。
`rg-alerts`をマウントすることで利用できます。
タグへのパラメータとして`alerts`配列を渡します。

```javascript:
{
  'alerts': [
    {
      'type': 'primary', // アラートの種類 primary / secondary / error の3種類
      'text': 'Look! Something you should know about.', // 表示するメッセージ
      'dismissable': false, // Xボタンを表示するかどうか 省略時:true
      'timeout': 10000, // 自動的に消すまでの時間(ms)
      'isvisible': true // 表示するかどうか 省略時:true
    }
  ]
}
```

### イベント
`select`: アラートを選択時(`onclick`)発行
`dismiss`: アラートをXで閉じた時(`onclick`)発行

## バブル
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="KAJIKEN" data-slug-hash="gObmQNJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="gObmQNJ">
  <span>See the Pen <a href="https://codepen.io/KAJIKEN/pen/gObmQNJ">
  gObmQNJ</a> by KAJIKEN (<a href="https://codepen.io/KAJIKEN">@KAJIKEN</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

マウスホバーすると指定した文字列をポップアップ表示します。
`rg-bubble`をマウントすることで利用できます。
タグへのパラメータとして`bubble`オブジェクトを渡します。

```javascript:
{
  'bubble': {
    'text': 'Bubbles go pop!' // 表示する文字列
  }
}
```

## チャート
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="KAJIKEN" data-slug-hash="OJPprPL" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="OJPprPL">
  <span>See the Pen <a href="https://codepen.io/KAJIKEN/pen/OJPprPL">
  OJPprPL</a> by KAJIKEN (<a href="https://codepen.io/KAJIKEN">@KAJIKEN</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

[Chart.js](https://www.chartjs.org/)を使ってグラフを表示します。そのためChart.jsの読み込みが別途必要。
`rg-chart`をマウントすることで利用できます。
タグへのパラメータとして`chart`オブジェクトを渡します。

```javascript:
{
  'chart': {
    'type': 'doughnut', // line|bar|radar|polar|pie|doughnut
    'options': {}, // Look at Chart.js documentation on how to populate data and options
    'data': [{
      'value': 300,
      'color': "#F7464A",
      'highlight': "#FF5A5E",
      'label': "Red"
    }, {
      'value': 50,
      'color': "#46BFBD",
      'highlight': "#5AD3D1",
      'label': "Green"
    }, {
      'value': 100,
      'color': "#FDB45C",
      'highlight': "#FFC870",
      'label': "Yellow"
    }]
  }
}
```

### イベント
`loaded`: チャートを表示した後(`mount`の最後)に発行

## コード
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="KAJIKEN" data-slug-hash="KKwWbMN" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="KKwWbMN">
  <span>See the Pen <a href="https://codepen.io/KAJIKEN/pen/KKwWbMN">
  KKwWbMN</a> by KAJIKEN (<a href="https://codepen.io/KAJIKEN">@KAJIKEN</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

公式ページには一切書いていないですが、[Ace](https://ace.c9.io/)を使ってコードをエディタで表示します。そのためace.jsの読み込みが別途必要。
`rg-code`をマウントすることで利用できます。
タグへのパラメータとして`editor`オブジェクトを渡します。
オプションは[Aceのドキュメント](https://ace.c9.io/#nav=howto)を参照

```javascript:
{
  'editor': {
    'code': '<h2>Hello World</h2>',
    'mode': 'html', // シンタックスハイライト
    'tabsize': 2,
    'softtabs': false,
    'wordwrap': false,
    'readonly': false
  }
}
```

## クレジットカード
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="KAJIKEN" data-slug-hash="LYEWMLM" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="LYEWMLM">
  <span>See the Pen <a href="https://codepen.io/KAJIKEN/pen/LYEWMLM">
  LYEWMLM</a> by KAJIKEN (<a href="https://codepen.io/KAJIKEN">@KAJIKEN</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

カードのアイコンを表示するには画像を用意する必要があります。
> img/amex.png
img/diners_club.png
img/discover.png
img/jcb.png
img/mastercard.png
img/visa.png

有効な番号の場合、カード会社が出て緑色の枠になります。
スペースやハイフンをいれても無視されます。

`rg-credit-card-number`をマウントすることで利用できます。
タグへのパラメータとして`card`オブジェクトを渡します。
公式ページのサンプルコードはcardオブジェクトを使っていなくてバグっているのでハマった…。

しかし、カード番号を入れるもので外部コンポーネントを使う気にはとてもならないので使うことは無いだろう。

```javascript:
{
  'card': {
    'placeholder': 'Long number on front',
    'cardnumber': '4000 0000 0000 0002'
  }
}
```

## 日付
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="KAJIKEN" data-slug-hash="NWPjOEY" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="NWPjOEY">
  <span>See the Pen <a href="https://codepen.io/KAJIKEN/pen/NWPjOEY">
  NWPjOEY</a> by KAJIKEN (<a href="https://codepen.io/KAJIKEN">@KAJIKEN</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

いわゆるDatepickerです。[Moment.js](https://momentjs.com/)が必要です。
`rg-date`をマウントすることで利用できます。
タグへのパラメータとして`date`オブジェクトを渡します。
これも公式ページのサンプルコードはdateオブジェクトを使っていなくてバグっている。
さらにサンプルはマウント時のタグ名指定`'rg-date'`も忘れている。

```javascript:
{
  'date': {
    'date' : moment(),   // 初期日付
    'min': '2019/12/01', // 選択可能最小日付
    'max': '2019/12/25'  // 選択可能最大日付
  }
}
```

## ドロワー
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="KAJIKEN" data-slug-hash="GRgmwaw" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="GRgmwaw">
  <span>See the Pen <a href="https://codepen.io/KAJIKEN/pen/GRgmwaw">
  GRgmwaw</a> by KAJIKEN (<a href="https://codepen.io/KAJIKEN">@KAJIKEN</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

ドロワーメニューです。
`rg-drawer`をマウントすることで利用できます。
タグへのパラメータとして`drawer`オブジェクトを渡します。

```javascript:
{
  drawer: {
    header: 'Drawer', // ヘッダー部
    isvisible: true,  // 初期表示
    position: 'top',  // 表示位置: top|right|bottom|left
    items: [{
      id: 1,
      text: 'Item 1'
    }, {
      id: 2,
      text: 'Item 2'
    }]
  }
}
```
### イベント
`select`: 項目を選択(`onclick`)した時に発行
`close`: 枠外の黒い背景を選択(`onclick`)した時に発行

## Google Analytics

Google Analyticsを設置します。
`rg-ga`をマウントすることで利用できます。
カスタムタグのパラメータとして`property`属性をセットします。
見た目に変化ないのでコードだけにします。

```html
<rg-ga property="UA-12345678-1"></rg-ga>
```
```javascript
riot.mount('rg-ga');
```

## iFramify

[iFramify](https://github.com/edenspiekermann/iframify)というライブラリを使ってレスポンシブ対応されたコンポーネントを表示する…らしい。
`rg-iframify`をマウントすることで利用できます。
タグへのパラメータとして`iframify`オブジェクトを渡します。
iframifyオブジェクトの中身はiFramifyのオプションと同じとのこと。

```html
<rg-iframify>
  <div class="component">
    This is a component. Under 200px, the border of this component will go pink.
  </div>
</rg-iframify>
```
```javascript
riot.mount('rg-iframify', {
  iframify: { /* iframify options */ }
});
```

## インクルード

外部ファイルを読み込んで表示する。
`rg-include`をマウントすることで利用できます。
タグへのパラメータとして`include`オブジェクトを渡します。

```html
<rg-include></rg-include>
```
```javascript
var tags = riot.mount('rg-include', {
  include: {
    url: 'demo_text.html', // 読み込むURL
    unsafe: true // trueの場合 カスタムタグごと取得結果で置き換える
  }
});
tags[0].on('loaded', function () {
  console.log("loaded");
});
```

### イベント
`loading`: HTTPリクエストを発行(`XMLHttpRequest#send`)した後に発行
`loaded`: HTTPリクエストの結果を読み込みんだ(`XMLHttpRequest#onload`)時に発行

## Google Maps

Google Mapsを読み込んで表示する。
`rg-map`をマウントすることで利用できます。
タグへのパラメータとして`map`オブジェクトを渡します。

```html
<rg-map></rg-map>
```
```javascript
var tags = riot.mount('rg-map', {
  map: {
    center: { lat: 37.7577, lng: -122.4376 },
    zoom: 8
  }
});

tags[0].on('loaded', function (map) {
  var marker = new google.maps.Marker({
    position: { lat: 37.7577, lng: -122.4376 },
    map: map,
    title: 'Hello RiotGear!'
  });
});
```

### イベント
`initialize`: 読み込み開始時(内部利用専用？)
`loaded`: Map読み込み完了時

## その1 まとめ

一度に全部やりたかったですが、思いのほか時間が掛かったのでここで一旦区切ります。
RiotGearの存在自体知らなかったですが、使ってみて思うのはサードパーティのライブラリに依存しすぎていることかな。
簡単に呼び出そうという発想は良いですが、サードパーティライブラリ単体でも呼び出しは簡単なオプションで呼べるので大して変わらない。
そしてドキュメントが不十分であるため、結局サードパーティライブラリの説明は読まなきゃ使えないので意味がない。
サードパーティライブラリを使わずに、よく使うようなHTMLテンプレートがコンポーネント化されてたら便利かな。
ハンバーガーメニューとか。依存するなら１つに絞った方がいい気がする。Bootstrapとか。