Angular Material を愛する皆さんこんにちは!フロントエンドエンジニアの高橋 a.k.a 黄色い人( @fusho_takahashi )です。 エモーションテック Advent Calendar 2024 22 日目の記事を担当させていただきます!
M2 のまま使い続ける恐怖
エモーションテックでは、UI コンポーネントライブラリとして Angular Material を使用しています。Angular Material はその名の通り、Material Design のデザインを基に作られており、本家 Material Design のバージョンアップに伴い、これまでに 2 度大きな変更が行われました。
M1 から M2 への変更では、見た目に大きな変化はなく、公式からマイグレーションガイドも提供されていました。しかし、M2からM3への変更は事情が異なります。見た目が大幅に変わったこともあり、公式見解としてM2とM3は今後もしばらく両方サポートされ続けるようです。
現在エモーションテックでは M2 の設定を採用しています。v17 時点では引き続きサポートされるとのことでしたが、いつ M2 が Mat Legacy になるか分かりません。ちなみに、私は M2 が v20 で廃止されるというアナウンスが出る夢を見て、恐怖のあまり汗だくで目覚めたことが 2 度あります笑
M3 のテーマで M2 のデザインを再現する
M2 はサポートが続けられるそうですが、私が三度目の悪夢を見る前に M3 で M2 のデザインを再現する方法を考えておきましょう。しかも!v19 から公式サイトの各コンポーネントのページに styling タブが新設されました!この styling タブで紹介されている overrides mixin
を駆使して、M2 のデザインを再現していきます!
実践編:Button
とりあえず並べてみる
Angular v19 でアプリケーションを new
して、Angular Material を入れて MatButton を 2 つ並べます(上: M3 下: M2)。分かりやすいように、今回は mat-flat-button
を使用しています。
いやーかなり違いますね笑 これはただテーマ設定をマイグレーションしただけでは、アプリケーションの印象がガラッと変わってしまいそうです。
形を揃える
border-radius
まず角の丸さが全然違いますね。ただし styling タブを見てもそれらしい設定項目がなさそうなので、開発者ツールで見てみると --mat-sys-corner-full
という css 変数を設定しているようです。
今回は button だけ変更したいので、下記のように書いて上書きします。
[mat-flat-button] { --mat-sys-corner-full: 4px; }
letter-spacing
よく見るとボタン全体だけでなく、文字の横幅も違いそうです。
描画されている文字と文字の間、つまり letter-spacing
の値が違うようです。styling タブでいうと filled-label-text-tracking
の設定が異なっています。開発者ツールで M2 テーマの letter-spacing
を見つけ出して設定します。
:root { @include mat.button-overrides( ( filled-label-text-tracking: 0.0892857143em, ) ); }
padding
文字の横幅が揃ったので、続いてボタンの横幅を揃えます。これは単純に padding
を揃えればよいだけです。filled-horizontal-padding
の設定を追加します。
:root { @include mat.button-overrides( ( filled-label-text-tracking: 0.0892857143em, filled-horizontal-padding: 16px, ) ); }
height
あと少しです!横幅は完璧に揃いましたが、横並びにしてみると高さが違うことがわかります。(左: M3 右: M2)
filled-container-height
を設定しましょう
:root { @include mat.button-overrides( ( filled-label-text-tracking: 0.0892857143em, filled-horizontal-padding: 16px, filled-container-height: 36px, ) ); }
これで形は完璧に揃いました!続いて色を揃えましょう。
色を揃える
M3 用の Custom Color Palette を作成します。M3 から schematics が提供されているので、M2 の primary color を指定して作成します。
ng generate @angular/material:theme-color
_theme-colors.scss というファイルが出来上がるので、theme 設定の mixin に渡します。
@use "../theme-colors" as custom-colors; @include mat.theme( ( color: ( theme-type: light, primary: custom-colors.$primary-palette, ), typography: Roboto, density: 0, ) );
これで完璧!…いや、あれ?微妙に色が違います涙 どうやら primary color を指定してもその通りの色で palette が生成されるわけではなさそうです。M3 に合わせた色にマッピングされる仕様のようですね。惜しいところですが、大きな違いはないので今回はこれで良しとしましょう。
終わりに
Angular Material 公式サイトの各コンポーネントに styling タブができたおかげで、割とすんなり M2 のテーマを再現することができました。class をつければ簡単に M2 と M3 のテーマを分けることができるので、段階的にマイグレーションしていくのが良いかもしれません。実際に試してみたところ、少し手間はかかりましたが、それでも思ったよりはスムーズに進められ、これで悪夢を見ることもなくなりそうです!
エモーションテックでは顧客体験、従業員体験の改善をサポートし、世の中の体験を変えるプロダクトを開発しています。 プロダクトに興味のある方、Angular ・ Angular Material を使ったアプリケーション開発をしたい方、ぜひ採用ページからご応募をお願いいたします。