kintoneカスタマイズのアイコン置き場に困ったら

この記事は[kintone Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kintone)の10日目の記事です🎅

こんにちは、キンタンラボ本橋です。

今年の後半はkintoneプラグインばかり何本も作っていた気がします。となると不採用になったアイデアもあり、供養していきたいと思います。

# メニューアイコンをoffcanvasに押し込んだ

プラグインの追加で増加の一途をたどる『レコード一覧のメニューの右側の空白部分の要素』に並べた機能呼び出しアイコンを、bootstrapのoffcanvasに積み上げてしまおう、という実装です。

![GIFアニメ開いたり閉じたり](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/615254c2-dbb3-6e81-9b25-0cc3d76322bb.gif)

公式には『レコード一覧のメニューの右側の空白部分の要素』と呼ばれているこちらのスペースですが、ここではAPI準拠で『ヘッダーメニュースペース』と呼んでいきたいと思います。

それと記事の後半で、kintoneに合わせたhtmlボタンのスタイルについても補足しました。

よろしければオチまでお付き合いください。

## 公開コード

ここで紹介した機能はシンプルなJSカスタマイズに適用してgithubに公開しています。あわせてこちらもご覧ください。

https://github.com/motohasystem/headermenu100/

:::note info
メニューキャンバスのデモ用ブランチ
https://github.com/motohasystem/headermenu100/tree/menucanvas
:::

:::note info
MenuCanvas本体のコード(TypeScript)
https://github.com/motohasystem/headermenu100/blob/menucanvas/src/ts/menu_canvas.ts
:::

## 課題

お客さんからのご依頼でプラグインを作るとき、

>😺『メニューのあたりにアイコンを置いてそこから呼び出せるようにして』

という要望によく出くわします。

そんなときJSカスタマイズやプラグインでは、だいたい **kintone.app.getHeaderMenuSpaceElement()** を呼び出してヘッダーメニュースペースを取得し、そこにメニューやアイコンを配置することになるかと思います。

```
const headerSpace = kintone.app.getHeaderMenuSpaceElement()
```

### 呼び出しボタンの配置場所

ヘッダーメニュースペースは kintone に機能拡張するときのアイコン置き場として便利なので、これ幸いと追加していくといつの間にか溢れかえっていたりしますね。

ひとまず溢れかえらせてみます。アイコンを50個配置しました。

![アイコンを50個追加した状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/ce3013a6-8354-8601-0aea-df04b7db4853.png)

こうなるとあとから追加したメニューアイコンが行方不明になったり、行方不明を避けようと prepend すると今度は別のプラグインのアイコンがお隠れになります。

せっかくなのでもっと追加してみます。4倍の200個のアイコンで溢れかえらせました。

![アイコンを200個追加した状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/fa222bad-275b-88d2-6586-efd8d5d1b94b.png)

一覧のヘッダーを通り越して下からハミ出しました。ヘェー、ですね。

200個のアイコンが暴れるケースも少ないと思いますが、メニューアイコンが一覧に隠れてしまう事態はありがちです。

### 社外のエンジニアと客の会話

> 😿『アイコンが隠れてしまうの、どうにかなりませんか？』
> 
> 🤔『最初から隠しておきますか』

冗談まじりに言ったらウケたので作ってみたものが今回の供養対象（不採用）です。

![GIFアニメ開いたり閉じたり](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/eb02eae3-07ce-c6ee-a4d3-8fa1076316ab.gif)

引き出しみたいですね。bootstrap の offcanvas という機能を使っています。

提案当時、iPhone14向けのDynamic Islandが話題になっていたことに乗っかってダイナアイランと呼ぼうとしたけど気恥ずかしくなりストレートに**メニューキャンバス**にしました。

出オチ感極まるうえに不採用でしたが実用性もそこまで悪くないと思うのでここで供養させてください。

![アイコンを200個追加したメニューキャンバス](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/b2b6279e-03c3-b8c7-6e0e-6502901796d4.png)

次はメニューキャンバスの適用方法です。

## プロジェクトにメニューキャンバスを適用する手順

 1. menu_canvas.tsをプロジェクトに追加する
 2. メインロジックでnewする
 3. HTMLElementをappendする

の3ステップです。

まず、お使いのTypeScriptプロジェクトにこちらの
 menu_canvas.ts を追加します。

https://github.com/motohasystem/headermenu100/blob/menucanvas/src/ts/menu_canvas.ts

次に、メインロジックから引数のIDを渡してnewします。

```javascript
const menu_canvas_id = 'sample_menu_canvas'
const plugin_canvas = new MenuCanvas(menu_canvas_id)
```

別々のプラグインからの利用であっても、このIDが共通していれば同じキャンバスにアイコンを相乗りさせられます。（そういう用途で作りました）


最後に、ヘッダーメニュースペースの場合と同じようにHTMLElementを append してあげてください。

```javascript
const node_item = new HTMLElement()
plugin_canvas.append(node_item)
```

吹き出しアイコンがヘッダーメニュースペースに出現していれば適用できています。

![吹き出しアイコン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/ce366c4d-dc7b-cdc5-fef3-77ee517b9d40.png)

## 動作確認

追加された吹き出しアイコンをクリックするとメニューキャンバスがスルスル出てきます。

![GIFアニメ開いたり閉じたりアイコン100個版](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/7c0817bd-c11c-c765-c4f7-1e6cb070e0ec.gif)

うまく動作しない場合はbootstrapが動作していない可能性があるので、サンプルコードを参考に確認してみてください。僕も style.scss あたりでよくつまづきました。

https://github.com/motohasystem/headermenu100/tree/menucanvas

# 余談1

余談ですが、githubにあげている[サンプルコード](https://github.com/motohasystem/headermenu100/blob/menucanvas/src/ts/main_customize.ts)では、FontAwesome のアイコンをランダムで生成して追加しています。

```javascript
// メニューキャンバスにアイコン100個追加
const generator = new ItemGenerator()
for (let i = 0; i < CONSTANTS.REPEAT; i++) {
    plugin_canvas.append(generator.get())
}
```

kintoneカスタマイズのお供に FontAwesome 良いですね。

# 余談2

余談ですが、kintone のヘッダーメニュースペースにアイコンを並べるときは以下のスタイルをあてると標準の絞り込みアイコンやグラフアイコンの雰囲気に寄せることができます。

```javascript
const icon = document.createElement('button');

icon.style.width = '48px'
icon.style.height = '48px'
icon.style.backgroundColor = '#f7f9fa'
icon.style.fontSize = '28px'
icon.style.border = '1px solid #e3e7e8'
icon.style.display = 'inline'
```

FontAwesome のアイコンがとても良く馴染みます。


# 余談というより本質

![アイコンを200個追加した状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/0125795b-e1bc-d878-7cf9-fc049975ecf7.png)

余談というより本質なんですが、多くの場合 HeaderMenuSpace のスタイルに height = 'auto' を指定すると自動で高さが広がり多少のアイコン数であれば問題なく表示できます。

```
kintone.app.getHeaderMenuSpaceElement().style.height = 'auto'
```

ブラウザで開発者ツールを開いて、コンソールにこの１行を入力することで一時的に広げられます。お試しください。

![heightにautoを指定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/371fc6f9-1b13-f4ac-cd29-656d9eb57784.png)

対応としてもスクリプトに一行足すだけなのでこの方が楽ちんです。

お困りの際はoffcanvasとか使ってないで HeaderMenuSpaceの height に auto を指定して済ませてください。

ありがとうございました。