【Handsontable】シンプルデザインの実現

# はじめに
Handsontable で普通に作成すると、Excel風のデザインになってしまいます。
Boostrap や Material Design のテーブルコンポーネントは、シンプルなデザインです。

https://getbootstrap.jp/docs/5.0/content/tables/

入力部分は、Handsontable を使用して、一覧表示はテーブルコンポーネントを使用するように分けて作成してもいいでのですが、一覧表示であっても Handsontable のまま使用したいじゃないですか。

# 環境
HandsontableはMITライセンス版のバージョン 6.2.2を使用しています。

## CDN
```html
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/handsontable/6.2.2/handsontable.full.css">

<script src="https://cdnjs.cloudflare.com/ajax/libs/handsontable/6.2.2/handsontable.full.min.js"></script>
```

# 実装
<p class="codepen" data-height="600" data-default-tab="result" data-slug-hash="LYXpewb" data-user="yaju-the-encoder" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yaju-the-encoder/pen/LYXpewb">
  Handsontable Simple Design</a> by やじゅ (<a href="https://codepen.io/yaju-the-encoder">@yaju-the-encoder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# ソースコード
```html
<!DOCTYPE html>
<html lang="jp">
<body>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/handsontable/6.2.2/handsontable.full.css">
<style>
/* 行ヘッダー部 背景色なし、下線のみ表示 */
#grid .handsontable th {
  background-color : transparent;
  border-left-style : none !important;
  border-right-style : none !important;
  border-top-style : none !important;
  font-weight : bold;
  text-align: left;
  font-size: 16px;
}

/* データ部 背景色なし、下線のみ表示 */
#grid .handsontable td {
  background-color:transparent;
  border-left-style : none !important;
  border-right-style : none !important;
  border-top-style : none !important;
  text-align: left;
  padding: 4px 0px 4px 10px;
  font-size: 16px;
}

/* 列ヘッダー部 下線のみ表示 */
#grid .handsontable thead th .relative  {
  border-bottom-style : solid;
  border-bottom-width : thin;
}

/* 列ヘッダー部 文字位置調整 */
#grid .handsontable .relative {
  padding-top :  4px;
  padding-left : 8px;
}

/* 行ヘッダー部 文字位置調整 */
#grid .handsontable span.colHeader {
  padding-left  : 2px;
}

/* コーナー部 文字表示 */
#grid .handsontable .cornerHeader::before {
  content : '#';
  font-weight : bold;
  padding-left  : 2px;
}

/* 選択行 色変更 */
#grid .handsontable .currentRow  {
   background: rgb(230, 239, 254) !important;
}

/* 行ヘッダー部 選択時ハイライトなし */
#grid .handsontable thead th.ht__highlight {
   background-color: transparent;
}

/* 交互背景色(偶数) */
#grid .htCore tbody tr:nth-child(even) th,
#grid .htCore tbody tr:nth-child(even) td {
  background-color: whitesmoke;
}

/* 交互背景色(奇数) */
#grid .htCore tbody tr:nth-child(odd) th,
#grid .htCore tbody tr:nth-child(odd) td {
  background-color: transparent;
}

/* マウスホバー色 */
#grid .htCore tbody tr:hover th,
#grid .htCore tbody tr:hover td {
  background-color: lemonchiffon !important;
}

/* 読取り専用色 */
#grid.handsontable .htDimmed {
    color: black;
}
</style>
<head>
<body onload="createGrid()">
<div id="grid"></div>
<script src="https://cdn.jsdelivr.net/npm/handsontable@6.2.2/dist/handsontable.full.min.js"></script>
<script>
function createGrid() {
    let data = [
        ['Beverages', 'Soft drinks, coffees, teas, beers, and ales'],
        ['Condiments', 'Sweet and savory sauces, relishes, spreads, and seasonings'],
        ['Confections', 'Desserts, candies, and sweet breads'],
        ['Dairy Products', 'Cheeses']
    ];

    let grid = document.getElementById('grid');
    let hot = new Handsontable(grid, {
        data: data,
        colHeaders: ['分類名', '説明'],
        columns: [
            { type: 'text' , width: 200 },
            { type: 'text' , width: 650 }
        ],
        readOnly: true,
        currentRowClassName: 'currentRow',
        rowHeaders: true,
        manualColumnResize: true,
        fillHandle: false,
        fixedColumnsLeft: 2
    });
}
</script>
</html>
```

# ポイント
CSSを駆使しています。

CSSにDIVタグのIDである `#grid` を付けることで、他の Hansontable には影響しないようにしています。

## テーブル行ホバー
マウスカーソルが乗っているときに行の背景色を変えています。
ただし、行ヘッダーである先頭列の背景色は変わりません。

行ヘッダーは、`rowHeaders`オプションで実現しているのですが、タグ的には`th`タグになります。
テーブル行ホバーは、`td`タグにしているので連動しないのです。
この部分がどうしても気になる方は、`rowHeaders : false` として、行ヘッダーの番号自体もデータとして扱えば実現出来ます。

### 行ヘッダーの変更も実現 
【2023/06/18追記】
何とかCSS等で行ヘッダーまで変更出来ないかと模索していました、普通のテーブルダグであれば、`tr:hover`だけで行ヘッダー部分まで背景色が変更されるんですが、Handsontableだと行ヘッダー(`th`)のみ、データ(`td`)のみと分かれてしまう。
下記HandsontableのQ＆Aサイトの nvrcght さんの jsfiddle で行ヘッダー部分まで背景色が変更されていることに気が付きました。

* https://forum.handsontable.com/t/highlight-row-with-frozen-columns/1070
* http://jsfiddle.net/55z02om4/2/

自分のと何が違うのか調査すると、固定行オプションの`fixedColumnsLeft`を指定していることでした。これに最大列数をセットすることで実現することが出来ました。

今回の例では最大列数は 2 となります。最大列数は`colHeaders`の配列数とか何かしらで取得してセットすればいいでしょう。

```js
fixedColumnsLeft: 2
```

列ヘッダーは、対象外にしています。

```css
/* マウスホバー色 */
#grid .htCore tbody tr:hover th,
#grid .htCore tbody tr:hover td {
  background-color: lemonchiffon !important;
}
```

# 最後に
現在、Blazor　を使用した Webアプリケーションを作成していて、 一覧表示をどうしようか悩んでいたんですよね。
これで見た目もシンプルデザインを実現できたので、 Hansontable で統一していこうと思います。

久しぶりに、CodePen を使いました。Twitterによるアカウントが出来なくなっていたので、Githubアカウントに変更した。