KEPPLE DB の Mantine v6 を Mantine v7 に更新しました

こんにちは! 株式会社ケップルの Product Development Section でエンジニア兼スクラムマスターをやっている芹田です。

2024年 8月、スタートアップデータベース「KEPPLE DB」で使用している UI コンポーネントライブラリ Mantine を、v6 から v7 に更新しました。

Mantine v6 と Mantine v7 の間で破壊的変更が多かったことと、Mantine の良さがもっと知られるべきという思いがあったため、今回記事を書くに至りました。

なぜ Mantine なのか

はじめに、KEPPLE DB 独立時になぜ Mantine v6 を採用したか説明します。

ヘッドレス UI ライブラリと旧来の UI ライブラリの比較

まず、デザインシステムを構築した上でヘッドレス UI ライブラリを採用するか、旧来の UI ライブラリを使用するか検討しました。結果、KEPPLE DB というプロダクトで提供したい「価値」に対してデザインシステムの構築は過剰であると判断し、旧来の UI ライブラリを使用する決断をしました。

Mantine と他の UI ライブラリの比較

次に、旧来の UI ライブラリの中で比較検討しました。Mantine の他に、Chakra UI、Fluent UI、MUI、Ant Design と比較した結果、カスタマイズの余地が大きいこと、プロダクトの性質に合う「程よくフォーマル程よくポップなトーン」であること、DatePicker や 検索機能が付いた MultiSelect などの比較的複雑なコンポーネントが揃っていることから、Mantine を選定しました。

Mantine v7 の変更点

Mantine v7 では、スタイルシステムが大きく変わりました。

emotion からの脱却と emotion の復活

Mantine v7 は 2023 年 9 月にリリースされました。Mantine v7 は、Next.js の App Router 登場以後の emotion 排除の潮流に乗って、emotion から脱却して CSS Modules がデフォルトになりました。

KEPPLE DB 独立の開発が半分以上完了していたタイミングだったこと、枯れるのを待ちたいという考えから、半年ほど Mantine v7 への移行を保留し、2024 年 3 月ごろから移行作業を開始しました。カイゼン活動日に CSS Modules で書き直していたのですが、5 月 2 日に @mantine/emotion というパッケージが追加され、最小限の労力で Mantine v7 への移行ができるようになりました。

移行が楽になった喜びと今までの作業が無駄になった悲しみの間で揺れながら、移行作業を進め、2024年8月に無事 Mantine v7 に移行できたという流れです。

Mantine のスタイルシステム

Mantine のスタイルシステムは柔軟ですが複雑です。

style prop と style props と styles prop が別物であるというのが、複数形と単数形の違いに鈍感な私にとって非常に難しく、また同じことができる選択肢が多いのも難しい点です。

表にしてみました。

  v6 v7 v7 with @mantine/emotion
インラインで特定のスタイルを記述 style props

<Box mx="auto" maw={400} c="blue.6" bg="#fff"> のようにスタイルを指定
emotion でスタイルが当たる
style props

style 属性に変換される
v6 時代と異なりあまり推奨されない
style props
スタイルを記述 createStyles CSS Modules 他、className prop にクラス名渡せるものなら何でも createStyles
コンポーネント特定要素スタイル記述 Styles API

クラス名を用いた API なので、createStyles, classNames prop, styles prop, static class name, theme, など様々な方法で使用できる
Styles API

クラス名を用いた API なので classNames prop, styles prop, static class name, theme, など様々な方法で使用できる。
また CSS 変数を style prop で指定してスタイル当てることできる
左記に加えて createStyles と sx prop を使用できるが、sx prop については挙動が不安定なので使うのはお勧めしない

複雑でないスタイルは style props を用い、複雑なスタイルは v6 であれば createStyles, v7 であれば CSS Modules を使用するのが基本かなと思います。

Mantine v7 移行で行ったこと

実際に移行でなにをやったのか、肝となる部分をピックアップしてご紹介します。

方針を立てる

まずは移行作業を始める前に小さく検証し、以下の方針を立てました。

  • Mantine v6 で使用していた emotion 依存のスタイルは、足元はそのままにする
  • スタイルが崩れているところ、新たにスタイルを当てるところは CSS Modules で書き直す
  • 動かなくなったコンポーネントを作り直す際は Mantine v7 の作法で作り直す
  • Mantine v7 移行後に少しずつ CSS Modules に置き換えていく
  • JavaScript から CSS に値を渡したいときは CSS の変数や data 属性を用いる

@mantine/emotion の導入

ドキュメント通りセットアップし、createStyles や sx prop の型などの import 元を @mantine/core から @mantine/emotion に変更しました。

一部を CSS Modules で書き直す

基本的には @mantine/emotion で問題ないのですが、スタイルが崩れているところ、正しく当たっていないところが3割くらいありました。エンジニア、デザイナーが協力してひたすら探し、リストアップしました。それらは CSS Modules で書き直しました。

今まで JavaScript から CSS に値を渡すときは createStyles に変数を渡していました。CSS Modules では、 style prop で CSS の変数を定義するか、data 属性を使います。style prop を使うことに迷いがあったのですが、ドキュメントに記載されている方法なので、使うことにしました。

動かなくなったコンポーネントの修正や作り直し

KEPPLE DB はスタートアップのデータベースサービスです。複雑な検索も可能なプロダクトなので、特殊なコンポーネントがたくさんあります。

  • 数百種類あるタグを検索条件に指定するための階層と検索機能がついた MultiSelect
  • 広い範囲の金額で検索するため金額によりステップが変わるスライダー
  • ショートカット機能がついた日付範囲入力コンポーネント
  • などなど……

これらの修正あるいは作り直しをしました。

Mantine v7 移行で困った点

Mantine v7 移行で困った点をいくつかご紹介します。

動作のあやしい @mantine/emotion

emotion が復活し、段階的な移行ができるようになったことは、とてつもなくありがたいことです。とはいえ、Mantine v7 で emotion 依存の機能は不完全なところが多く、最終的には剥がしたほうがよさそうです。

たとえば、sx prop と style props を組み合わせた場合に sx prop のスタイルが当たらない、props で別コンポーネントに createStyles で作成したクラス名を渡した際にスタイルが当たらない、レンダリングが終わった後にワンテンポ遅れてスタイルが当たることがあるといった事象を確認しています。

動作が怪しいFlexコンポーネント

Flex や Stack などの Flexコンポーネントで、style props と style prop を組み合わせた場合に style prop が効かない、style props と sx prop を組み合わせた場合に sx prop が効かない場合があることを確認しています。そもそも style prop などでいろいろとスタイルを当てるのであれば Flex を使うことそのものが間違いだと思われるので、Box コンポーネントを使ったり、素の div を使ったりするように変更しています。

スタイルの継承の仕方が変わった Text コンポーネント

v6 までの Text コンポーネントは親の color や line-height などを引き継いでいましたが、引き継がなくなりました。これによりかなりのスタイル崩れが発生しました。

inherit prop を指定しても v6 までの動作と同じになるわけではないため、素の p タグや span タグを使うように変更しなければならない箇所もありました。

Mantine v7 移行で嬉しかった点

逆に、Mantine v7 に移行して嬉しかった点を紹介します。

Combobox コンポーネント

先ほど触れた、数百種類あるタグを検索条件に指定するための階層と検索機能がついた MultiSelect は、Mantine の MultiSelect をかなり強引に改造して使っており、作り直しが必要になりました。しかし、Mantine v7 にはカスタムコンポーネントを作るためのコンポーネント Combobox があるため、思ったよりは苦労せず済みました。

ナビゲーション時にプログレスバーを表示する、@mantine/nprogress というパッケージがあります。内部で NProgress を使っているのかと思いきや、まったく使っていません。

v6 時代は Safari で不思議な挙動をすることがありましたが、v7 で解消されました。

Mantine v7 移行を経て得たもの

KEPPLE DB 開発チームは3人です。今回、大きな機能の開発・リリースと並行して UI ライブラリの更新という大きな作業ができました。昨年、負債の返済のために KEPPLE DB を作り直しましたが、負債を返しながら運用できる実績を作ったことで、チームはかなりの自信をつけました。

今後も DX がよい状態を保ちつつバリバリ開発して KEPPLE DB をよくしていきたいと思っています。