旧ブログ(ISSEN)から移行しました

【React】MantineUIのv7.0.0での変更点

【React】MantineUIのv7.0.0での変更点

杉田侑祐
杉田侑祐6分で読めます

はじめに

この記事の概要

こんにちは、株式会社TOKOSのスギタです!
今回は先日アップデートされてv6系からv7系にメジャーアップデートされたMantineの気になった変更箇所をまとめましたので紹介します。

Version v7.0.0 | Mantine

React components and hooks library with native dark theme support and focus on usability, accessibility and developer experience

mantine.dev

対象読者

  • Reactを用いたWEB制作、WEB開発を行っている方
  • Tailwind CSSを使用しながらUIライブラリを使用したい方

破壊的変更

まずは破壊的変更からです。

  • コンポーネントのオーバーライドの方法が大幅に変更になりました。
  • Emotionに依存しなくなりました。
  • createStyle関数は使用できなくなりました。
  • SX propsを使用できなくなりました。
  • styles propsはネストされたセレクターをサポートしなくなりました。

より軽量になるのはめちゃくちゃ嬉しいです。

新要素

color scheme

MantineProvidercolor schemeを設定できるようになりました。

Demo.tsx
import { MantineProvider, ColorSchemeScript } from "@mantine/core"
 
function Demo() {
  return (
    <>
      <ColorSchemeScript defaultColorScheme="auto" />
      <MantineProvider defaultColorScheme="auto">
        <App />
      </MantineProvider>
    </>
  )
}

CSSモジュールとPostCSSのプリセット

CSSモジュールはスタイルを設定するために推奨ですが必須ではありません。
postcss-preset-mantineを使用することも推奨になりました。

PostCSS preset | Mantine

React components and hooks library with native dark theme support and focus on usability, accessibility and developer experience

mantine.dev

ヘッドレスUI化

@mantine/styles.cssをインポートしなければヘッドレスUIとしても使用できるようになりました。

テーマ作成関数

createTheme関数を使うとすべてのテーマのプロパティに対してオーバーライドできるようになりました。

Demo.tsx
import { createTheme, MantineProvider } from "@mantine/core"
 
const theme = createTheme({
  fontFamily: "sans-serif",
  primaryColor: "orange",
})
 
function Demo() {
  return (
    <MantineProvider theme={theme}>
      <App />
    </MantineProvider>
  )
}

コンポーネントの機能拡張

extendでコンポーネントの拡張ができるようになりました。

下記はTextInputのデフォルトスタイルをオーバーライドしています。
独自のpropsとかも作成できるようになりました。

theme.ts
const theme = createTheme({
  components: {
    TextInput: TextInput.extend({
      styles: (theme, props) => ({
        input: {
          fontSize: props.size === "compact" ? theme.fontSizes.sm : undefined,
        },
      }),
      classNames: {
        root: classes.root,
        input: classes.input,
        label: classes.label,
      },
 
      defaultProps: {
        size: "compact",
      },
    }),
  },
})
 
function Demo() {
  return (
    <MantineProvider theme={theme}>
      <App />
    </MantineProvider>
  )
}

カラー指定の拡張

16進数、RGBA、HSLでカラーの指定が可能になりました。

Demo.tsx
function Demo() {
  return <Button color="#fff">ボタン</Button>
}

Comboboxコンポーネント

AutocompleteSelectTagsInputMultiselectのベースとして使用されるComboboxコンポーネントが追加されました。
以前のAutocompleteSelectMultiselectで実装されていた機能のベースは共通でComboboxコンポーネントが受け持つようになるみたいです。
また公式が出しているDEMOページが素晴らしいので是非一度見てほしいです。

Combobox examples | Mantine

50+ examples of using Mantine Combobox component

mantine.dev

リセットCSSについて

リセットCSSのnormalize.cssがなくなりました。
代わりに最小限のリセットCSSに変更されました。

reset.css
html,
body {
  height: 100%;
}
 
body {
  margin: 0;
}
 
*,
*::before,
*::after {
  box-sizing: border-box;
}
 
input,
button,
textarea,
select {
  font: inherit;
}
 
button,
select {
  text-transform: none;
}

この変更で、Tailwind側のリセットCSSとの互換性がよくなるかなと期待したのですが、あまり良くありませんでした。
どうせならばTailwindのリセットCSSとして採用されているmodern-normalize.cssに合わせてくれれば個人的には嬉しかったです。
現状はmodern-normalize.cssがMantineに干渉するプロパティだけ削除して使用するのが良さそうです。

globals.css
@tailwind components;
@tailwind utilities;
 
/*
node_modules/tailwindcss/lib/css/preflight.css からコピペしている
Mantineと競合するスタイルのみを削除している
*/
 
*,
::before,
::after {
  box-sizing: border-box;
  border-width: 0;
  border-style: solid;
  border-color: theme("borderColor.DEFAULT", currentColor);
}
 
::before,
::after {
  --tw-content: "";
}
 
html {
  -webkit-text-size-adjust: 100%;
  -moz-tab-size: 4;
  tab-size: 4;
  font-family: theme("fontFamily.sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");
  /* CSS変数を使っているためコメントアウト */
  /* font-feature-settings: theme(
    "fontFamily.sans[1].fontFeatureSettings",
    normal
  ); */
  /* font-variation-settings: theme(
    "fontFamily.sans[1].fontVariationSettings",
    normal
  ); */
}
 
body {
  margin: 0;
  line-height: inherit;
  color: #151515 !important;
}
 
hr {
  height: 0;
  color: inherit;
  border-top-width: 1px;
}
 
abbr:where([title]) {
  text-decoration: underline dotted;
}
 
h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
}
 
a {
  color: inherit;
  text-decoration: inherit;
}
 
b,
strong {
  font-weight: bolder;
}
 
code,
kbd,
samp,
pre {
  font-family: theme("fontFamily.mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);
  font-size: 1em;
}
 
small {
  font-size: 80%;
}
 
sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}
 
sub {
  bottom: -0.25em;
}
 
sup {
  top: -0.5em;
}
 
table {
  text-indent: 0;
  border-color: inherit;
  border-collapse: collapse;
}
 
button,
input,
optgroup,
select,
textarea {
  font-family: inherit;
  font-feature-settings: inherit;
  font-variation-settings: inherit;
  font-size: 100%;
  font-weight: inherit;
  line-height: inherit;
  color: inherit;
  margin: 0;
  padding: 0;
}
 
button,
select {
  text-transform: none;
}
 
button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
  /* MantineのButtonの色が上手く当たらないためコメントアウト */
  /* background-color: transparent; */
  background-image: none;
}
 
:-moz-focusring {
  outline: auto;
}
 
:-moz-ui-invalid {
  box-shadow: none;
}
 
progress {
  vertical-align: baseline;
}
 
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
  height: auto;
}
 
[type="search"] {
  -webkit-appearance: textfield;
  outline-offset: -2px;
}
 
::-webkit-search-decoration {
  -webkit-appearance: none;
}
 
::-webkit-file-upload-button {
  -webkit-appearance: button;
  font: inherit;
}
 
summary {
  display: list-item;
}
 
blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
  margin: 0;
}
 
fieldset {
  margin: 0;
  padding: 0;
}
 
legend {
  padding: 0;
}
 
ol,
ul,
menu {
  list-style: none;
  margin: 0;
  padding: 0;
}
 
dialog {
  padding: 0;
}
 
textarea {
  resize: vertical;
}
 
input::placeholder,
textarea::placeholder {
  opacity: 1;
  color: theme("colors.gray.400", #9ca3af);
}
 
button,
[role="button"] {
  cursor: pointer;
}
 
:disabled {
  cursor: default;
}
 
img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
  display: block;
  vertical-align: middle;
}
 
img,
video {
  max-width: 100%;
  height: auto;
}
 
[hidden] {
  display: none;
}

現状はこれで運用しています。
また何か良い方法があればご教示いただけたら幸いです。

さいごに

今回はメジャーアップデートされたMantineUIの変更箇所を紹介いたしました。
ここに紹介していないものもあるので一度公式ドキュメントを見ていただければと思います。
また公式ドキュメントの内容構成もアップデートされてコンポーネントの構成等も追記されていたりドキュメントの読みやすさも格段に上がったと思います!

この記事を書いた人

杉田侑祐
杉田侑祐

TOKOSのフロントエンドエンジニア兼UI/UXデザイナー。このブログではフロントエンドメインで投稿しています。HIPHOPとゲームが好きです✌️