Top
/
Articles
/
Mantineコンポーネントのカスタムバリアントの作り方
カテゴリー「mantine」の画像

Mantineコンポーネントのカスタムバリアントの作り方

Mantine
customize

2025年4月24日

独自のバリアントを定義する

<Button variant="my-variant">...</Button> のように、
Mantineコンポーネントに独自のバリアント(この記事ではmy-variant という名前にします)を指定すると、
HTMLでは以下のようになります

<button class="mantine-Button-root mantine-UnstyledButton-root ..." data-variant="my-variant" type="button">
  ...
</button>

root要素にdata-variant="my-variant"のようにdata属性がつきます。
(コンポーネントによって内部の要素(inner, labelなど)にもdata属性が付いたり付かなかったりと一貫性はないようです。)

このdata属性を使って独自のバリアントのスタイルを指定します。

globals.css
.mantine-Button-root[data-variant="my-variant"] {
  ...
}

色だけをカスタマイズできればよい場合

カスタムバリアントをサポートしているコンポーネント(Button, Badge, ActionIconなど) の色だけを変更できればよい場合は、
テーマのvariantColorResolverを使って色を変更できます。
このやり方で設定できるのは、

  • 背景色 (background)
  • 文字色 (color)
  • ホバー時の背景色 (hover)
  • ホバー時の文字色 (hoverColor)
  • 境界線のスタイル (border)、borderプロパティに使われるので、これだけ色だけでなくスタイルも指定可能

のみです。

variantColorResolverによる色設定に対応しているコンポーネントは少なく、どのコンポーネントが対応しているのか書かれていない ので、
今のところ Button, Badge, ActionIcon の色設定のみにしか使いどころがないです。
variantColorResolverに対応していないコンポーネントに独自のバリアントを設定しても何の効果もありません。

variantColorResolverはクライアントサイドから呼ばれるため、
Next.jsを使っている場合は"use client";指定が必要です。

theme.ts
"use client";
 
import {
  createTheme,
  defaultVariantColorsResolver,
} from "@mantine/core";
 
export const theme = createTheme({
  variantColorResolver: (input) => {
    if (input.variant === "my-variant") {
      return {
        background: "var(--mantine-color-yellow-filled)",
        hover: "var(--mantine-color-yellow-filled-hover)",
        color: "var(--mantine-color-yellow-text)",
        border: "1px dashed var(--mantine-color-yellow-outline)",
        hoverColor: "var(--mantine-color-white)",
      };
    }
 
    // カスタマイズしないならデフォルトを返す
    return defaultVariantColorsResolver(input);
  },
});

variantColorResolverから返された値は、要素のstyle属性内で使われます。
css変数を使いたいときは、"var(...)"のように指定する必要があります。
例えば<Button variant="my-variant">variantColorResolverで色を設定したとき、
HTMLは以下のようになります:

<button style="
--button-color: <colorの値>;
--button-bg: <backgroundの値>;
--button-hover: <hoverの値>;
--button-bd: <borderの値>;
--button-hover-color: <hoverColorの値>;
" ...>...</button>

型情報

型定義は @mantine/core/src/core/MantineProvider/color-functions/default-variant-colors-resolver/default-variant-colors-resolver.ts
で定義されています。

variantColorResolverのinputの型
export interface VariantColorsResolverInput {
  color: MantineColor | undefined;
  theme: MantineTheme;
  variant: string;
  gradient?: MantineGradient;
  autoContrast?: boolean;
}
variantColorResolverから返す値の型
export interface VariantColorResolverResult {
  background: string;   // 背景色
  hover: string;        // ホバー時の背景色
  color: string;        // 文字色
  border: string;       // 境界線の色
  hoverColor?: string;  // ホバー時の文字色
}

parseThemeColor(...)関係
@mantine/core/src/core/MantineProvider/color-functions/parse-theme-color/parse-theme-color.ts

export function parseThemeColor({
  color,
  theme,
  colorScheme,
}: ParseThemeColorOptions): ParseThemeColorResult;
 
interface ParseThemeColorOptions {
  color: unknown;       // unknownだがstringを渡す必要がある
  theme: MantineTheme;
  colorScheme?: MantineColorScheme;
}
 
interface ParseThemeColorResult {
  color: string;          // 色名
  value: string;          // 解決された値
  shade: MantineColorShade | undefined;
  variable: CssVariable | undefined;  // 対応するcss変数名
  isThemeColor: boolean;  // theme.colorsで定義された色かどうか
  isLight: boolean;       // 明るい色かどうか (autoContrastなどで使われる)
}

情報源

Variants and sizes | Mantine

サンプルプロジェクト

https://github.com/sousyokunotomonokai/mantine-custom-variants

横長宣伝