Office UI FabricのSpinnerとOverlay(モーダル表示UI)

今日はOffice UI Fabric(以下"OfficeUI")の[Spinner](http://dev.office.com/fabric/components/spinner)と[Overlay](http://dev.office.com/fabric/components/overlay)について解説します。

[Spinner](http://dev.office.com/fabric/components/spinner)はくるくる回る表示を行うだけのもので、時間のかかる処理を実行中であることをユーザに知らせるためのUIです。[Overlay](http://dev.office.com/fabric/components/overlay)は他のUIを操作させないように画面(というかUI)をロックするためのものです。時間のかかる処理はSpinnerで表示しつつ、ユーザが何か操作するのを防止しておきたい場合に、この2つを組み合わせるのが定石ですね。

上記のような動作を想定したサンプルプログラムを作成してみました。表示は以下のようになります。OverlayでUIをロックしつつSpinnerを表示しています。「Cencel」ボタンで処理を中断できるようにするため、Spinnerはダイアログボックスの上に表示しています。ダイアログボックスについては[10日目の記事](http://qiita.com/furandon_pig/items/7543e483f20be7619369)をご参照ください。

![img601.png](https://qiita-image-store.s3.amazonaws.com/0/61137/c4441dfe-f973-d070-97c5-d498efbf731f.png)

サンプルソースコードは以下になります。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Spinner Sample</title>
    <link rel="stylesheet" href="//appsforoffice.microsoft.com/fabric/1.0/fabric.min.css">
    <link rel="stylesheet" href="//appsforoffice.microsoft.com/fabric/1.0/fabric.components.min.css">
    <link rel="stylesheet" href="//dev.office.com/Modules/DevOffice.Fabric/Fabric/components/Spinner/Spinner.css">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//dev.office.com/Modules/DevOffice.Fabric/Fabric/components/Spinner/Spinner.js"></script>
    <script>
      $(document).ready(function() {
        if ($.fn.Spinner) {
          $('.ms-Spinner').Spinner();
        }
        // Vanilla JS Components
        if (typeof fabric !== "") {
          if ('Spinner' in fabric) {
            var element = document.querySelector('.ms-Spinner');
            var component = new fabric['Spinner'](element);
          }
        }
      });
    </script>
  </head>
  <body>
    <div class="ms-Grid-col ms-u-sm6 ms-u-md8 ms-u-lg12">
      <button class="ms-Button ms-Button--primary" onclick="APP.openDialog()">
        <span class="ms-Button-label">Spinner表示<span>
      </button>
    </div>
    <div class="ms-Dialog" id="dialog1" style="visibility:hidden;"> <!-- ダイアログボックス -->
      <div class="ms-Overlay ms-Overlay ms-Overlay--dark"></div>
        <div class="ms-Dialog-main">
          <div class="ms-Dialog-header">
            <p class="ms-Dialog-title">Spinnerサンプル</p>
          </div>
          <div class="ms-Dialog-inner">
            <div class="ms-Dialog-content">
              <div align="center">
                <div class="ms-Spinner"></div>
              </div>
            </div>
            <div class="ms-Dialog-actions">
              <div class="ms-Dialog-actionsRight">
                <button class="ms-Dialog-action ms-Button ms-Button--primary" onclick="APP.closeDialog()">
                  <span class="ms-Button-label">Cancel</span>
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <script>
      APP = (function() {
        var isDialogShow = false;
        toggleShowState = function() {
          isDialogShow = !isDialogShow;
        };
        openDialog = function() {
          if (isDialogShow == false) {
            $('#dialog1').css('visibility', 'visible');
          } else {
            $('#dialog1').css('visibility', 'hidden');
          }
          toggleShowState();
        };
        closeDialog = function() {
          $('#dialog1').css('visibility', 'hidden');
          toggleShowState();
        };
        return {
          'toggleShowState': toggleShowState,
          'openDialog'   : openDialog,
          'closeDialog'  : closeDialog,
        };
      })();
    </script>
  </body>
</html>
```

## Spinnerを使用する

HTML上でのSpinnerは以下のようにCSSを読み込みんでから、DIV要素で指定します。

```html
<link rel="stylesheet" href="//dev.office.com/Modules/DevOffice.Fabric/Fabric/components/Spinner/Spinner.css">
...
<div class="ms-Spinner"></div>
```

ただし、[ドロップダウンリスト](http://qiita.com/furandon_pig/items/8b543a1df5df2ef15974)や[パネル](http://qiita.com/furandon_pig/items/f49f5f004c56af5975eb)の場合と同じく、以下のような処理でページ読み込み時にSpinnerを初期化する必要があります。

```js
      $(document).ready(function() {
        if ($.fn.Spinner) {
          $('.ms-Spinner').Spinner();
        }
        // Vanilla JS Components
        if (typeof fabric !== "") {
          if ('Spinner' in fabric) {
            var element = document.querySelector('.ms-Spinner');
            var component = new fabric['Spinner'](element);
          }
        }
      });
```

そして、Spinner()の定義は以下のJavaScript内で定義されています。今回はこちらで独自に手を入れる必要がなかったので[MSのSpinnerサンプル](http://dev.office.com/fabric/components/spinner)で使用しているJavaScriptをそのまま利用(直リン……)しています。

```html
<script src="//dev.office.com/Modules/DevOffice.Fabric/Fabric/components/Spinner/Spinner.js"></script>
```

## Overlayを使用する

[Overlay](http://dev.office.com/fabric/components/overlay)は以下の1行で指定します。

```html
<div class="ms-Overlay ms-Overlay"></div>
```

上記のOverlay指定では、画面に白いもやがかかったような感じのモーダル表示になります。画面を暗くするような感じでモーダル感を強調したい場合は、以下のように「ms-Overlay--dark」クラスを追加指定します(サンプルプログラムではこちらを使用しています)。

```html
<div class="ms-Overlay ms-Overlay ms-Overlay--dark"></div>
```

## まとめ

今回はSpinnerとOverlayの解説を行いました。両方ともHTMLを1行指定するだけで良さそうだったので、サクッと記事を書き終えられそうと思っていたのですが、SpinnerにはJavaScript側で初期化が必要というワナにハマってしまいました。各UI毎にページ読み込み時点での初期化が必要・不要なものがあるようなので、後々Advent Calendarで解説できればと思います。

## 参考URL

 * [Spinner](http://dev.office.com/fabric/components/spinner)
 * [Overlay](http://dev.office.com/fabric/components/overlay)