
Mantineコンポーネントのカスタムバリアントの作り方
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属性を使って独自のバリアントのスタイルを指定します。
.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";
指定が必要です。
"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
で定義されています。
export interface VariantColorsResolverInput {
color: MantineColor | undefined;
theme: MantineTheme;
variant: string;
gradient?: MantineGradient;
autoContrast?: boolean;
}
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などで使われる)
}
情報源
サンプルプロジェクト
https://github.com/sousyokunotomonokai/mantine-custom-variants
