🐳

【公式よりも詳しい】Mantine V7移行ガイド

2024/01/24に公開

背景

AppRouterへの対応
弊社のプロジェクトでは、Mantineを使用しています。Next.jsをApp Routerに移行したことにより、Emotionに依存するライブラリの使用が困難になりました。以前までEmotionに依存していたMantineがバージョン7でApp Routerに対応したことから、弊社のプロジェクトでもMantineをバージョンアップすることになりました。

公式ドキュメント見ればいいんじゃない?
公式ドキュメントにはV6からV7への移行ガイドが用意されていますが、コンポーネントごとの移行詳細については記載されていないため、私が移行したコンポーネントについて詳細を記事にすることで、バージョン移行作業を少しでも楽にできる方がいればと思い、本記事を執筆することにしました。

https://mantine.dev

読者の方へ(閲覧必須)

  • 本記事はNext.jsのAppRouterプロジェクトに関する内容です。
  • V5からV7への移行の詳細についてまとめています。
  • この記事には、変更点の一部を紹介していますが、全てを網羅しているわけではありません。

移行の最初のステップ(必須)

1. 公式ドキュメントのGetting startedに書かれていることを実践

https://mantine.dev/guides/next

2. global cssを設定

  • こちらの章に書かれていますが、global cssの設定をしないとMantineのデフォルトのstyleが適用されません。
  • app/layout.tsxに下記の一行を追加することで適用されます。
app/layout.tsx
import '@mantine/core/styles.css';

3. themeについて

  • themeの設定方法に変更がありました。
  • 下記のようにcreateThemeを使用します。
import { createTheme } from '@mantine/core';

const theme = createTheme({
  spacing: {
    sm: '8px',
    md: '12px',
    lg: '20px',
  },
  radius: {
    md: '8px',
    lg: '16px',
  },
});

4. sxの廃止

  • V7以前までは、sxを指定することで設定したthemeからstyleを選択することができましたが、廃止されました。そのため、下記のように「style」propsを指定するか、className等でstyleを適用するようにします。
    • また、&:hover等の擬似要素(ネストされた要素)は「style」propsでサポートされていないため、classNameを使用します。
<Box style={{ backgroundColor: 'var(--mantine-color-red-5)' }} />

コンポーネント

MantineProvider

  • V7以前はEmotionに依存していたため、clientコンポーネントにしか置くことができませんでした。それに加え、app/layout.tsxは"use client"を指定できないため、下記のような加工したコンポーネントを作成する方もいたと思います。
ClientProvider.tsx
'use clinet'

import { MantineProvider } from '@mantine/core';

export const ClientProvider = ({ children }: { children: ReactNode }) => 
     <MantineProvider>{children}</MantineProvider>
  • しかし、Mantineの内部でCSS Moduleを使用し、Emotion依存から脱却したことで、app/layout.tsxに直接配置することができるようになりました。
    • また、Emotion脱却したため、emotion用のカスタムキャッシュコンポーネントも必要なくなりました。
app/layout.tsx
import { MantineProvider } from '@mantine/core';

const RootLayout = ({ children }: { children: React.ReactNode }) => {
  return (
    <html>
      <body>
        <MantineProvider>{children}</MantineProvider>
      </body>
    </html>
  );
};

Select

変更点 V5 V7
onChangeの型 (( value: string ) => void) (( value: string | null ) => void)
  • 引数の型にnullが追加されたことにより、onChange関数の処理内容によっては、nullを早期リターンさせる必要があるため、ご注意下さい。

AppShell

  • Headerを使用する場合
    • AppShellのpropsのheaderで{{ height: 数値 }}の指定が必須
<AppShell
  header={{ height: 70 }}
>
  • Navbarを使用する場合
    • AppShellのpropsのnavbarでwidthとbreakpointの指定が必須
<AppShell
    header={{ height: 70 }}
    navbar={{ width: 60, breakpoint: 'md' }}
>

AppShellHeader

  • heightが廃止された
    • 代わりにAppShellで指定する

AppShellNavbar

  • 「width」propsが廃止
  • 解決策として、下記のようにstyleを指定する
<AppShell.Navbar
    style={{
      width: 170,
    }}
>	

Input

変更点 V5 V7
props名 icon leftSection
  • 他にも、leftSectionやrightSectionに対して、pointerEventを指定できるようになりました。
<Input
  leftSection={<Icon name="hoge" />}
  leftSectionPointerEvents={'auto'}
  pointer={true}
/>

TextInput

変更点 V5 V7
props名 icon leftSection
  • こちらも上記のInputコンポーネントと同様に、leftSectionやrightSectionに対して、pointerEventを指定できるようになりました。
変更点 V5 V7
props名 icon leftSection
  • InputやTextInputコンポーネントは、アイコンに対してpointerEventを使用できるようになりましたが、NavLinkはサポートされていないようです。

Tabs

変更点 V5 V7
onChangeの型 (( value: string ) => void) (( value: string | null ) => void)
props名 onTabChange onChange
  • 引数の型にnullが追加されたことにより、onChange関数の処理内容によっては、nullを早期リターンさせる必要があるため、ご注意下さい。

Text

変更点 V5 V7
props名 weight fw
color c
size fontSize
  • 他には、truncateを指定することにより"text-overflow: ellipsis"を設定できるようになりました。
  • また、variantプロパティがgradientに設定されている場合、gradientプロパティを使用してグラデーションを設定できるようになりました。

Title

変更点 V5 V7
props名 color c

Checkbox.Group

  • 「orientation」propsが廃止
  • 解決策は、MantineのGroupコンポーネントを使用する or Checboxコンポーネントを任意のHTMLタグで囲み、flexなどを使用して自前で横並びにすることが挙げられます。
<CheckboxGroup>
  <Group>
    <Checkbox label="Checkbox1" value="1" />
    <Checkbox label="Checkbox2" value="2" />
    <Checkbox label="Checkbox3" value="3" />
  </Group>
</CheckboxGroup>
変更点 V5 V7
props名 icon leftSection
  • InputやTextInputコンポーネントは、アイコンに対してpointerEventを使用できるようになりましたが、Menu.Itemはサポートされていないようです。

Button

変更点 V5 V7
props名 rightIcon rightSection
  • 他には、sizeの選択肢も豊富になったという変更がありました。"xs"や"md"だけでなく、"compact-xs"や"compact-md"など、更に細かくsizeを調整できます。

SimpleGrid

変更点 V5 V7
propsの指定方法 cols={4} cols={{ base: 1, sm: 2, md: 3, lg: 4 }}
spacing="sm" spacing={{ base: "sm", md: "md" }}
  • V5では、breakpointsというpropsを使用してレスポンシブ対応していましたが、colsやspacing内で直感的に指定できるようになりました。
変更点 V5 V7
props名 overlayOpacity overlayProps

実際の書き方

<Modal
  opened={true}
  size={size}
  title={title}
  overlayProps={{ style: { opacity: 0.5 } }}
>

Stack

変更点 V5 V7
props名 spacing gap
  • こちらは命名の変更以外は特に無いようです。

RangeCalendar

  • V5では「RangeCalendar」というコンポーネントを使用していましたが、V7では「DatePicker」に変わり、type="range"を指定します。
  • V5の公式ドキュメントでは、Calendarセクションに説明が記述されていましたが、V7では、DatePickerセクションに書かれています。

V5

<RangeCalendar value={hoge} onChange={onChange} />;

V7

  <DatePicker type="range" value={hoge} onChange={onChange} />;

MantineNumberSize

変更点 V5 V7
型名 MantineNumberSize MantineSize

SelectItem

変更点 V5 V7
型名 SelectItem ComboboxData

FloatingPosition

  • mantine/core/lib/FloatingからFloatingPositionがimportできなくなった
  • 解決策として、下記のように独自で型を定義する
type FloatingPosition =
  | 'bottom'
  | 'left'
  | 'right'
  | 'top'
  | 'bottom-end'
  | 'bottom-start'
  | 'left-end'
  | 'left-start'
  | 'right-end'
  | 'right-start'
  | 'top-end'
  | 'top-start';

DataRangePickerValue

  • この型は廃止されたため、代わりに下記のように独自で型を定義
type DataRangePickerValue = [Date, Date]

MantineThemeOverride

  • 廃止されたため、createThemeでstyleを定義する

まとめ

  • V7アップデートの大きい変更点はEmotionを脱却し、AppRouterに対応したこと。
  • コンポーネントごとの変更点は、「型にnullが追加された」「props名の微修正」がほとんど。
  • 私達のプロジェクトでは、Mantineコンポーネントをラップしていたため、修正箇所を最小限に留め、スマートにバージョン移行を行うことができた。

今回のようにバージョン移行作業をスマートにできた要因は下記の記事に書いてあることを実践したことが大きいです。
かなり有益な内容が載っている記事のため、ぜひ一読してみて下さい!!

https://zenn.dev/ficilcom/articles/app_router_registant_to_changes

フィシルコム

Discussion