Mantine v7 alphaを触ってみる

[以前の記事](https://qiita.com/goqsystem_nagaoka/items/ab3f791ba7156a58beb4)でMantineの内部実装をみる必要があったので、リポジトリを覗きに行った時、ついでに[v7のリポジトリ](https://github.com/mantinedev/mantine-v7)を見つけました。  
アップデート内容を見てみたら気になる内容だったので、理解ついでに触ってみました。

## アップデートで気になる点
### [Emotion](https://emotion.sh/docs/introduction)の利用をやめる
昨今のCSS-in-JSの問題を受けての対応かと思います。  
すべてネイティブCSSに変更となるので、内部的に大きなアップデートになることがわかるかと思います。

CSS-in-JSに問題については、こちらの記事をご参考に。

https://zenn.dev/poteboy/articles/e9f63b87b3cd69

### Headless UIとして利用できるようになる
最近よく目にするようになった**Headless UI**。  
個人的には、利用したいコンポーネントが多くてMantineを選んだ経緯があるので、今後Mantineが注目されるきっかけになりそうです。  
Headless UIとして利用する方法は簡単で、後ほど解説します。

Headless UIの詳細については、こちらの記事をご参考に。

https://ics.media/entry/230413/

### normalize.cssを含めない
そこまでレイアウトに影響のあるものではないと思いますが、ちらほら気になるところが出てくるかもしれません。

https://v7.mantine.dev/styles/global-styles

一応、v6の方の[リンク](https://github.com/mantinedev/mantine/blob/master/src/mantine-styles/src/theme/NormalizeCSS.tsx)も

## 試してみる
今回は[Vite Template](https://github.com/mantinedev/vite-template)を利用します。  
masterブランチがv6になっているので、ブランチは`v7`を指定します。
```
git clone -b v7 https://github.com/mantinedev/vite-template.git mantine-v7
```
※6/15時点の最新は`7.0.0-aplha.13`ですが、v7用のtemplateでは`7.0.0-aplha.11`が利用されています。コンポーネント数が多少増えた程度なので、今回は気にせず`7.0.0-aplha.11`のまま進めます。

起動してみると下記の様な画面が表示されます。
![スクリーンショット 2023-06-13 22.35.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359978/f7926f8d-13ca-3c9e-9ee5-d24c0c0dfbfd.png)

### Emotionについて
`package.json`を見ても、Emotionを利用していないことが確認できます。

https://github.com/mantinedev/vite-template/blob/v7/package.json

一応、v6の方の[リンク](https://github.com/mantinedev/vite-template/blob/master/package.json#L18)も

### Headless UIについて
> You can now use Mantine as a headless library. To do that, just do not import @mantine/*/styles.css in your application. Then you will be able to apply styles with Styles API.

上記の通り、`styles.css`をimportしなければ、Headless UIとして利用できます。

```jsx:App.tsx
- import '@mantine/core/styles.css';
import { MantineProvider } from '@mantine/core';
import { Router } from './Router';
import { theme } from './theme';

export default function App() {
  return (
    <MantineProvider theme={theme}>
      <Router />
    </MantineProvider>
  );
}
```
`styles.css`を読み込まないと下記の様な画面になります。
![スクリーンショット 2023-06-13 22.47.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359978/1e9b2cfc-c1bc-aa3a-6b96-d5ba0bc74784.png)

最後に[Tailwind CSS](https://tailwindcss.com/)を利用してStyleをあててみます。

```
yarn add tailwindcss --dev
npx tailwindcss init -p
```

`postcss.config.js`はすでにtemplateに含まれているので、`tailwind.config.js`のみ生成されます。  
それぞれを下記の様に修正します。

```javascript:tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
-  content: [],
+  content: [
+    './index.html',
+    './src/**/*.{js,ts,jsx,tsx}',
+  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

```javascript:postcss.config.js
module.exports = {
  plugins: {
+    tailwindcss: {},
    'postcss-preset-mantine': {},
    'postcss-simple-vars': {
      variables: {
        'mantine-breakpoint-xs': '36em',
        'mantine-breakpoint-sm': '48em',
        'mantine-breakpoint-md': '62em',
        'mantine-breakpoint-lg': '75em',
        'mantine-breakpoint-xl': '88em',
      },
    },
  },
};
```
また、`index.css`を新規作成して、`App.tsx`内で読み込めばTailwind CSSのクラスが利用できるようになります。
```css:index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

```jsx:App.tsx
+ import './index.css';
import { MantineProvider } from '@mantine/core';
import { Router } from './Router';
import { theme } from './theme';

export default function App() {
  return (
    <MantineProvider theme={theme}>
      <Router />
    </MantineProvider>
  );
}
```

簡単ではありますが、実際にStyleが適用されるか試してみます。

```css:Button.module.css
.button {
  @apply p-1 bg-gray-300 rounded-md;
}
```

```jsx:ColorSchemeToggle.tsx
import { Button, Group, useMantineColorScheme } from '@mantine/core';
import classes from './Button.module.css';

export function ColorSchemeToggle() {
  const { setColorScheme } = useMantineColorScheme();

  return (
    <Group className="flex justify-center gap-2">
      <Button
        className={classes.button}
        onClick={() => setColorScheme('light')}
      >
        Light
      </Button>
      <Button className="p-1 bg-black rounded-md text-white" onClick={() => setColorScheme('dark')}>Dark</Button>
      <Button onClick={() => setColorScheme('auto')}>Auto</Button>
    </Group>
  );
}
```
Styleが適用されていることが確認できました。
![スクリーンショット 2023-06-15 10.10.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359978/c275018e-45cc-8071-2d13-27a51a15e4b3.png)
v6の時はTailwind CSSを読み込んだ時、Styleが競合してしまい利用するために設定がややこしかったのが、苦労せず利用できるようになりました。

## v7に向けて準備できること
こちらの[changelog](https://v7.mantine.dev/changelog/7-0-0)を読んで修正対応箇所をキャッチアップしておきましょう。  
参考までに、個人的に多用していて修正しないといけない箇所を挙げておきます。
- Emotionを利用しなくなるため、`sx` propが廃止。v7では`style` propへ変更。
- Groupコンポーネントの`position` propが`justify` propへ変更になり、値も変更。
- Tabコンポーネントの`onTabChange` propが`onChange` propへ変更。

## まとめ
v7へのバージョンアップにより、Mantineを利用しているアプリケーションでも大幅な変更が発生しそうということが分かりました。  
現状、coreパッケージの移植が6割程度という感じで、まだまだ先になりそうですがアップデートを楽しみにしています。

## 最後に
### GoQSystemでは一緒に働いてくれる仲間を募集中です！
ご興味がある方は以下リンクよりご確認ください。

https://goqsystem.recruit.site/?qiita=b52382d957b01086f9ea